@wemap/geo 11.0.0-alpha.25 → 11.0.0-alpha.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/index.js +414 -1400
  2. package/dist/index.js.map +1 -1
  3. package/dist/index.mjs +414 -1400
  4. package/dist/index.mjs.map +1 -1
  5. package/index.ts +19 -9
  6. package/package.json +5 -6
  7. package/src/Utils.ts +4 -4
  8. package/src/coordinates/Coordinates.ts +7 -16
  9. package/src/coordinates/Level.spec.ts +1 -6
  10. package/src/coordinates/Level.ts +6 -15
  11. package/src/graph/GraphEdge.spec.ts +74 -0
  12. package/src/graph/GraphEdge.ts +134 -0
  13. package/src/graph/GraphNode.spec.ts +202 -0
  14. package/src/graph/GraphNode.ts +174 -0
  15. package/src/graph/GraphProjection.ts +23 -0
  16. package/src/graph/GraphUtils.ts +21 -0
  17. package/src/graph/{GeoGraphProjectionHandler.spec.ts → MapMatching.spec.ts} +73 -74
  18. package/src/graph/{GeoGraphProjectionHandler.ts → MapMatching.ts} +44 -39
  19. package/src/graph/Network.spec.ts +148 -0
  20. package/src/graph/Network.ts +177 -0
  21. package/src/router/GraphItinerary.spec.ts +14 -0
  22. package/src/router/GraphItinerary.ts +80 -0
  23. package/src/router/GraphRouter.spec.ts +298 -0
  24. package/src/router/GraphRouter.ts +283 -0
  25. package/src/router/GraphRouterOptions.ts +14 -0
  26. package/src/{graph → router}/NoRouteFoundError.ts +14 -9
  27. package/src/types.ts +3 -3
  28. package/tests/CommonTest.ts +75 -69
  29. package/src/graph/GeoGraph.spec.ts +0 -278
  30. package/src/graph/GeoGraph.ts +0 -170
  31. package/src/graph/GeoGraphEdge.spec.ts +0 -51
  32. package/src/graph/GeoGraphEdge.ts +0 -98
  33. package/src/graph/GeoGraphItinerary.spec.ts +0 -14
  34. package/src/graph/GeoGraphItinerary.ts +0 -61
  35. package/src/graph/GeoGraphProjection.ts +0 -24
  36. package/src/graph/GeoGraphRouter.spec.ts +0 -297
  37. package/src/graph/GeoGraphRouter.ts +0 -267
  38. package/src/graph/GeoGraphVertex.spec.ts +0 -54
  39. package/src/graph/GeoGraphVertex.ts +0 -139
package/dist/index.js CHANGED
@@ -80,27 +80,18 @@ const _Level = class {
80
80
  if (str === null) {
81
81
  return null;
82
82
  }
83
- if (typeof str !== "string" || !str.length) {
84
- throw Error(`argument must be a non empty string, got ${typeof str}`);
83
+ if (typeof str !== "string") {
84
+ throw Error(`argument must be a string, got ${typeof str}`);
85
85
  }
86
86
  if (!isNaN(Number(str))) {
87
87
  return parseFloat(str);
88
88
  }
89
89
  const splited = str.split(";");
90
- if (splited.length > 1) {
91
- const levels = splited.map((str2) => Number(str2));
92
- const low = Math.min(...levels);
93
- const up = Math.max(...levels);
90
+ if (splited.length === 2) {
91
+ const low = Number(splited[0]);
92
+ const up = Number(splited[1]);
94
93
  this.checkType([low, up]);
95
- return [low, up];
96
- } else {
97
- const rangeSeparator = str.substring(1).indexOf("-") + 1;
98
- if (rangeSeparator > 0) {
99
- const low = Number(str.substring(0, rangeSeparator));
100
- const up = Number(str.substring(rangeSeparator + 1));
101
- this.checkType([low, up]);
102
- return [low, up];
103
- }
94
+ return [parseFloat(splited[0]), parseFloat(splited[1])];
104
95
  }
105
96
  throw Error(`Cannot parse following level: ${str}`);
106
97
  }
@@ -492,9 +483,9 @@ class Coordinates {
492
483
  }
493
484
  toJson() {
494
485
  return {
495
- lat: Number(this.lat.toFixed(8)),
496
- lng: Number(this.lng.toFixed(8)),
497
- ...this.alt !== null && { alt: Number(this.alt.toFixed(3)) },
486
+ lat: this.lat,
487
+ lng: this.lng,
488
+ ...this.alt !== null && { alt: this.alt },
498
489
  ...this.level !== null && { level: this.level }
499
490
  };
500
491
  }
@@ -503,21 +494,12 @@ class Coordinates {
503
494
  }
504
495
  toCompressedJson() {
505
496
  if (this.level !== null) {
506
- return [
507
- Number(this.lat.toFixed(8)),
508
- Number(this.lng.toFixed(8)),
509
- this.alt === null ? null : Number(this.alt.toFixed(3)),
510
- this.level
511
- ];
497
+ return [this.lat, this.lng, this.alt, this.level];
512
498
  }
513
499
  if (this.alt !== null) {
514
- return [
515
- Number(this.lat.toFixed(8)),
516
- Number(this.lng.toFixed(8)),
517
- Number(this.alt.toFixed(3))
518
- ];
500
+ return [this.lat, this.lng, this.alt];
519
501
  }
520
- return [Number(this.lat.toFixed(8)), Number(this.lng.toFixed(8))];
502
+ return [this.lat, this.lng];
521
503
  }
522
504
  static fromCompressedJson(json) {
523
505
  const coords = new Coordinates(json[0], json[1]);
@@ -1113,1118 +1095,158 @@ class AbsoluteHeading {
1113
1095
  return new AbsoluteHeading(this.heading, this.time, this.accuracy);
1114
1096
  }
1115
1097
  }
1116
- var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
1117
- var uaParser = { exports: {} };
1118
- (function(module2, exports2) {
1119
- (function(window2, undefined$1) {
1120
- var LIBVERSION = "1.0.33", EMPTY = "", UNKNOWN = "?", FUNC_TYPE = "function", UNDEF_TYPE = "undefined", OBJ_TYPE = "object", STR_TYPE = "string", MAJOR = "major", MODEL = "model", NAME = "name", TYPE = "type", VENDOR = "vendor", VERSION = "version", ARCHITECTURE = "architecture", CONSOLE = "console", MOBILE = "mobile", TABLET = "tablet", SMARTTV = "smarttv", WEARABLE = "wearable", EMBEDDED = "embedded", UA_MAX_LENGTH = 350;
1121
- var AMAZON = "Amazon", APPLE = "Apple", ASUS = "ASUS", BLACKBERRY = "BlackBerry", BROWSER = "Browser", CHROME = "Chrome", EDGE = "Edge", FIREFOX = "Firefox", GOOGLE = "Google", HUAWEI = "Huawei", LG = "LG", MICROSOFT = "Microsoft", MOTOROLA = "Motorola", OPERA = "Opera", SAMSUNG = "Samsung", SHARP = "Sharp", SONY = "Sony", XIAOMI = "Xiaomi", ZEBRA = "Zebra", FACEBOOK = "Facebook";
1122
- var extend = function(regexes2, extensions) {
1123
- var mergedRegexes = {};
1124
- for (var i in regexes2) {
1125
- if (extensions[i] && extensions[i].length % 2 === 0) {
1126
- mergedRegexes[i] = extensions[i].concat(regexes2[i]);
1098
+ class GraphNode {
1099
+ constructor(coords, builtFrom = null) {
1100
+ __publicField(this, "coords");
1101
+ __publicField(this, "edges", []);
1102
+ __publicField(this, "builtFrom");
1103
+ __publicField(this, "io", false);
1104
+ this.coords = coords;
1105
+ this.builtFrom = builtFrom;
1106
+ }
1107
+ distanceTo(other) {
1108
+ return this.coords.distanceTo(other.coords);
1109
+ }
1110
+ bearingTo(other) {
1111
+ return this.coords.bearingTo(other.coords);
1112
+ }
1113
+ equals(other) {
1114
+ return this.coords.equals(other.coords) && this.builtFrom === other.builtFrom;
1115
+ }
1116
+ clone() {
1117
+ const node = new GraphNode(this.coords, this.builtFrom);
1118
+ node.edges = this.edges.slice(0);
1119
+ node.io = this.io;
1120
+ return node;
1121
+ }
1122
+ toJson() {
1123
+ return this.coords.toCompressedJson();
1124
+ }
1125
+ static fromJson(json, builtFrom = null) {
1126
+ return new GraphNode(Coordinates.fromCompressedJson(json), builtFrom);
1127
+ }
1128
+ _generateLevelFromEdges() {
1129
+ let tmpLevel = null;
1130
+ for (let i = 0; i < this.edges.length; i++) {
1131
+ const edge = this.edges[i];
1132
+ if (edge.level !== null) {
1133
+ if (tmpLevel === null) {
1134
+ tmpLevel = Level.clone(edge.level);
1127
1135
  } else {
1128
- mergedRegexes[i] = regexes2[i];
1129
- }
1130
- }
1131
- return mergedRegexes;
1132
- }, enumerize = function(arr) {
1133
- var enums = {};
1134
- for (var i = 0; i < arr.length; i++) {
1135
- enums[arr[i].toUpperCase()] = arr[i];
1136
- }
1137
- return enums;
1138
- }, has = function(str1, str2) {
1139
- return typeof str1 === STR_TYPE ? lowerize(str2).indexOf(lowerize(str1)) !== -1 : false;
1140
- }, lowerize = function(str) {
1141
- return str.toLowerCase();
1142
- }, majorize = function(version) {
1143
- return typeof version === STR_TYPE ? version.replace(/[^\d\.]/g, EMPTY).split(".")[0] : undefined$1;
1144
- }, trim = function(str, len) {
1145
- if (typeof str === STR_TYPE) {
1146
- str = str.replace(/^\s\s*/, EMPTY);
1147
- return typeof len === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH);
1148
- }
1149
- };
1150
- var rgxMapper = function(ua, arrays) {
1151
- var i = 0, j, k, p, q, matches, match;
1152
- while (i < arrays.length && !matches) {
1153
- var regex = arrays[i], props = arrays[i + 1];
1154
- j = k = 0;
1155
- while (j < regex.length && !matches) {
1156
- matches = regex[j++].exec(ua);
1157
- if (!!matches) {
1158
- for (p = 0; p < props.length; p++) {
1159
- match = matches[++k];
1160
- q = props[p];
1161
- if (typeof q === OBJ_TYPE && q.length > 0) {
1162
- if (q.length === 2) {
1163
- if (typeof q[1] == FUNC_TYPE) {
1164
- this[q[0]] = q[1].call(this, match);
1165
- } else {
1166
- this[q[0]] = q[1];
1167
- }
1168
- } else if (q.length === 3) {
1169
- if (typeof q[1] === FUNC_TYPE && !(q[1].exec && q[1].test)) {
1170
- this[q[0]] = match ? q[1].call(this, match, q[2]) : undefined$1;
1171
- } else {
1172
- this[q[0]] = match ? match.replace(q[1], q[2]) : undefined$1;
1173
- }
1174
- } else if (q.length === 4) {
1175
- this[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined$1;
1176
- }
1177
- } else {
1178
- this[q] = match ? match : undefined$1;
1179
- }
1180
- }
1181
- }
1182
- }
1183
- i += 2;
1184
- }
1185
- }, strMapper = function(str, map) {
1186
- for (var i in map) {
1187
- if (typeof map[i] === OBJ_TYPE && map[i].length > 0) {
1188
- for (var j = 0; j < map[i].length; j++) {
1189
- if (has(map[i][j], str)) {
1190
- return i === UNKNOWN ? undefined$1 : i;
1191
- }
1136
+ tmpLevel = Level.intersection(tmpLevel, edge.level);
1137
+ if (tmpLevel === null) {
1138
+ throw Error("Something bad happend during parsing: We cannot retrieve node level from adjacent ways: " + this.coords);
1192
1139
  }
1193
- } else if (has(map[i], str)) {
1194
- return i === UNKNOWN ? undefined$1 : i;
1195
1140
  }
1196
1141
  }
1197
- return str;
1198
- };
1199
- var oldSafariMap = {
1200
- "1.0": "/8",
1201
- "1.2": "/1",
1202
- "1.3": "/3",
1203
- "2.0": "/412",
1204
- "2.0.2": "/416",
1205
- "2.0.3": "/417",
1206
- "2.0.4": "/419",
1207
- "?": "/"
1208
- }, windowsVersionMap = {
1209
- "ME": "4.90",
1210
- "NT 3.11": "NT3.51",
1211
- "NT 4.0": "NT4.0",
1212
- "2000": "NT 5.0",
1213
- "XP": ["NT 5.1", "NT 5.2"],
1214
- "Vista": "NT 6.0",
1215
- "7": "NT 6.1",
1216
- "8": "NT 6.2",
1217
- "8.1": "NT 6.3",
1218
- "10": ["NT 6.4", "NT 10.0"],
1219
- "RT": "ARM"
1220
- };
1221
- var regexes = {
1222
- browser: [
1223
- [
1224
- /\b(?:crmo|crios)\/([\w\.]+)/i
1225
- ],
1226
- [VERSION, [NAME, "Chrome"]],
1227
- [
1228
- /edg(?:e|ios|a)?\/([\w\.]+)/i
1229
- ],
1230
- [VERSION, [NAME, "Edge"]],
1231
- [
1232
- /(opera mini)\/([-\w\.]+)/i,
1233
- /(opera [mobiletab]{3,6})\b.+version\/([-\w\.]+)/i,
1234
- /(opera)(?:.+version\/|[\/ ]+)([\w\.]+)/i
1235
- ],
1236
- [NAME, VERSION],
1237
- [
1238
- /opios[\/ ]+([\w\.]+)/i
1239
- ],
1240
- [VERSION, [NAME, OPERA + " Mini"]],
1241
- [
1242
- /\bopr\/([\w\.]+)/i
1243
- ],
1244
- [VERSION, [NAME, OPERA]],
1245
- [
1246
- /(kindle)\/([\w\.]+)/i,
1247
- /(lunascape|maxthon|netfront|jasmine|blazer)[\/ ]?([\w\.]*)/i,
1248
- /(avant |iemobile|slim)(?:browser)?[\/ ]?([\w\.]*)/i,
1249
- /(ba?idubrowser)[\/ ]?([\w\.]+)/i,
1250
- /(?:ms|\()(ie) ([\w\.]+)/i,
1251
- /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale|qqbrowserlite|qq|duckduckgo)\/([-\w\.]+)/i,
1252
- /(weibo)__([\d\.]+)/i
1253
- ],
1254
- [NAME, VERSION],
1255
- [
1256
- /(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i
1257
- ],
1258
- [VERSION, [NAME, "UC" + BROWSER]],
1259
- [
1260
- /microm.+\bqbcore\/([\w\.]+)/i,
1261
- /\bqbcore\/([\w\.]+).+microm/i
1262
- ],
1263
- [VERSION, [NAME, "WeChat(Win) Desktop"]],
1264
- [
1265
- /micromessenger\/([\w\.]+)/i
1266
- ],
1267
- [VERSION, [NAME, "WeChat"]],
1268
- [
1269
- /konqueror\/([\w\.]+)/i
1270
- ],
1271
- [VERSION, [NAME, "Konqueror"]],
1272
- [
1273
- /trident.+rv[: ]([\w\.]{1,9})\b.+like gecko/i
1274
- ],
1275
- [VERSION, [NAME, "IE"]],
1276
- [
1277
- /yabrowser\/([\w\.]+)/i
1278
- ],
1279
- [VERSION, [NAME, "Yandex"]],
1280
- [
1281
- /(avast|avg)\/([\w\.]+)/i
1282
- ],
1283
- [[NAME, /(.+)/, "$1 Secure " + BROWSER], VERSION],
1284
- [
1285
- /\bfocus\/([\w\.]+)/i
1286
- ],
1287
- [VERSION, [NAME, FIREFOX + " Focus"]],
1288
- [
1289
- /\bopt\/([\w\.]+)/i
1290
- ],
1291
- [VERSION, [NAME, OPERA + " Touch"]],
1292
- [
1293
- /coc_coc\w+\/([\w\.]+)/i
1294
- ],
1295
- [VERSION, [NAME, "Coc Coc"]],
1296
- [
1297
- /dolfin\/([\w\.]+)/i
1298
- ],
1299
- [VERSION, [NAME, "Dolphin"]],
1300
- [
1301
- /coast\/([\w\.]+)/i
1302
- ],
1303
- [VERSION, [NAME, OPERA + " Coast"]],
1304
- [
1305
- /miuibrowser\/([\w\.]+)/i
1306
- ],
1307
- [VERSION, [NAME, "MIUI " + BROWSER]],
1308
- [
1309
- /fxios\/([-\w\.]+)/i
1310
- ],
1311
- [VERSION, [NAME, FIREFOX]],
1312
- [
1313
- /\bqihu|(qi?ho?o?|360)browser/i
1314
- ],
1315
- [[NAME, "360 " + BROWSER]],
1316
- [
1317
- /(oculus|samsung|sailfish|huawei)browser\/([\w\.]+)/i
1318
- ],
1319
- [[NAME, /(.+)/, "$1 " + BROWSER], VERSION],
1320
- [
1321
- /(comodo_dragon)\/([\w\.]+)/i
1322
- ],
1323
- [[NAME, /_/g, " "], VERSION],
1324
- [
1325
- /(electron)\/([\w\.]+) safari/i,
1326
- /(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i,
1327
- /m?(qqbrowser|baiduboxapp|2345Explorer)[\/ ]?([\w\.]+)/i
1328
- ],
1329
- [NAME, VERSION],
1330
- [
1331
- /(metasr)[\/ ]?([\w\.]+)/i,
1332
- /(lbbrowser)/i,
1333
- /\[(linkedin)app\]/i
1334
- ],
1335
- [NAME],
1336
- [
1337
- /((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i
1338
- ],
1339
- [[NAME, FACEBOOK], VERSION],
1340
- [
1341
- /safari (line)\/([\w\.]+)/i,
1342
- /\b(line)\/([\w\.]+)\/iab/i,
1343
- /(chromium|instagram)[\/ ]([-\w\.]+)/i
1344
- ],
1345
- [NAME, VERSION],
1346
- [
1347
- /\bgsa\/([\w\.]+) .*safari\//i
1348
- ],
1349
- [VERSION, [NAME, "GSA"]],
1350
- [
1351
- /headlesschrome(?:\/([\w\.]+)| )/i
1352
- ],
1353
- [VERSION, [NAME, CHROME + " Headless"]],
1354
- [
1355
- / wv\).+(chrome)\/([\w\.]+)/i
1356
- ],
1357
- [[NAME, CHROME + " WebView"], VERSION],
1358
- [
1359
- /droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i
1360
- ],
1361
- [VERSION, [NAME, "Android " + BROWSER]],
1362
- [
1363
- /(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i
1364
- ],
1365
- [NAME, VERSION],
1366
- [
1367
- /version\/([\w\.\,]+) .*mobile\/\w+ (safari)/i
1368
- ],
1369
- [VERSION, [NAME, "Mobile Safari"]],
1370
- [
1371
- /version\/([\w(\.|\,)]+) .*(mobile ?safari|safari)/i
1372
- ],
1373
- [VERSION, NAME],
1374
- [
1375
- /webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i
1376
- ],
1377
- [NAME, [VERSION, strMapper, oldSafariMap]],
1378
- [
1379
- /(webkit|khtml)\/([\w\.]+)/i
1380
- ],
1381
- [NAME, VERSION],
1382
- [
1383
- /(navigator|netscape\d?)\/([-\w\.]+)/i
1384
- ],
1385
- [[NAME, "Netscape"], VERSION],
1386
- [
1387
- /mobile vr; rv:([\w\.]+)\).+firefox/i
1388
- ],
1389
- [VERSION, [NAME, FIREFOX + " Reality"]],
1390
- [
1391
- /ekiohf.+(flow)\/([\w\.]+)/i,
1392
- /(swiftfox)/i,
1393
- /(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror|klar)[\/ ]?([\w\.\+]+)/i,
1394
- /(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([-\w\.]+)$/i,
1395
- /(firefox)\/([\w\.]+)/i,
1396
- /(mozilla)\/([\w\.]+) .+rv\:.+gecko\/\d+/i,
1397
- /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir|obigo|mosaic|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i,
1398
- /(links) \(([\w\.]+)/i
1399
- ],
1400
- [NAME, VERSION],
1401
- [
1402
- /(cobalt)\/([\w\.]+)/i
1403
- ],
1404
- [NAME, [VERSION, /master.|lts./, ""]]
1405
- ],
1406
- cpu: [
1407
- [
1408
- /(?:(amd|x(?:(?:86|64)[-_])?|wow|win)64)[;\)]/i
1409
- ],
1410
- [[ARCHITECTURE, "amd64"]],
1411
- [
1412
- /(ia32(?=;))/i
1413
- ],
1414
- [[ARCHITECTURE, lowerize]],
1415
- [
1416
- /((?:i[346]|x)86)[;\)]/i
1417
- ],
1418
- [[ARCHITECTURE, "ia32"]],
1419
- [
1420
- /\b(aarch64|arm(v?8e?l?|_?64))\b/i
1421
- ],
1422
- [[ARCHITECTURE, "arm64"]],
1423
- [
1424
- /\b(arm(?:v[67])?ht?n?[fl]p?)\b/i
1425
- ],
1426
- [[ARCHITECTURE, "armhf"]],
1427
- [
1428
- /windows (ce|mobile); ppc;/i
1429
- ],
1430
- [[ARCHITECTURE, "arm"]],
1431
- [
1432
- /((?:ppc|powerpc)(?:64)?)(?: mac|;|\))/i
1433
- ],
1434
- [[ARCHITECTURE, /ower/, EMPTY, lowerize]],
1435
- [
1436
- /(sun4\w)[;\)]/i
1437
- ],
1438
- [[ARCHITECTURE, "sparc"]],
1439
- [
1440
- /((?:avr32|ia64(?=;))|68k(?=\))|\barm(?=v(?:[1-7]|[5-7]1)l?|;|eabi)|(?=atmel )avr|(?:irix|mips|sparc)(?:64)?\b|pa-risc)/i
1441
- ],
1442
- [[ARCHITECTURE, lowerize]]
1443
- ],
1444
- device: [
1445
- [
1446
- /\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
1447
- ],
1448
- [MODEL, [VENDOR, SAMSUNG], [TYPE, TABLET]],
1449
- [
1450
- /\b((?:s[cgp]h|gt|sm)-\w+|galaxy nexus)/i,
1451
- /samsung[- ]([-\w]+)/i,
1452
- /sec-(sgh\w+)/i
1453
- ],
1454
- [MODEL, [VENDOR, SAMSUNG], [TYPE, MOBILE]],
1455
- [
1456
- /\((ip(?:hone|od)[\w ]*);/i
1457
- ],
1458
- [MODEL, [VENDOR, APPLE], [TYPE, MOBILE]],
1459
- [
1460
- /\((ipad);[-\w\),; ]+apple/i,
1461
- /applecoremedia\/[\w\.]+ \((ipad)/i,
1462
- /\b(ipad)\d\d?,\d\d?[;\]].+ios/i
1463
- ],
1464
- [MODEL, [VENDOR, APPLE], [TYPE, TABLET]],
1465
- [
1466
- /(macintosh);/i
1467
- ],
1468
- [MODEL, [VENDOR, APPLE]],
1469
- [
1470
- /\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i
1471
- ],
1472
- [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]],
1473
- [
1474
- /(?:huawei|honor)([-\w ]+)[;\)]/i,
1475
- /\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][012359c][adn]?)\b(?!.+d\/s)/i
1476
- ],
1477
- [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]],
1478
- [
1479
- /\b(poco[\w ]+)(?: bui|\))/i,
1480
- /\b; (\w+) build\/hm\1/i,
1481
- /\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i,
1482
- /\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i,
1483
- /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\))/i
1484
- ],
1485
- [[MODEL, /_/g, " "], [VENDOR, XIAOMI], [TYPE, MOBILE]],
1486
- [
1487
- /\b(mi[-_ ]?(?:pad)(?:[\w_ ]+))(?: bui|\))/i
1488
- ],
1489
- [[MODEL, /_/g, " "], [VENDOR, XIAOMI], [TYPE, TABLET]],
1490
- [
1491
- /; (\w+) bui.+ oppo/i,
1492
- /\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i
1493
- ],
1494
- [MODEL, [VENDOR, "OPPO"], [TYPE, MOBILE]],
1495
- [
1496
- /vivo (\w+)(?: bui|\))/i,
1497
- /\b(v[12]\d{3}\w?[at])(?: bui|;)/i
1498
- ],
1499
- [MODEL, [VENDOR, "Vivo"], [TYPE, MOBILE]],
1500
- [
1501
- /\b(rmx[12]\d{3})(?: bui|;|\))/i
1502
- ],
1503
- [MODEL, [VENDOR, "Realme"], [TYPE, MOBILE]],
1504
- [
1505
- /\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w ]+build\//i,
1506
- /\bmot(?:orola)?[- ](\w*)/i,
1507
- /((?:moto[\w\(\) ]+|xt\d{3,4}|nexus 6)(?= bui|\)))/i
1508
- ],
1509
- [MODEL, [VENDOR, MOTOROLA], [TYPE, MOBILE]],
1510
- [
1511
- /\b(mz60\d|xoom[2 ]{0,2}) build\//i
1512
- ],
1513
- [MODEL, [VENDOR, MOTOROLA], [TYPE, TABLET]],
1514
- [
1515
- /((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i
1516
- ],
1517
- [MODEL, [VENDOR, LG], [TYPE, TABLET]],
1518
- [
1519
- /(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i,
1520
- /\blg[-e;\/ ]+((?!browser|netcast|android tv)\w+)/i,
1521
- /\blg-?([\d\w]+) bui/i
1522
- ],
1523
- [MODEL, [VENDOR, LG], [TYPE, MOBILE]],
1524
- [
1525
- /(ideatab[-\w ]+)/i,
1526
- /lenovo ?(s[56]000[-\w]+|tab(?:[\w ]+)|yt[-\d\w]{6}|tb[-\d\w]{6})/i
1527
- ],
1528
- [MODEL, [VENDOR, "Lenovo"], [TYPE, TABLET]],
1529
- [
1530
- /(?:maemo|nokia).*(n900|lumia \d+)/i,
1531
- /nokia[-_ ]?([-\w\.]*)/i
1532
- ],
1533
- [[MODEL, /_/g, " "], [VENDOR, "Nokia"], [TYPE, MOBILE]],
1534
- [
1535
- /(pixel c)\b/i
1536
- ],
1537
- [MODEL, [VENDOR, GOOGLE], [TYPE, TABLET]],
1538
- [
1539
- /droid.+; (pixel[\daxl ]{0,6})(?: bui|\))/i
1540
- ],
1541
- [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]],
1542
- [
1543
- /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
1544
- ],
1545
- [MODEL, [VENDOR, SONY], [TYPE, MOBILE]],
1546
- [
1547
- /sony tablet [ps]/i,
1548
- /\b(?:sony)?sgp\w+(?: bui|\))/i
1549
- ],
1550
- [[MODEL, "Xperia Tablet"], [VENDOR, SONY], [TYPE, TABLET]],
1551
- [
1552
- / (kb2005|in20[12]5|be20[12][59])\b/i,
1553
- /(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i
1554
- ],
1555
- [MODEL, [VENDOR, "OnePlus"], [TYPE, MOBILE]],
1556
- [
1557
- /(alexa)webm/i,
1558
- /(kf[a-z]{2}wi)( bui|\))/i,
1559
- /(kf[a-z]+)( bui|\)).+silk\//i
1560
- ],
1561
- [MODEL, [VENDOR, AMAZON], [TYPE, TABLET]],
1562
- [
1563
- /((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i
1564
- ],
1565
- [[MODEL, /(.+)/g, "Fire Phone $1"], [VENDOR, AMAZON], [TYPE, MOBILE]],
1566
- [
1567
- /(playbook);[-\w\),; ]+(rim)/i
1568
- ],
1569
- [MODEL, VENDOR, [TYPE, TABLET]],
1570
- [
1571
- /\b((?:bb[a-f]|st[hv])100-\d)/i,
1572
- /\(bb10; (\w+)/i
1573
- ],
1574
- [MODEL, [VENDOR, BLACKBERRY], [TYPE, MOBILE]],
1575
- [
1576
- /(?:\b|asus_)(transfo[prime ]{4,10} \w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i
1577
- ],
1578
- [MODEL, [VENDOR, ASUS], [TYPE, TABLET]],
1579
- [
1580
- / (z[bes]6[027][012][km][ls]|zenfone \d\w?)\b/i
1581
- ],
1582
- [MODEL, [VENDOR, ASUS], [TYPE, MOBILE]],
1583
- [
1584
- /(nexus 9)/i
1585
- ],
1586
- [MODEL, [VENDOR, "HTC"], [TYPE, TABLET]],
1587
- [
1588
- /(htc)[-;_ ]{1,2}([\w ]+(?=\)| bui)|\w+)/i,
1589
- /(zte)[- ]([\w ]+?)(?: bui|\/|\))/i,
1590
- /(alcatel|geeksphone|nexian|panasonic|sony(?!-bra))[-_ ]?([-\w]*)/i
1591
- ],
1592
- [VENDOR, [MODEL, /_/g, " "], [TYPE, MOBILE]],
1593
- [
1594
- /droid.+; ([ab][1-7]-?[0178a]\d\d?)/i
1595
- ],
1596
- [MODEL, [VENDOR, "Acer"], [TYPE, TABLET]],
1597
- [
1598
- /droid.+; (m[1-5] note) bui/i,
1599
- /\bmz-([-\w]{2,})/i
1600
- ],
1601
- [MODEL, [VENDOR, "Meizu"], [TYPE, MOBILE]],
1602
- [
1603
- /\b(sh-?[altvz]?\d\d[a-ekm]?)/i
1604
- ],
1605
- [MODEL, [VENDOR, SHARP], [TYPE, MOBILE]],
1606
- [
1607
- /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron)[-_ ]?([-\w]*)/i,
1608
- /(hp) ([\w ]+\w)/i,
1609
- /(asus)-?(\w+)/i,
1610
- /(microsoft); (lumia[\w ]+)/i,
1611
- /(lenovo)[-_ ]?([-\w]+)/i,
1612
- /(jolla)/i,
1613
- /(oppo) ?([\w ]+) bui/i
1614
- ],
1615
- [VENDOR, MODEL, [TYPE, MOBILE]],
1616
- [
1617
- /(archos) (gamepad2?)/i,
1618
- /(hp).+(touchpad(?!.+tablet)|tablet)/i,
1619
- /(kindle)\/([\w\.]+)/i,
1620
- /(nook)[\w ]+build\/(\w+)/i,
1621
- /(dell) (strea[kpr\d ]*[\dko])/i,
1622
- /(le[- ]+pan)[- ]+(\w{1,9}) bui/i,
1623
- /(trinity)[- ]*(t\d{3}) bui/i,
1624
- /(gigaset)[- ]+(q\w{1,9}) bui/i,
1625
- /(vodafone) ([\w ]+)(?:\)| bui)/i
1626
- ],
1627
- [VENDOR, MODEL, [TYPE, TABLET]],
1628
- [
1629
- /(surface duo)/i
1630
- ],
1631
- [MODEL, [VENDOR, MICROSOFT], [TYPE, TABLET]],
1632
- [
1633
- /droid [\d\.]+; (fp\du?)(?: b|\))/i
1634
- ],
1635
- [MODEL, [VENDOR, "Fairphone"], [TYPE, MOBILE]],
1636
- [
1637
- /(u304aa)/i
1638
- ],
1639
- [MODEL, [VENDOR, "AT&T"], [TYPE, MOBILE]],
1640
- [
1641
- /\bsie-(\w*)/i
1642
- ],
1643
- [MODEL, [VENDOR, "Siemens"], [TYPE, MOBILE]],
1644
- [
1645
- /\b(rct\w+) b/i
1646
- ],
1647
- [MODEL, [VENDOR, "RCA"], [TYPE, TABLET]],
1648
- [
1649
- /\b(venue[\d ]{2,7}) b/i
1650
- ],
1651
- [MODEL, [VENDOR, "Dell"], [TYPE, TABLET]],
1652
- [
1653
- /\b(q(?:mv|ta)\w+) b/i
1654
- ],
1655
- [MODEL, [VENDOR, "Verizon"], [TYPE, TABLET]],
1656
- [
1657
- /\b(?:barnes[& ]+noble |bn[rt])([\w\+ ]*) b/i
1658
- ],
1659
- [MODEL, [VENDOR, "Barnes & Noble"], [TYPE, TABLET]],
1660
- [
1661
- /\b(tm\d{3}\w+) b/i
1662
- ],
1663
- [MODEL, [VENDOR, "NuVision"], [TYPE, TABLET]],
1664
- [
1665
- /\b(k88) b/i
1666
- ],
1667
- [MODEL, [VENDOR, "ZTE"], [TYPE, TABLET]],
1668
- [
1669
- /\b(nx\d{3}j) b/i
1670
- ],
1671
- [MODEL, [VENDOR, "ZTE"], [TYPE, MOBILE]],
1672
- [
1673
- /\b(gen\d{3}) b.+49h/i
1674
- ],
1675
- [MODEL, [VENDOR, "Swiss"], [TYPE, MOBILE]],
1676
- [
1677
- /\b(zur\d{3}) b/i
1678
- ],
1679
- [MODEL, [VENDOR, "Swiss"], [TYPE, TABLET]],
1680
- [
1681
- /\b((zeki)?tb.*\b) b/i
1682
- ],
1683
- [MODEL, [VENDOR, "Zeki"], [TYPE, TABLET]],
1684
- [
1685
- /\b([yr]\d{2}) b/i,
1686
- /\b(dragon[- ]+touch |dt)(\w{5}) b/i
1687
- ],
1688
- [[VENDOR, "Dragon Touch"], MODEL, [TYPE, TABLET]],
1689
- [
1690
- /\b(ns-?\w{0,9}) b/i
1691
- ],
1692
- [MODEL, [VENDOR, "Insignia"], [TYPE, TABLET]],
1693
- [
1694
- /\b((nxa|next)-?\w{0,9}) b/i
1695
- ],
1696
- [MODEL, [VENDOR, "NextBook"], [TYPE, TABLET]],
1697
- [
1698
- /\b(xtreme\_)?(v(1[045]|2[015]|[3469]0|7[05])) b/i
1699
- ],
1700
- [[VENDOR, "Voice"], MODEL, [TYPE, MOBILE]],
1701
- [
1702
- /\b(lvtel\-)?(v1[12]) b/i
1703
- ],
1704
- [[VENDOR, "LvTel"], MODEL, [TYPE, MOBILE]],
1705
- [
1706
- /\b(ph-1) /i
1707
- ],
1708
- [MODEL, [VENDOR, "Essential"], [TYPE, MOBILE]],
1709
- [
1710
- /\b(v(100md|700na|7011|917g).*\b) b/i
1711
- ],
1712
- [MODEL, [VENDOR, "Envizen"], [TYPE, TABLET]],
1713
- [
1714
- /\b(trio[-\w\. ]+) b/i
1715
- ],
1716
- [MODEL, [VENDOR, "MachSpeed"], [TYPE, TABLET]],
1717
- [
1718
- /\btu_(1491) b/i
1719
- ],
1720
- [MODEL, [VENDOR, "Rotor"], [TYPE, TABLET]],
1721
- [
1722
- /(shield[\w ]+) b/i
1723
- ],
1724
- [MODEL, [VENDOR, "Nvidia"], [TYPE, TABLET]],
1725
- [
1726
- /(sprint) (\w+)/i
1727
- ],
1728
- [VENDOR, MODEL, [TYPE, MOBILE]],
1729
- [
1730
- /(kin\.[onetw]{3})/i
1731
- ],
1732
- [[MODEL, /\./g, " "], [VENDOR, MICROSOFT], [TYPE, MOBILE]],
1733
- [
1734
- /droid.+; (cc6666?|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i
1735
- ],
1736
- [MODEL, [VENDOR, ZEBRA], [TYPE, TABLET]],
1737
- [
1738
- /droid.+; (ec30|ps20|tc[2-8]\d[kx])\)/i
1739
- ],
1740
- [MODEL, [VENDOR, ZEBRA], [TYPE, MOBILE]],
1741
- [
1742
- /(ouya)/i,
1743
- /(nintendo) ([wids3utch]+)/i
1744
- ],
1745
- [VENDOR, MODEL, [TYPE, CONSOLE]],
1746
- [
1747
- /droid.+; (shield) bui/i
1748
- ],
1749
- [MODEL, [VENDOR, "Nvidia"], [TYPE, CONSOLE]],
1750
- [
1751
- /(playstation [345portablevi]+)/i
1752
- ],
1753
- [MODEL, [VENDOR, SONY], [TYPE, CONSOLE]],
1754
- [
1755
- /\b(xbox(?: one)?(?!; xbox))[\); ]/i
1756
- ],
1757
- [MODEL, [VENDOR, MICROSOFT], [TYPE, CONSOLE]],
1758
- [
1759
- /smart-tv.+(samsung)/i
1760
- ],
1761
- [VENDOR, [TYPE, SMARTTV]],
1762
- [
1763
- /hbbtv.+maple;(\d+)/i
1764
- ],
1765
- [[MODEL, /^/, "SmartTV"], [VENDOR, SAMSUNG], [TYPE, SMARTTV]],
1766
- [
1767
- /(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i
1768
- ],
1769
- [[VENDOR, LG], [TYPE, SMARTTV]],
1770
- [
1771
- /(apple) ?tv/i
1772
- ],
1773
- [VENDOR, [MODEL, APPLE + " TV"], [TYPE, SMARTTV]],
1774
- [
1775
- /crkey/i
1776
- ],
1777
- [[MODEL, CHROME + "cast"], [VENDOR, GOOGLE], [TYPE, SMARTTV]],
1778
- [
1779
- /droid.+aft(\w)( bui|\))/i
1780
- ],
1781
- [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]],
1782
- [
1783
- /\(dtv[\);].+(aquos)/i,
1784
- /(aquos-tv[\w ]+)\)/i
1785
- ],
1786
- [MODEL, [VENDOR, SHARP], [TYPE, SMARTTV]],
1787
- [
1788
- /(bravia[\w ]+)( bui|\))/i
1789
- ],
1790
- [MODEL, [VENDOR, SONY], [TYPE, SMARTTV]],
1791
- [
1792
- /(mitv-\w{5}) bui/i
1793
- ],
1794
- [MODEL, [VENDOR, XIAOMI], [TYPE, SMARTTV]],
1795
- [
1796
- /\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i,
1797
- /hbbtv\/\d+\.\d+\.\d+ +\([\w ]*; *(\w[^;]*);([^;]*)/i
1798
- ],
1799
- [[VENDOR, trim], [MODEL, trim], [TYPE, SMARTTV]],
1800
- [
1801
- /\b(android tv|smart[- ]?tv|opera tv|tv; rv:)\b/i
1802
- ],
1803
- [[TYPE, SMARTTV]],
1804
- [
1805
- /((pebble))app/i
1806
- ],
1807
- [VENDOR, MODEL, [TYPE, WEARABLE]],
1808
- [
1809
- /droid.+; (glass) \d/i
1810
- ],
1811
- [MODEL, [VENDOR, GOOGLE], [TYPE, WEARABLE]],
1812
- [
1813
- /droid.+; (wt63?0{2,3})\)/i
1814
- ],
1815
- [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]],
1816
- [
1817
- /(quest( 2)?)/i
1818
- ],
1819
- [MODEL, [VENDOR, FACEBOOK], [TYPE, WEARABLE]],
1820
- [
1821
- /(tesla)(?: qtcarbrowser|\/[-\w\.]+)/i
1822
- ],
1823
- [VENDOR, [TYPE, EMBEDDED]],
1824
- [
1825
- /droid .+?; ([^;]+?)(?: bui|\) applew).+? mobile safari/i
1826
- ],
1827
- [MODEL, [TYPE, MOBILE]],
1828
- [
1829
- /droid .+?; ([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i
1830
- ],
1831
- [MODEL, [TYPE, TABLET]],
1832
- [
1833
- /\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i
1834
- ],
1835
- [[TYPE, TABLET]],
1836
- [
1837
- /(phone|mobile(?:[;\/]| [ \w\/\.]*safari)|pda(?=.+windows ce))/i
1838
- ],
1839
- [[TYPE, MOBILE]],
1840
- [
1841
- /(android[-\w\. ]{0,9});.+buil/i
1842
- ],
1843
- [MODEL, [VENDOR, "Generic"]]
1844
- ],
1845
- engine: [
1846
- [
1847
- /windows.+ edge\/([\w\.]+)/i
1848
- ],
1849
- [VERSION, [NAME, EDGE + "HTML"]],
1850
- [
1851
- /webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i
1852
- ],
1853
- [VERSION, [NAME, "Blink"]],
1854
- [
1855
- /(presto)\/([\w\.]+)/i,
1856
- /(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna)\/([\w\.]+)/i,
1857
- /ekioh(flow)\/([\w\.]+)/i,
1858
- /(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i,
1859
- /(icab)[\/ ]([23]\.[\d\.]+)/i
1860
- ],
1861
- [NAME, VERSION],
1862
- [
1863
- /rv\:([\w\.]{1,9})\b.+(gecko)/i
1864
- ],
1865
- [VERSION, NAME]
1866
- ],
1867
- os: [
1868
- [
1869
- /microsoft (windows) (vista|xp)/i
1870
- ],
1871
- [NAME, VERSION],
1872
- [
1873
- /(windows) nt 6\.2; (arm)/i,
1874
- /(windows (?:phone(?: os)?|mobile))[\/ ]?([\d\.\w ]*)/i,
1875
- /(windows)[\/ ]?([ntce\d\. ]+\w)(?!.+xbox)/i
1876
- ],
1877
- [NAME, [VERSION, strMapper, windowsVersionMap]],
1878
- [
1879
- /(win(?=3|9|n)|win 9x )([nt\d\.]+)/i
1880
- ],
1881
- [[NAME, "Windows"], [VERSION, strMapper, windowsVersionMap]],
1882
- [
1883
- /ip[honead]{2,4}\b(?:.*os ([\w]+) like mac|; opera)/i,
1884
- /cfnetwork\/.+darwin/i
1885
- ],
1886
- [[VERSION, /_/g, "."], [NAME, "iOS"]],
1887
- [
1888
- /(mac os x) ?([\w\. ]*)/i,
1889
- /(macintosh|mac_powerpc\b)(?!.+haiku)/i
1890
- ],
1891
- [[NAME, "Mac OS"], [VERSION, /_/g, "."]],
1892
- [
1893
- /droid ([\w\.]+)\b.+(android[- ]x86|harmonyos)/i
1894
- ],
1895
- [VERSION, NAME],
1896
- [
1897
- /(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish)[-\/ ]?([\w\.]*)/i,
1898
- /(blackberry)\w*\/([\w\.]*)/i,
1899
- /(tizen|kaios)[\/ ]([\w\.]+)/i,
1900
- /\((series40);/i
1901
- ],
1902
- [NAME, VERSION],
1903
- [
1904
- /\(bb(10);/i
1905
- ],
1906
- [VERSION, [NAME, BLACKBERRY]],
1907
- [
1908
- /(?:symbian ?os|symbos|s60(?=;)|series60)[-\/ ]?([\w\.]*)/i
1909
- ],
1910
- [VERSION, [NAME, "Symbian"]],
1911
- [
1912
- /mozilla\/[\d\.]+ \((?:mobile|tablet|tv|mobile; [\w ]+); rv:.+ gecko\/([\w\.]+)/i
1913
- ],
1914
- [VERSION, [NAME, FIREFOX + " OS"]],
1915
- [
1916
- /web0s;.+rt(tv)/i,
1917
- /\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i
1918
- ],
1919
- [VERSION, [NAME, "webOS"]],
1920
- [
1921
- /crkey\/([\d\.]+)/i
1922
- ],
1923
- [VERSION, [NAME, CHROME + "cast"]],
1924
- [
1925
- /(cros) [\w]+ ([\w\.]+\w)/i
1926
- ],
1927
- [[NAME, "Chromium OS"], VERSION],
1928
- [
1929
- /(nintendo|playstation) ([wids345portablevuch]+)/i,
1930
- /(xbox); +xbox ([^\);]+)/i,
1931
- /\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i,
1932
- /(mint)[\/\(\) ]?(\w*)/i,
1933
- /(mageia|vectorlinux)[; ]/i,
1934
- /([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,
1935
- /(hurd|linux) ?([\w\.]*)/i,
1936
- /(gnu) ?([\w\.]*)/i,
1937
- /\b([-frentopcghs]{0,5}bsd|dragonfly)[\/ ]?(?!amd|[ix346]{1,2}86)([\w\.]*)/i,
1938
- /(haiku) (\w+)/i
1939
- ],
1940
- [NAME, VERSION],
1941
- [
1942
- /(sunos) ?([\w\.\d]*)/i
1943
- ],
1944
- [[NAME, "Solaris"], VERSION],
1945
- [
1946
- /((?:open)?solaris)[-\/ ]?([\w\.]*)/i,
1947
- /(aix) ((\d)(?=\.|\)| )[\w\.])*/i,
1948
- /\b(beos|os\/2|amigaos|morphos|openvms|fuchsia|hp-ux)/i,
1949
- /(unix) ?([\w\.]*)/i
1950
- ],
1951
- [NAME, VERSION]
1952
- ]
1953
- };
1954
- var UAParser = function(ua, extensions) {
1955
- if (typeof ua === OBJ_TYPE) {
1956
- extensions = ua;
1957
- ua = undefined$1;
1958
- }
1959
- if (!(this instanceof UAParser)) {
1960
- return new UAParser(ua, extensions).getResult();
1142
+ }
1143
+ this.coords.level = tmpLevel;
1144
+ }
1145
+ _inferNodeLevelByRecursion() {
1146
+ const { level } = this.coords;
1147
+ if (level === null || !Level.isRange(level)) {
1148
+ return;
1149
+ }
1150
+ if (this.edges.length > 1) {
1151
+ return;
1152
+ }
1153
+ const lookForLevel = (node, visitedNodes) => {
1154
+ visitedNodes.push(node);
1155
+ if (node.coords.level === null) {
1156
+ return null;
1961
1157
  }
1962
- var _ua = ua || (typeof window2 !== UNDEF_TYPE && window2.navigator && window2.navigator.userAgent ? window2.navigator.userAgent : EMPTY);
1963
- var _rgxmap = extensions ? extend(regexes, extensions) : regexes;
1964
- this.getBrowser = function() {
1965
- var _browser = {};
1966
- _browser[NAME] = undefined$1;
1967
- _browser[VERSION] = undefined$1;
1968
- rgxMapper.call(_browser, _ua, _rgxmap.browser);
1969
- _browser.major = majorize(_browser.version);
1970
- return _browser;
1971
- };
1972
- this.getCPU = function() {
1973
- var _cpu = {};
1974
- _cpu[ARCHITECTURE] = undefined$1;
1975
- rgxMapper.call(_cpu, _ua, _rgxmap.cpu);
1976
- return _cpu;
1977
- };
1978
- this.getDevice = function() {
1979
- var _device = {};
1980
- _device[VENDOR] = undefined$1;
1981
- _device[MODEL] = undefined$1;
1982
- _device[TYPE] = undefined$1;
1983
- rgxMapper.call(_device, _ua, _rgxmap.device);
1984
- return _device;
1985
- };
1986
- this.getEngine = function() {
1987
- var _engine = {};
1988
- _engine[NAME] = undefined$1;
1989
- _engine[VERSION] = undefined$1;
1990
- rgxMapper.call(_engine, _ua, _rgxmap.engine);
1991
- return _engine;
1992
- };
1993
- this.getOS = function() {
1994
- var _os = {};
1995
- _os[NAME] = undefined$1;
1996
- _os[VERSION] = undefined$1;
1997
- rgxMapper.call(_os, _ua, _rgxmap.os);
1998
- return _os;
1999
- };
2000
- this.getResult = function() {
2001
- return {
2002
- ua: this.getUA(),
2003
- browser: this.getBrowser(),
2004
- engine: this.getEngine(),
2005
- os: this.getOS(),
2006
- device: this.getDevice(),
2007
- cpu: this.getCPU()
2008
- };
2009
- };
2010
- this.getUA = function() {
2011
- return _ua;
2012
- };
2013
- this.setUA = function(ua2) {
2014
- _ua = typeof ua2 === STR_TYPE && ua2.length > UA_MAX_LENGTH ? trim(ua2, UA_MAX_LENGTH) : ua2;
2015
- return this;
2016
- };
2017
- this.setUA(_ua);
2018
- return this;
2019
- };
2020
- UAParser.VERSION = LIBVERSION;
2021
- UAParser.BROWSER = enumerize([NAME, VERSION, MAJOR]);
2022
- UAParser.CPU = enumerize([ARCHITECTURE]);
2023
- UAParser.DEVICE = enumerize([MODEL, VENDOR, TYPE, CONSOLE, MOBILE, SMARTTV, TABLET, WEARABLE, EMBEDDED]);
2024
- UAParser.ENGINE = UAParser.OS = enumerize([NAME, VERSION]);
2025
- {
2026
- if (module2.exports) {
2027
- exports2 = module2.exports = UAParser;
1158
+ if (!Level.isRange(node.coords.level)) {
1159
+ return node.coords.level;
2028
1160
  }
2029
- exports2.UAParser = UAParser;
2030
- }
2031
- var $ = typeof window2 !== UNDEF_TYPE && (window2.jQuery || window2.Zepto);
2032
- if ($ && !$.ua) {
2033
- var parser = new UAParser();
2034
- $.ua = parser.getResult();
2035
- $.ua.get = function() {
2036
- return parser.getUA();
2037
- };
2038
- $.ua.set = function(ua) {
2039
- parser.setUA(ua);
2040
- var result = parser.getResult();
2041
- for (var prop in result) {
2042
- $.ua[prop] = result[prop];
2043
- }
2044
- };
2045
- }
2046
- })(typeof window === "object" ? window : commonjsGlobal);
2047
- })(uaParser, uaParser.exports);
2048
- var __defProp2 = Object.defineProperty;
2049
- var __defNormalProp2 = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
2050
- var __publicField2 = (obj, key, value) => {
2051
- __defNormalProp2(obj, typeof key !== "symbol" ? key + "" : key, value);
2052
- return value;
2053
- };
2054
- const Browser = {
2055
- UNKNOWN: "Unknown",
2056
- SAFARI: "Safari",
2057
- FIREFOX: "Firefox",
2058
- OPERA: "Opera",
2059
- CHROME: "Chrome",
2060
- IOS_WEBVIEW: "iOS-webview"
2061
- };
2062
- class BrowserUtils {
2063
- static getName() {
2064
- if (!this._name) {
2065
- if (typeof navigator === "undefined" || !navigator) {
2066
- this._name = Browser.UNKNOWN;
2067
- } else {
2068
- const { userAgent } = navigator;
2069
- if (userAgent.match(/Firefox/i)) {
2070
- this._name = Browser.FIREFOX;
2071
- } else if (userAgent.match(/(Opera|OPR)/i)) {
2072
- this._name = Browser.OPERA;
2073
- } else if (userAgent.match(/Chrome/i)) {
2074
- this._name = Browser.CHROME;
2075
- } else if (userAgent.match(/Safari/i)) {
2076
- this._name = Browser.SAFARI;
2077
- } else if (userAgent.match(/(iPhone|iPod|iPad).*AppleWebKit(?!.*Version)/i)) {
2078
- this._name = Browser.IOS_WEBVIEW;
2079
- } else {
2080
- this._name = Browser.UNKNOWN;
1161
+ let tmpLevel = null;
1162
+ for (let i = 0; i < node.edges.length; i++) {
1163
+ const edge = node.edges[i];
1164
+ const otherNode = edge.node1 === node ? edge.node2 : edge.node1;
1165
+ if (!visitedNodes.includes(otherNode)) {
1166
+ tmpLevel = Level.union(lookForLevel(otherNode, visitedNodes), tmpLevel);
2081
1167
  }
2082
1168
  }
2083
- }
2084
- return this._name;
2085
- }
2086
- static get isMobile() {
2087
- if (this._isMobile === null) {
2088
- this._isMobile = false;
2089
- if (typeof navigator !== "undefined" && navigator) {
2090
- const userAgent = navigator.userAgent || navigator.vendor;
2091
- 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)))) {
2092
- this._isMobile = true;
2093
- }
1169
+ return tmpLevel;
1170
+ };
1171
+ const othersLevels = lookForLevel(this, []);
1172
+ if (othersLevels !== null) {
1173
+ if (!Level.isRange(othersLevels)) {
1174
+ this.coords.level = othersLevels === level[0] ? level[1] : level[0];
1175
+ return;
2094
1176
  }
2095
- }
2096
- return this._isMobile;
2097
- }
2098
- static clearCache() {
2099
- this._name = null;
2100
- this._isMobile = null;
2101
- }
2102
- }
2103
- __publicField2(BrowserUtils, "_name", null);
2104
- __publicField2(BrowserUtils, "_isMobile", null);
2105
- const _GraphVertex = class {
2106
- constructor(params = {}) {
2107
- __publicField2(this, "name", null);
2108
- __publicField2(this, "data", null);
2109
- __publicField2(this, "id");
2110
- __publicField2(this, "edges", []);
2111
- Object.assign(this, params);
2112
- if (typeof params.id === "number") {
2113
- this.id = params.id;
2114
- GraphEdge.currentUniqueId = Math.max(GraphEdge.currentUniqueId, params.id + 1);
2115
- } else {
2116
- this.id = _GraphVertex.currentUniqueId++;
1177
+ throw Error("Level of: " + this.coords.toString() + " cannot be decided");
2117
1178
  }
2118
1179
  }
2119
- };
2120
- let GraphVertex = _GraphVertex;
2121
- __publicField2(GraphVertex, "currentUniqueId", 0);
2122
- const _GraphEdge = class {
2123
- constructor(vertex1, vertex2, params = {}) {
2124
- __publicField2(this, "name", null);
2125
- __publicField2(this, "data", null);
2126
- __publicField2(this, "id");
2127
- __publicField2(this, "_vertex1");
2128
- __publicField2(this, "_vertex2");
2129
- Object.assign(this, params);
2130
- this.vertex1 = vertex1;
2131
- this.vertex2 = vertex2;
2132
- if (typeof params.id === "number") {
2133
- this.id = params.id;
2134
- _GraphEdge.currentUniqueId = Math.max(_GraphEdge.currentUniqueId, params.id + 1);
2135
- } else {
2136
- this.id = GraphVertex.currentUniqueId++;
1180
+ _inferNodeLevelByNeighboors() {
1181
+ const { level } = this.coords;
1182
+ if (level === null || !Level.isRange(level)) {
1183
+ return true;
2137
1184
  }
2138
- }
2139
- get vertex1() {
2140
- return this._vertex1;
2141
- }
2142
- set vertex1(vertex) {
2143
- if (this._vertex1 && this._vertex2 !== this._vertex1) {
2144
- this._vertex1.edges = this._vertex1.edges.filter((edge) => edge !== this);
1185
+ let tmpLevel = null;
1186
+ for (let i = 0; i < this.edges.length; i++) {
1187
+ const edge = this.edges[i];
1188
+ const otherNode = edge.node1 === this ? edge.node2 : edge.node1;
1189
+ tmpLevel = Level.union(otherNode.coords.level, tmpLevel);
2145
1190
  }
2146
- vertex.edges.push(this);
2147
- this._vertex1 = vertex;
2148
- }
2149
- get vertex2() {
2150
- return this._vertex2;
2151
- }
2152
- set vertex2(vertex) {
2153
- if (this._vertex2 && this._vertex2 !== this._vertex1) {
2154
- this._vertex2.edges = this._vertex2.edges.filter((edge) => edge !== this);
1191
+ if (tmpLevel === null || !Level.isRange(tmpLevel)) {
1192
+ this.coords.level = tmpLevel === level[0] ? level[1] : level[0];
2155
1193
  }
2156
- vertex.edges.push(this);
2157
- this._vertex2 = vertex;
2158
- }
2159
- static getEdgeByVertices(edges, vertex1, vertex2) {
2160
- return edges.find(
2161
- (edge) => vertex1 === edge.vertex1 && vertex2 === edge.vertex2 || vertex2 === edge.vertex1 && vertex1 === edge.vertex2
2162
- );
2163
- }
2164
- };
2165
- let GraphEdge = _GraphEdge;
2166
- __publicField2(GraphEdge, "currentUniqueId", 0);
2167
- class Graph {
2168
- constructor(vertices, edges) {
2169
- __publicField2(this, "vertices");
2170
- __publicField2(this, "edges");
2171
- this.vertices = Array.isArray(vertices) ? vertices : [];
2172
- this.edges = Array.isArray(edges) ? edges : [];
2173
- }
2174
- getEdgeByVertices(vertex1, vertex2) {
2175
- return GraphEdge.getEdgeByVertices(this.edges, vertex1, vertex2);
2176
- }
2177
- getVertexByName(name) {
2178
- return this.vertices.find((vertex) => vertex.name === name);
1194
+ return true;
2179
1195
  }
2180
- getEdgeByName(name) {
2181
- return this.edges.find((edge) => edge.name === name);
1196
+ _checkIO() {
1197
+ this.io = this.coords.level !== null && this.edges.some((edge) => edge.level === null);
1198
+ return true;
2182
1199
  }
2183
- toDetailedString() {
2184
- let output = `--- Network ---
2185
- Vertices: ${this.vertices.length}
2186
- Edges: ${this.edges.length}
2187
- ---
2188
- Vertices
2189
- `;
2190
- this.vertices.forEach((vertex) => {
2191
- output += `${vertex.id} [edges: ${vertex.edges.length}]
2192
- `;
2193
- });
2194
- output += "---\nEdges\n";
2195
- this.edges.forEach((edge) => {
2196
- output += `${edge.id} `;
2197
- output += `[${edge.vertex1.id} -- ${edge.vertex2.id}]
2198
- `;
2199
- });
2200
- output += "---";
2201
- return output;
1200
+ static generateNodesLevels(nodes) {
1201
+ nodes.forEach((node) => node._generateLevelFromEdges());
1202
+ nodes.forEach((node) => node._inferNodeLevelByNeighboors());
1203
+ nodes.forEach((node) => node._inferNodeLevelByRecursion());
1204
+ nodes.forEach((node) => node._checkIO());
2202
1205
  }
2203
1206
  }
2204
- class GeoGraphEdge extends GraphEdge {
2205
- constructor(vertex1, vertex2, params) {
2206
- super(vertex1, vertex2, params);
1207
+ class GraphEdge {
1208
+ constructor(node1, node2, level = null, builtFrom = null) {
1209
+ __publicField(this, "_node1");
1210
+ __publicField(this, "_node2");
2207
1211
  __publicField(this, "_level", null);
2208
1212
  __publicField(this, "_bearing", null);
2209
1213
  __publicField(this, "_length", null);
2210
1214
  __publicField(this, "_computedSizeAndBearing", false);
1215
+ __publicField(this, "builtFrom");
2211
1216
  __publicField(this, "isOneway", false);
2212
- Object.assign(this, params);
1217
+ this.node1 = node1;
1218
+ this.node2 = node2;
1219
+ this.level = level;
1220
+ this.builtFrom = builtFrom;
1221
+ }
1222
+ get node1() {
1223
+ return this._node1;
2213
1224
  }
2214
- set vertex1(vertex) {
2215
- super.vertex1 = vertex;
1225
+ set node1(node) {
1226
+ if (!(node instanceof GraphNode)) {
1227
+ throw new TypeError("node1 is not a GraphNode");
1228
+ }
1229
+ if (this._node1 instanceof GraphNode && this._node2 !== this._node1) {
1230
+ this._node1.edges = this._node1.edges.filter((edge) => edge !== this);
1231
+ }
1232
+ node.edges.push(this);
1233
+ this._node1 = node;
2216
1234
  this._computedSizeAndBearing = false;
2217
1235
  }
2218
- get vertex1() {
2219
- return this._vertex1;
1236
+ get node2() {
1237
+ return this._node2;
2220
1238
  }
2221
- set vertex2(vertex) {
2222
- super.vertex2 = vertex;
1239
+ set node2(node) {
1240
+ if (!(node instanceof GraphNode)) {
1241
+ throw new TypeError("node2 is not a GraphNode");
1242
+ }
1243
+ if (this._node2 instanceof GraphNode && this._node2 !== this._node1) {
1244
+ this._node2.edges = this._node2.edges.filter((edge) => edge !== this);
1245
+ }
1246
+ node.edges.push(this);
1247
+ this._node2 = node;
2223
1248
  this._computedSizeAndBearing = false;
2224
1249
  }
2225
- get vertex2() {
2226
- return this._vertex2;
2227
- }
2228
1250
  get level() {
2229
1251
  return this._level;
2230
1252
  }
@@ -2245,206 +1267,159 @@ class GeoGraphEdge extends GraphEdge {
2245
1267
  return this._length;
2246
1268
  }
2247
1269
  _computeSizeAndBearing() {
2248
- this._length = this.vertex1.distanceTo(this.vertex2);
2249
- this._bearing = this.vertex1.bearingTo(this.vertex2);
1270
+ this._length = this.node1.distanceTo(this.node2);
1271
+ this._bearing = this.node1.bearingTo(this.node2);
2250
1272
  this._computedSizeAndBearing = true;
2251
1273
  }
2252
- static getEdgeByVertices(edges, vertex1, vertex2) {
2253
- return super.getEdgeByVertices(edges, vertex1, vertex2);
2254
- }
2255
- }
2256
- class GeoGraphVertex extends GraphVertex {
2257
- constructor(coords, params) {
2258
- super(params);
2259
- __publicField(this, "coords");
2260
- __publicField(this, "io", false);
2261
- this.coords = coords;
2262
- }
2263
- distanceTo(other) {
2264
- return this.coords.distanceTo(other.coords);
2265
- }
2266
- bearingTo(other) {
2267
- return this.coords.bearingTo(other.coords);
2268
- }
2269
- toJson() {
2270
- return this.coords.toCompressedJson();
2271
- }
2272
- static fromJson(json) {
2273
- return new GeoGraphVertex(Coordinates.fromCompressedJson(json));
2274
- }
2275
- inferVertexLevelFromEdges() {
2276
- let tmpLevel = null;
2277
- for (let i = 0; i < this.edges.length; i++) {
2278
- const edge = this.edges[i];
2279
- if (edge.level !== null) {
2280
- if (tmpLevel === null) {
2281
- tmpLevel = Level.clone(edge.level);
2282
- } else {
2283
- tmpLevel = Level.intersection(tmpLevel, edge.level);
2284
- if (tmpLevel === null) {
2285
- throw Error("Something bad happend during parsing: We cannot retrieve vertex level from adjacent ways: " + this.coords);
2286
- }
2287
- }
2288
- }
2289
- }
2290
- this.coords.level = tmpLevel;
2291
- }
2292
- inferVertexLevelByNeighboors() {
2293
- const { level } = this.coords;
2294
- if (level === null || !Level.isRange(level)) {
1274
+ equals(other) {
1275
+ if (this === other) {
2295
1276
  return true;
2296
1277
  }
2297
- let tmpLevel = null;
2298
- for (let i = 0; i < this.edges.length; i++) {
2299
- const edge = this.edges[i];
2300
- const otherVertex = edge.vertex1 === this ? edge.vertex2 : edge.vertex1;
2301
- tmpLevel = Level.union(otherVertex.coords.level, tmpLevel);
2302
- }
2303
- if (tmpLevel === null || !Level.isRange(tmpLevel)) {
2304
- this.coords.level = tmpLevel === level[0] ? level[1] : level[0];
1278
+ if (!(other instanceof GraphEdge)) {
1279
+ return false;
2305
1280
  }
2306
- return true;
1281
+ return other.node1.equals(this.node1) && other.node2.equals(this.node2) && Level.equals(other.level, this.level) && other.isOneway === this.isOneway && other.builtFrom === this.builtFrom;
2307
1282
  }
2308
- inferVertexLevelByRecursion() {
2309
- const { level } = this.coords;
2310
- if (level === null || !Level.isRange(level)) {
2311
- return;
2312
- }
2313
- if (this.edges.length > 1) {
2314
- return;
2315
- }
2316
- const lookForLevel = (vertex, visitedVertices) => {
2317
- visitedVertices.push(vertex);
2318
- if (vertex.coords.level === null) {
2319
- return null;
2320
- }
2321
- if (!Level.isRange(vertex.coords.level)) {
2322
- return vertex.coords.level;
2323
- }
2324
- let tmpLevel = null;
2325
- for (let i = 0; i < vertex.edges.length; i++) {
2326
- const edge = vertex.edges[i];
2327
- const otherVertex = edge.vertex1 === vertex ? edge.vertex2 : edge.vertex1;
2328
- if (!visitedVertices.includes(otherVertex)) {
2329
- tmpLevel = Level.union(lookForLevel(otherVertex, visitedVertices), tmpLevel);
2330
- }
2331
- }
2332
- return tmpLevel;
2333
- };
2334
- const othersLevels = lookForLevel(this, []);
2335
- if (othersLevels !== null) {
2336
- if (!Level.isRange(othersLevels)) {
2337
- this.coords.level = othersLevels === level[0] ? level[1] : level[0];
2338
- return;
2339
- }
2340
- throw Error("Level of: " + this.coords.toString() + " cannot be decided");
2341
- }
1283
+ clone() {
1284
+ const edge = new GraphEdge(this.node1, this.node2, this.level, this.builtFrom);
1285
+ edge.isOneway = this.isOneway;
1286
+ return edge;
2342
1287
  }
2343
1288
  }
2344
- class GeoGraph extends Graph {
2345
- constructor(vertices, edges, generateVerticesLevels = false) {
2346
- super(vertices, edges);
2347
- generateVerticesLevels && this.generateVerticesLevels();
2348
- }
2349
- getVertexByCoords(coords) {
2350
- return GeoGraph.getVertexByCoords(this.vertices, coords);
2351
- }
2352
- static getVertexByCoords(vertices, coords) {
2353
- return vertices.find((vertex) => vertex.coords.equals(coords));
1289
+ function getEdgeByNodes(edges, node1, node2) {
1290
+ return edges.find(
1291
+ (edge) => node1 === edge.node1 && node2 === edge.node2 || node2 === edge.node1 && node1 === edge.node2
1292
+ );
1293
+ }
1294
+ function getNodeByCoords(nodes, coords) {
1295
+ return nodes.find((node) => node.coords.equals(coords));
1296
+ }
1297
+ const GraphUtils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1298
+ __proto__: null,
1299
+ getEdgeByNodes,
1300
+ getNodeByCoords
1301
+ }, Symbol.toStringTag, { value: "Module" }));
1302
+ class Network {
1303
+ constructor(nodes, edges) {
1304
+ __publicField(this, "nodes");
1305
+ __publicField(this, "edges");
1306
+ this.nodes = Array.isArray(nodes) ? nodes : [];
1307
+ this.edges = Array.isArray(edges) ? edges : [];
2354
1308
  }
2355
- getVertexByName(name) {
2356
- return super.getVertexByName(name);
1309
+ getNodeByCoords(coords) {
1310
+ return this.nodes.find((node) => node.coords.equals(coords));
2357
1311
  }
2358
- getEdgeByName(name) {
2359
- return super.getEdgeByName(name);
1312
+ getEdgeByNodes(node1, node2) {
1313
+ return getEdgeByNodes(this.edges, node1, node2);
2360
1314
  }
2361
1315
  getBoundingBox(extendedMeasure) {
2362
- if (!this.vertices.length) {
1316
+ if (!this.nodes.length) {
2363
1317
  return null;
2364
1318
  }
2365
- const boundingBox = BoundingBox.fromCoordinates(this.vertices.map((vertex) => vertex.coords));
1319
+ const boundingBox = BoundingBox.fromCoordinates(this.nodes.map((node) => node.coords));
2366
1320
  if (extendedMeasure) {
2367
1321
  boundingBox.extendsWithMeasure(extendedMeasure);
2368
1322
  }
2369
1323
  return boundingBox;
2370
1324
  }
1325
+ toDetailedString(_nodeToStringFn, _edgeToStringFn) {
1326
+ let nodeToStringFn = _nodeToStringFn;
1327
+ if (!nodeToStringFn) {
1328
+ nodeToStringFn = (node) => `${node.builtFrom}`;
1329
+ }
1330
+ let edgeToStringFn = _edgeToStringFn;
1331
+ if (!_edgeToStringFn) {
1332
+ edgeToStringFn = (edge) => `${edge.builtFrom}`;
1333
+ }
1334
+ let output = `--- Network ---
1335
+ Nodes: ${this.nodes.length}
1336
+ Edges: ${this.edges.length}
1337
+ ---
1338
+ Nodes
1339
+ `;
1340
+ this.nodes.forEach((node) => {
1341
+ output += `${nodeToStringFn(node)} [edges: ${node.edges.length}]
1342
+ `;
1343
+ });
1344
+ output += "---\nEdges\n";
1345
+ this.edges.forEach((edge) => {
1346
+ output += `${edgeToStringFn(edge)} `;
1347
+ output += `[${nodeToStringFn(edge.node1)} -- ${nodeToStringFn(edge.node2)}]
1348
+ `;
1349
+ });
1350
+ output += "---";
1351
+ return output;
1352
+ }
2371
1353
  toCompressedJson() {
2372
1354
  return {
2373
- vertices: this.vertices.map((vertex) => vertex.toJson()),
1355
+ nodes: this.nodes.map((node) => node.toJson()),
2374
1356
  edges: this.edges.map((edge) => {
2375
- const vertex1Idx = this.vertices.indexOf(edge.vertex1);
2376
- const vertex2Idx = this.vertices.indexOf(edge.vertex2);
1357
+ const node1Idx = this.nodes.indexOf(edge.node1);
1358
+ const node2Idx = this.nodes.indexOf(edge.node2);
2377
1359
  if (edge.isOneway) {
2378
- return [vertex1Idx, vertex2Idx, edge.level, true];
1360
+ return [node1Idx, node2Idx, edge.level, true];
2379
1361
  }
2380
- if (edge.level !== null) {
2381
- return [vertex1Idx, vertex2Idx, edge.level];
1362
+ if (edge.level) {
1363
+ return [node1Idx, node2Idx, edge.level];
2382
1364
  }
2383
- return [vertex1Idx, vertex2Idx];
1365
+ return [node1Idx, node2Idx];
2384
1366
  })
2385
1367
  };
2386
1368
  }
2387
1369
  static fromCompressedJson(json) {
2388
- const geograph = new GeoGraph();
2389
- geograph.vertices = json.vertices.map((vertex) => GeoGraphVertex.fromJson(vertex));
2390
- geograph.edges = json.edges.map((jsonEdge) => {
2391
- const edge = new GeoGraphEdge(
2392
- geograph.vertices[jsonEdge[0]],
2393
- geograph.vertices[jsonEdge[1]],
2394
- { level: jsonEdge.length > 2 ? jsonEdge[2] : null }
1370
+ const network = new Network();
1371
+ network.nodes = json.nodes.map((node) => GraphNode.fromJson(node, null));
1372
+ network.edges = json.edges.map((jsonEdge) => {
1373
+ const edge = new GraphEdge(
1374
+ network.nodes[jsonEdge[0]],
1375
+ network.nodes[jsonEdge[1]],
1376
+ jsonEdge[2],
1377
+ null
2395
1378
  );
2396
1379
  if (jsonEdge.length > 3 && jsonEdge[3]) {
2397
1380
  edge.isOneway = true;
2398
1381
  }
2399
1382
  return edge;
2400
1383
  });
2401
- return geograph;
1384
+ return network;
2402
1385
  }
2403
1386
  static fromCoordinates(segments) {
2404
- const geograph = new GeoGraph();
2405
- const getOrCreateVertex = (coords) => {
2406
- const vertex = geograph.vertices.find((otherVertex) => otherVertex.coords.equals(coords));
2407
- if (vertex) {
2408
- return vertex;
1387
+ const network = new Network();
1388
+ const getOrCreateNode = (coords) => {
1389
+ const node = network.nodes.find((otherNode) => otherNode.coords.equals(coords));
1390
+ if (node) {
1391
+ return node;
2409
1392
  }
2410
- const newVertex = new GeoGraphVertex(coords);
2411
- geograph.vertices.push(newVertex);
2412
- return newVertex;
1393
+ const newNode = new GraphNode(coords, null);
1394
+ network.nodes.push(newNode);
1395
+ return newNode;
2413
1396
  };
2414
- const createEdgeFromVertices = (vertex1, vertex2) => new GeoGraphEdge(
2415
- vertex1,
2416
- vertex2,
2417
- { level: Level.union(vertex1.coords.level, vertex2.coords.level) }
1397
+ const createEdgeFromNodes = (node1, node2) => new GraphEdge(
1398
+ node1,
1399
+ node2,
1400
+ Level.union(node1.coords.level, node2.coords.level),
1401
+ null
2418
1402
  );
2419
1403
  for (const segment of segments) {
2420
- let previousVertex = null;
1404
+ let previousNode = null;
2421
1405
  for (const coords of segment) {
2422
- const currentVertex = getOrCreateVertex(coords);
2423
- if (previousVertex) {
2424
- const edge = createEdgeFromVertices(currentVertex, previousVertex);
2425
- geograph.edges.push(edge);
1406
+ const currentNode = getOrCreateNode(coords);
1407
+ if (previousNode) {
1408
+ const edge = createEdgeFromNodes(currentNode, previousNode);
1409
+ network.edges.push(edge);
2426
1410
  }
2427
- previousVertex = currentVertex;
1411
+ previousNode = currentNode;
2428
1412
  }
2429
1413
  }
2430
- return geograph;
1414
+ return network;
2431
1415
  }
2432
1416
  getEdgesAtLevel(targetLevel, useMultiLevelEdges = true) {
2433
1417
  return this.edges.filter(
2434
1418
  ({ level }) => useMultiLevelEdges ? Level.intersect(targetLevel, level) : Level.contains(targetLevel, level)
2435
1419
  );
2436
1420
  }
2437
- generateVerticesLevels() {
2438
- const { vertices } = this;
2439
- vertices.forEach((vertex) => vertex.inferVertexLevelFromEdges());
2440
- vertices.forEach((vertex) => vertex.inferVertexLevelByNeighboors());
2441
- vertices.forEach((vertex) => vertex.inferVertexLevelByRecursion());
2442
- vertices.forEach((vertex) => {
2443
- vertex.io = vertex.coords.level !== null && vertex.edges.some((edge) => edge.level === null);
2444
- });
2445
- }
2446
1421
  }
2447
- class GeoGraphProjection {
1422
+ class GraphProjection {
2448
1423
  constructor(origin, distanceFromNearestElement, coords, nearestElement) {
2449
1424
  __publicField(this, "origin");
2450
1425
  __publicField(this, "distanceFromNearestElement");
@@ -2456,12 +1431,12 @@ class GeoGraphProjection {
2456
1431
  this.nearestElement = nearestElement;
2457
1432
  }
2458
1433
  }
2459
- const _GeoGraphProjectionHandler = class {
2460
- constructor(graph = null) {
2461
- __publicField(this, "graph", null);
1434
+ const _MapMatching = class {
1435
+ constructor(network = null) {
1436
+ __publicField(this, "network", null);
2462
1437
  __publicField(this, "_maxDistance", Number.MAX_VALUE);
2463
1438
  __publicField(this, "_maxAngleBearing", Math.PI);
2464
- this.graph = graph;
1439
+ this.network = network;
2465
1440
  }
2466
1441
  set maxAngleBearing(maxAngleBearing) {
2467
1442
  this._maxAngleBearing = maxAngleBearing;
@@ -2480,14 +1455,14 @@ const _GeoGraphProjectionHandler = class {
2480
1455
  return [false, false, false];
2481
1456
  }
2482
1457
  let checkEdge = Level.intersect(location.level, edge.level);
2483
- let checkNode1 = Level.intersect(location.level, edge.vertex1.coords.level);
2484
- let checkNode2 = Level.intersect(location.level, edge.vertex2.coords.level);
2485
- checkNode1 = checkNode1 || edge.vertex1.io && location.level === null;
2486
- checkNode2 = checkNode2 || edge.vertex2.io && location.level === null;
1458
+ let checkNode1 = Level.intersect(location.level, edge.node1.coords.level);
1459
+ let checkNode2 = Level.intersect(location.level, edge.node2.coords.level);
1460
+ checkNode1 = checkNode1 || edge.node1.io && location.level === null;
1461
+ checkNode2 = checkNode2 || edge.node2.io && location.level === null;
2487
1462
  if (!useMultiLevelSegments) {
2488
1463
  checkEdge = checkEdge && !Level.isRange(edge.level);
2489
- checkNode1 = checkNode1 && !Level.isRange(edge.vertex1.coords.level);
2490
- checkNode2 = checkNode2 && !Level.isRange(edge.vertex2.coords.level);
1464
+ checkNode1 = checkNode1 && !Level.isRange(edge.node1.coords.level);
1465
+ checkNode2 = checkNode2 && !Level.isRange(edge.node2.coords.level);
2491
1466
  }
2492
1467
  if (useBearing) {
2493
1468
  if (checkEdge) {
@@ -2512,8 +1487,11 @@ const _GeoGraphProjectionHandler = class {
2512
1487
  }
2513
1488
  }
2514
1489
  getProjection(location, useDistance = false, useBearing = false, useMultiLevelSegments = true, acceptEdgeFn = () => true) {
2515
- if (this.graph === null) {
2516
- throw new Error("Graph has not been set yet");
1490
+ if (this.network === null) {
1491
+ throw new Error("Network has not been set yet");
1492
+ }
1493
+ if (!(location instanceof Coordinates)) {
1494
+ throw new TypeError("location is not an instance of Coordinates");
2517
1495
  }
2518
1496
  if (useBearing && (!("bearing" in location && location.bearing !== null) || !this._maxAngleBearing)) {
2519
1497
  return null;
@@ -2524,7 +1502,7 @@ const _GeoGraphProjectionHandler = class {
2524
1502
  const isProjectionBetter = (distanceOfNewProjection) => {
2525
1503
  return distanceOfNewProjection < distanceFromNearestElement && (!useDistance || distanceOfNewProjection <= this._maxDistance);
2526
1504
  };
2527
- for (const edge of this.graph.edges) {
1505
+ for (const edge of this.network.edges) {
2528
1506
  const [checkEdge, checkNode1, checkNode2] = this._shouldProjectOnEdgeAndNodes(
2529
1507
  edge,
2530
1508
  location,
@@ -2533,38 +1511,38 @@ const _GeoGraphProjectionHandler = class {
2533
1511
  acceptEdgeFn
2534
1512
  );
2535
1513
  if (checkNode1) {
2536
- const distNode1 = location.distanceTo(edge.vertex1.coords);
1514
+ const distNode1 = location.distanceTo(edge.node1.coords);
2537
1515
  if (isProjectionBetter(distNode1) || distNode1 <= EPS_MM) {
2538
1516
  distanceFromNearestElement = distNode1;
2539
- nearestElement = edge.vertex1;
2540
- _GeoGraphProjectionHandler._assignLatLngLevel(edge.vertex1.coords, projection);
2541
- _GeoGraphProjectionHandler._handleLevelsWithIONodes(projection, location, edge.vertex1);
1517
+ nearestElement = edge.node1;
1518
+ _MapMatching._assignLatLngLevel(edge.node1.coords, projection);
1519
+ _MapMatching._handleLevelsWithIONodes(projection, location, edge.node1);
2542
1520
  if (distNode1 <= EPS_MM) {
2543
1521
  break;
2544
1522
  }
2545
1523
  }
2546
1524
  }
2547
1525
  if (checkNode2) {
2548
- const distNode2 = location.distanceTo(edge.vertex2.coords);
1526
+ const distNode2 = location.distanceTo(edge.node2.coords);
2549
1527
  if (isProjectionBetter(distNode2) || distNode2 <= EPS_MM) {
2550
1528
  distanceFromNearestElement = distNode2;
2551
- nearestElement = edge.vertex2;
2552
- _GeoGraphProjectionHandler._assignLatLngLevel(edge.vertex2.coords, projection);
2553
- _GeoGraphProjectionHandler._handleLevelsWithIONodes(projection, location, edge.vertex2);
1529
+ nearestElement = edge.node2;
1530
+ _MapMatching._assignLatLngLevel(edge.node2.coords, projection);
1531
+ _MapMatching._handleLevelsWithIONodes(projection, location, edge.node2);
2554
1532
  if (distNode2 <= EPS_MM) {
2555
1533
  break;
2556
1534
  }
2557
1535
  }
2558
1536
  }
2559
1537
  if (checkEdge) {
2560
- const segmentProjection = location.getSegmentProjection(edge.vertex1.coords, edge.vertex2.coords);
1538
+ const segmentProjection = location.getSegmentProjection(edge.node1.coords, edge.node2.coords);
2561
1539
  if (segmentProjection) {
2562
1540
  const distEdge = location.distanceTo(segmentProjection);
2563
1541
  if (isProjectionBetter(distEdge)) {
2564
1542
  distanceFromNearestElement = distEdge;
2565
1543
  nearestElement = edge;
2566
- _GeoGraphProjectionHandler._assignLatLngLevel(segmentProjection, projection);
2567
- _GeoGraphProjectionHandler._updateProjectionLevelFromEdge(edge, projection);
1544
+ _MapMatching._assignLatLngLevel(segmentProjection, projection);
1545
+ _MapMatching._updateProjectionLevelFromEdge(edge, projection);
2568
1546
  }
2569
1547
  }
2570
1548
  }
@@ -2575,7 +1553,7 @@ const _GeoGraphProjectionHandler = class {
2575
1553
  if (projection instanceof UserPosition && projection.accuracy !== null) {
2576
1554
  projection.accuracy += distanceFromNearestElement;
2577
1555
  }
2578
- return new GeoGraphProjection(
1556
+ return new GraphProjection(
2579
1557
  location,
2580
1558
  distanceFromNearestElement,
2581
1559
  projection,
@@ -2583,59 +1561,74 @@ const _GeoGraphProjectionHandler = class {
2583
1561
  );
2584
1562
  }
2585
1563
  };
2586
- let GeoGraphProjectionHandler = _GeoGraphProjectionHandler;
2587
- __publicField(GeoGraphProjectionHandler, "_updateProjectionLevelFromEdge", (_edge, _projection) => {
1564
+ let MapMatching = _MapMatching;
1565
+ __publicField(MapMatching, "_updateProjectionLevelFromEdge", (_edge, _projection) => {
2588
1566
  _projection.level = Level.clone(_edge.level);
2589
1567
  });
2590
- class GeoGraphItinerary extends GeoGraph {
2591
- constructor(start, end, vertices, edges, edgesWeights) {
2592
- super(vertices, edges);
1568
+ class GraphItinerary {
1569
+ constructor(start, end, nodes, edges, edgesWeights) {
1570
+ __publicField(this, "start");
1571
+ __publicField(this, "end");
1572
+ __publicField(this, "nodes");
1573
+ __publicField(this, "edges");
1574
+ __publicField(this, "edgesWeights");
2593
1575
  this.start = start;
2594
1576
  this.end = end;
1577
+ this.nodes = nodes;
1578
+ this.edges = edges;
2595
1579
  this.edgesWeights = edgesWeights;
2596
1580
  }
2597
- static fromGraphVertices(start, end, networkVertices, edgesWeights) {
2598
- const vertices = networkVertices.map((vertex) => {
2599
- return new GeoGraphVertex(
2600
- vertex.coords.clone(),
2601
- { name: vertex.name, id: vertex.id, data: vertex.data, io: vertex.io }
2602
- );
1581
+ static fromNetworkNodes(start, end, networkNodes, edgesWeights) {
1582
+ const nodes = networkNodes.map((node) => {
1583
+ const newNode = node.clone();
1584
+ newNode.edges = [];
1585
+ if (newNode.io) {
1586
+ newNode.coords = newNode.coords.clone();
1587
+ newNode.coords.level = null;
1588
+ }
1589
+ return newNode;
2603
1590
  });
2604
1591
  const edges = [];
2605
- networkVertices.forEach((vertex, idx, arr) => {
1592
+ networkNodes.forEach((node, idx, arr) => {
2606
1593
  if (idx === 0) {
2607
1594
  return;
2608
1595
  }
2609
- const prevVertex = arr[idx - 1];
2610
- const edge = GeoGraphEdge.getEdgeByVertices(prevVertex.edges, prevVertex, vertex);
1596
+ const prevNode = arr[idx - 1];
1597
+ const edge = getEdgeByNodes(prevNode.edges, prevNode, node);
2611
1598
  if (!edge) {
2612
1599
  Logger__default.default.error("Cannot retrieve edge to create itinerary");
2613
1600
  return;
2614
1601
  }
2615
- edges.push(new GeoGraphEdge(
2616
- vertices[idx - 1],
2617
- vertices[idx],
2618
- { name: edge.name, id: edge.id, data: edge.data, level: edge.level, isOneway: edge.isOneway }
2619
- ));
1602
+ const newEdge = new GraphEdge(
1603
+ nodes[idx - 1],
1604
+ nodes[idx],
1605
+ edge.level,
1606
+ edge.builtFrom
1607
+ );
1608
+ newEdge.isOneway = edge.isOneway;
1609
+ edges.push(newEdge);
2620
1610
  });
2621
- return new GeoGraphItinerary(start, end, vertices, edges, edgesWeights);
1611
+ return new GraphItinerary(start, end, nodes, edges, edgesWeights);
2622
1612
  }
2623
1613
  }
2624
1614
  class NoRouteFoundError extends Error {
2625
- constructor(start, end, details = null) {
1615
+ constructor(start, end, details) {
2626
1616
  super();
1617
+ __publicField(this, "details");
1618
+ __publicField(this, "end");
1619
+ __publicField(this, "start");
2627
1620
  this.start = start;
2628
1621
  this.end = end;
2629
1622
  this.details = details;
2630
1623
  }
2631
1624
  get startStr() {
2632
- if (this.start instanceof GeoGraphVertex) {
1625
+ if (this.start instanceof GraphNode) {
2633
1626
  return `GraphNode ${this.start.coords.toString()}`;
2634
1627
  }
2635
1628
  return this.start.toString();
2636
1629
  }
2637
1630
  get endStr() {
2638
- if (this.end instanceof GeoGraphVertex) {
1631
+ if (this.end instanceof GraphNode) {
2639
1632
  return `GraphNode ${this.end.coords.toString()}`;
2640
1633
  }
2641
1634
  return this.end.toString();
@@ -2648,142 +1641,159 @@ class NoRouteFoundError extends Error {
2648
1641
  return message;
2649
1642
  }
2650
1643
  }
2651
- const DEFAULT_OPTIONS = {
2652
- projectionMaxDistance: 50,
2653
- weightEdgeFn: (edge) => edge.length,
2654
- acceptEdgeFn: () => true
2655
- };
2656
- class GeoGraphRouter {
2657
- constructor(graph) {
1644
+ class GraphRouterOptions {
1645
+ constructor() {
1646
+ __publicField(this, "projectionMaxDistance", 50);
1647
+ __publicField(this, "weightEdgeFn", (edge) => edge.length);
1648
+ __publicField(this, "acceptEdgeFn", () => true);
1649
+ }
1650
+ }
1651
+ class GraphRouter {
1652
+ constructor(network) {
2658
1653
  __publicField(this, "_mapMatching");
2659
- __publicField(this, "_graph");
1654
+ __publicField(this, "_network");
2660
1655
  __publicField(this, "disabledEdges", /* @__PURE__ */ new Set());
2661
- this._graph = graph;
2662
- this._mapMatching = new GeoGraphProjectionHandler(graph);
1656
+ this._network = network;
1657
+ this._mapMatching = new MapMatching(network);
2663
1658
  }
2664
- getShortestPath(start, end, options = DEFAULT_OPTIONS) {
1659
+ getShortestPath(start, end, options = new GraphRouterOptions()) {
1660
+ if (!(start instanceof GraphNode) && !(start instanceof Coordinates)) {
1661
+ throw new Error("Unknown start type");
1662
+ }
1663
+ if (!(end instanceof GraphNode) && !(end instanceof Coordinates)) {
1664
+ throw new Error("Unknown end type");
1665
+ }
2665
1666
  const { acceptEdgeFn, weightEdgeFn, projectionMaxDistance } = options;
2666
1667
  this._mapMatching.maxDistance = projectionMaxDistance;
2667
- const createdVertices = [];
2668
- const retrieveOrCreateNearestVertex = (point) => {
2669
- if (point instanceof GeoGraphVertex) {
1668
+ const createdNodes = [];
1669
+ const retrieveOrCreateNearestNode = (point) => {
1670
+ if (point instanceof GraphNode) {
2670
1671
  return point;
2671
1672
  }
2672
- const closeVertex = this._graph.getVertexByCoords(point);
2673
- if (closeVertex) {
2674
- return closeVertex;
1673
+ const closeNode = this._network.getNodeByCoords(point);
1674
+ if (closeNode) {
1675
+ return closeNode;
2675
1676
  }
2676
1677
  const proj = this._mapMatching.getProjection(point, true, false, false, acceptEdgeFn);
2677
1678
  if (!proj) {
2678
- let message = `Point ${point.toString()} is too far from the graph > ${this._mapMatching.maxDistance.toFixed(0)} meters.`;
1679
+ let message = `Point ${point.toString()} is too far from the network > ${this._mapMatching.maxDistance.toFixed(0)} meters.`;
2679
1680
  if (point.level !== null) {
2680
- message += ` If it is a multi-level map, please verify if you have a graph at level ${Level.toString(point.level)}.`;
1681
+ message += ` If it is a multi-level map, please verify if you have a network at level ${Level.toString(point.level)}.`;
2681
1682
  }
2682
1683
  throw new NoRouteFoundError(start, end, message);
2683
1684
  }
2684
- if (proj.nearestElement instanceof GeoGraphVertex) {
1685
+ if (proj.nearestElement instanceof GraphNode) {
2685
1686
  return proj.nearestElement;
2686
1687
  }
2687
- const vertexCreated = this.createVertexInsideEdge(
1688
+ const nodeCreated = this.createNodeInsideEdge(
2688
1689
  proj.nearestElement,
2689
1690
  proj.coords
2690
1691
  );
2691
- createdVertices.push(vertexCreated);
2692
- return vertexCreated;
1692
+ createdNodes.push(nodeCreated);
1693
+ return nodeCreated;
2693
1694
  };
2694
- const removeCreatedVertices = () => {
2695
- while (createdVertices.length) {
2696
- this.removeVertexFromPreviouslyCreatedEdge(createdVertices.pop());
1695
+ const removeCreatedNodes = () => {
1696
+ while (createdNodes.length) {
1697
+ this.removeNodeFromPreviouslyCreatedEdge(createdNodes.pop());
2697
1698
  }
2698
1699
  };
2699
- const startVertex = retrieveOrCreateNearestVertex(start);
2700
- const endVertex = retrieveOrCreateNearestVertex(end);
2701
- const startCoords = start instanceof GeoGraphVertex ? start.coords : start;
2702
- const endCoords = end instanceof GeoGraphVertex ? end.coords : end;
1700
+ const startNode = retrieveOrCreateNearestNode(start);
1701
+ const endNode = retrieveOrCreateNearestNode(end);
1702
+ const startCoords = start instanceof GraphNode ? start.coords : start;
1703
+ const endCoords = end instanceof GraphNode ? end.coords : end;
2703
1704
  let graphItinerary;
2704
- if (startVertex === endVertex) {
2705
- graphItinerary = GeoGraphItinerary.fromGraphVertices(
1705
+ if (startNode === endNode) {
1706
+ graphItinerary = GraphItinerary.fromNetworkNodes(
2706
1707
  startCoords,
2707
1708
  endCoords,
2708
- [startVertex],
1709
+ [startNode],
2709
1710
  []
2710
1711
  );
2711
1712
  } else {
2712
- graphItinerary = this.getShortestPathBetweenGeoGraphVertices(
2713
- startVertex,
2714
- endVertex,
2715
- weightEdgeFn,
2716
- acceptEdgeFn
1713
+ graphItinerary = this.getShortestPathBetweenGraphNodes(
1714
+ startNode,
1715
+ endNode,
1716
+ acceptEdgeFn,
1717
+ weightEdgeFn
2717
1718
  );
2718
1719
  }
2719
1720
  graphItinerary.start = startCoords;
2720
1721
  graphItinerary.end = endCoords;
2721
- removeCreatedVertices();
2722
- if (!graphItinerary.vertices.length) {
1722
+ removeCreatedNodes();
1723
+ if (!graphItinerary.nodes.length) {
2723
1724
  throw new NoRouteFoundError(start, end);
2724
1725
  }
2725
1726
  return graphItinerary;
2726
1727
  }
2727
- createVertexInsideEdge(edge, point) {
2728
- const a = edge.vertex1;
2729
- const b = edge.vertex2;
2730
- const m = new GeoGraphVertex(point, { name: `proj on ${edge.name || null} (tmp)` });
2731
- const newEdgesParams = { name: `splitted ${edge.name || null} (tmp)`, data: edge.data, isOneway: edge.isOneway, level: edge.level };
2732
- const u = new GeoGraphEdge(a, m, newEdgesParams);
2733
- const v = new GeoGraphEdge(m, b, newEdgesParams);
1728
+ createNodeInsideEdge(edge, point) {
1729
+ const a = edge.node1;
1730
+ const b = edge.node2;
1731
+ const m = new GraphNode(point, null);
1732
+ m.coords.level = edge.level;
1733
+ const u = edge.clone();
1734
+ u.node1 = a;
1735
+ u.node2 = m;
1736
+ const v = edge.clone();
1737
+ v.node1 = m;
1738
+ v.node2 = b;
2734
1739
  a.edges = a.edges.filter((_edge) => _edge !== edge);
2735
1740
  b.edges = b.edges.filter((_edge) => _edge !== edge);
2736
- this._graph.vertices.push(m);
2737
- this._graph.edges.push(u, v);
2738
- this._graph.edges = this._graph.edges.filter(
1741
+ this._network.nodes.push(m);
1742
+ this._network.edges.push(u, v);
1743
+ this._network.edges = this._network.edges.filter(
2739
1744
  (_edge) => _edge !== edge
2740
1745
  );
2741
1746
  return m;
2742
1747
  }
2743
- removeVertexFromPreviouslyCreatedEdge(_vertex) {
2744
- const u = _vertex.edges[0];
2745
- const v = _vertex.edges[1];
2746
- u.vertex1.edges = u.vertex1.edges.filter((edge) => edge !== u);
2747
- v.vertex1.edges = v.vertex1.edges.filter((edge) => edge !== v);
2748
- const oldEdgeName = u.name.substring("splitted ".length, u.name.length - " (tmp)".length);
2749
- const oldEdgeParams = { name: oldEdgeName, data: u.data, isOneway: u.isOneway, level: u.level };
2750
- const oldEdge = new GeoGraphEdge(u.vertex1, v.vertex2, oldEdgeParams);
2751
- this._graph.edges.push(oldEdge);
2752
- this._graph.vertices = this._graph.vertices.filter((vertex) => vertex !== _vertex);
2753
- this._graph.edges = this._graph.edges.filter(
1748
+ removeNodeFromPreviouslyCreatedEdge(_node) {
1749
+ const u = _node.edges[0];
1750
+ const v = _node.edges[1];
1751
+ u.node1.edges = u.node1.edges.filter((edge) => edge !== u);
1752
+ v.node1.edges = v.node1.edges.filter((edge) => edge !== v);
1753
+ const oldEdge = u.clone();
1754
+ oldEdge.node1 = u.node1;
1755
+ oldEdge.node2 = v.node2;
1756
+ this._network.edges.push(oldEdge);
1757
+ this._network.nodes = this._network.nodes.filter((node) => node !== _node);
1758
+ this._network.edges = this._network.edges.filter(
2754
1759
  (edge) => edge !== u && edge !== v
2755
1760
  );
2756
1761
  }
2757
- getShortestPathBetweenGeoGraphVertices(start, end, weightFn, acceptEdgeFn) {
2758
- const distanceMap = {}, checking = {}, vertexList = {}, vertices = {}, parentVertices = {}, path = [];
2759
- this._graph.vertices.forEach((vertex) => {
2760
- vertices[vertex.id] = vertex;
2761
- distanceMap[vertex.id] = Infinity;
2762
- checking[vertex.id] = null;
2763
- vertexList[vertex.id] = true;
1762
+ getShortestPathBetweenGraphNodes(start, end, acceptEdgeFn, weightFn) {
1763
+ const distanceMap = {}, checking = {}, vertexList = {}, vertexNodes = {}, parentVertices = {}, path = [];
1764
+ let vertexId = 1;
1765
+ this._network.nodes.forEach((vertex) => {
1766
+ vertex.uniqueRouterId = vertexId;
1767
+ vertexNodes[vertexId] = vertex;
1768
+ distanceMap[vertexId] = Infinity;
1769
+ checking[vertexId] = null;
1770
+ vertexList[vertexId] = true;
1771
+ vertexId++;
2764
1772
  });
2765
- distanceMap[start.id] = 0;
1773
+ const startVertex = Object.values(vertexNodes).find((vertex) => start.equals(vertex));
1774
+ const endVertex = Object.values(vertexNodes).find((vertex) => end.equals(vertex));
1775
+ distanceMap[startVertex.uniqueRouterId] = 0;
2766
1776
  while (Object.keys(vertexList).length > 0) {
2767
1777
  const keys = Object.keys(vertexList).map(Number);
2768
1778
  const current = Number(
2769
- keys.reduce((_checking, vertexId) => {
2770
- return distanceMap[_checking] > distanceMap[vertexId] ? vertexId : _checking;
1779
+ keys.reduce((_checking, vertexId2) => {
1780
+ return distanceMap[_checking] > distanceMap[vertexId2] ? vertexId2 : _checking;
2771
1781
  }, keys[0])
2772
1782
  );
2773
- this._graph.edges.filter((edge) => {
2774
- if (acceptEdgeFn && !acceptEdgeFn(edge) || this.disabledEdges.has(edge)) {
1783
+ this._network.edges.filter((edge) => {
1784
+ if (!acceptEdgeFn(edge) || this.disabledEdges.has(edge)) {
2775
1785
  return false;
2776
1786
  }
2777
- const from = edge.vertex1.id, to = edge.vertex2.id;
1787
+ const from = edge.node1.uniqueRouterId, to = edge.node2.uniqueRouterId;
2778
1788
  return from === current || to === current;
2779
1789
  }).forEach((edge) => {
2780
1790
  let to, from, reversed = false;
2781
- if (edge.vertex1.id === current) {
2782
- to = edge.vertex2.id;
2783
- from = edge.vertex1.id;
1791
+ if (edge.node1.uniqueRouterId === current) {
1792
+ to = edge.node2.uniqueRouterId;
1793
+ from = edge.node1.uniqueRouterId;
2784
1794
  } else {
2785
- to = edge.vertex1.id;
2786
- from = edge.vertex2.id;
1795
+ to = edge.node1.uniqueRouterId;
1796
+ from = edge.node2.uniqueRouterId;
2787
1797
  reversed = true;
2788
1798
  }
2789
1799
  if (edge.isOneway && reversed) {
@@ -2799,34 +1809,38 @@ class GeoGraphRouter {
2799
1809
  delete vertexList[current];
2800
1810
  }
2801
1811
  const edgesWeights = [];
2802
- let endId = end.id;
2803
- while (typeof parentVertices[endId] !== "undefined") {
2804
- path.unshift(vertices[endId]);
1812
+ let endId = endVertex.uniqueRouterId;
1813
+ while (parentVertices[endId]) {
1814
+ path.unshift(vertexNodes[endId]);
2805
1815
  edgesWeights.unshift(distanceMap[endId] - distanceMap[parentVertices[endId]]);
2806
1816
  endId = parentVertices[endId];
2807
1817
  }
2808
1818
  if (path.length !== 0) {
2809
1819
  path.unshift(start);
2810
1820
  }
2811
- return GeoGraphItinerary.fromGraphVertices(start.coords, end.coords, path, edgesWeights);
1821
+ this._network.nodes.forEach((vertex) => {
1822
+ delete vertex.uniqueRouterId;
1823
+ });
1824
+ return GraphItinerary.fromNetworkNodes(start.coords, end.coords, path, edgesWeights);
2812
1825
  }
2813
1826
  }
2814
- __publicField(GeoGraphRouter, "DEFAULT_OPTIONS", DEFAULT_OPTIONS);
2815
1827
  exports.AbsoluteHeading = AbsoluteHeading;
2816
1828
  exports.Attitude = Attitude;
2817
1829
  exports.BoundingBox = BoundingBox;
2818
1830
  exports.Constants = Constants;
2819
1831
  exports.Coordinates = Coordinates;
2820
- exports.GeoGraph = GeoGraph;
2821
- exports.GeoGraphEdge = GeoGraphEdge;
2822
- exports.GeoGraphItinerary = GeoGraphItinerary;
2823
- exports.GeoGraphProjection = GeoGraphProjection;
2824
- exports.GeoGraphProjectionHandler = GeoGraphProjectionHandler;
2825
- exports.GeoGraphRouter = GeoGraphRouter;
2826
- exports.GeoGraphVertex = GeoGraphVertex;
2827
1832
  exports.GeoRef = GeoRef;
2828
1833
  exports.GeoRelativePosition = GeoRelativePosition;
1834
+ exports.GraphEdge = GraphEdge;
1835
+ exports.GraphItinerary = GraphItinerary;
1836
+ exports.GraphNode = GraphNode;
1837
+ exports.GraphProjection = GraphProjection;
1838
+ exports.GraphRouter = GraphRouter;
1839
+ exports.GraphRouterOptions = GraphRouterOptions;
1840
+ exports.GraphUtils = GraphUtils;
2829
1841
  exports.Level = Level;
1842
+ exports.MapMatching = MapMatching;
1843
+ exports.Network = Network;
2830
1844
  exports.NoRouteFoundError = NoRouteFoundError;
2831
1845
  exports.RelativePosition = RelativePosition;
2832
1846
  exports.UserPosition = UserPosition;