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

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 +410 -1401
  2. package/dist/index.js.map +1 -1
  3. package/dist/index.mjs +410 -1401
  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 +200 -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 +145 -0
  20. package/src/graph/Network.ts +175 -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 +72 -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,154 @@ 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) }
2418
- );
1397
+ const createEdgeFromNodes = (node1, node2) => new GraphEdge(node1, node2, Level.union(node1.coords.level, node2.coords.level), null);
2419
1398
  for (const segment of segments) {
2420
- let previousVertex = null;
1399
+ let previousNode = null;
2421
1400
  for (const coords of segment) {
2422
- const currentVertex = getOrCreateVertex(coords);
2423
- if (previousVertex) {
2424
- const edge = createEdgeFromVertices(currentVertex, previousVertex);
2425
- geograph.edges.push(edge);
1401
+ const currentNode = getOrCreateNode(coords);
1402
+ if (previousNode) {
1403
+ const edge = createEdgeFromNodes(currentNode, previousNode);
1404
+ network.edges.push(edge);
2426
1405
  }
2427
- previousVertex = currentVertex;
1406
+ previousNode = currentNode;
2428
1407
  }
2429
1408
  }
2430
- return geograph;
1409
+ return network;
2431
1410
  }
2432
1411
  getEdgesAtLevel(targetLevel, useMultiLevelEdges = true) {
2433
1412
  return this.edges.filter(
2434
1413
  ({ level }) => useMultiLevelEdges ? Level.intersect(targetLevel, level) : Level.contains(targetLevel, level)
2435
1414
  );
2436
1415
  }
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
1416
  }
2447
- class GeoGraphProjection {
1417
+ class GraphProjection {
2448
1418
  constructor(origin, distanceFromNearestElement, coords, nearestElement) {
2449
1419
  __publicField(this, "origin");
2450
1420
  __publicField(this, "distanceFromNearestElement");
@@ -2456,12 +1426,12 @@ class GeoGraphProjection {
2456
1426
  this.nearestElement = nearestElement;
2457
1427
  }
2458
1428
  }
2459
- const _GeoGraphProjectionHandler = class {
2460
- constructor(graph = null) {
2461
- __publicField(this, "graph", null);
1429
+ const _MapMatching = class {
1430
+ constructor(network = null) {
1431
+ __publicField(this, "network", null);
2462
1432
  __publicField(this, "_maxDistance", Number.MAX_VALUE);
2463
1433
  __publicField(this, "_maxAngleBearing", Math.PI);
2464
- this.graph = graph;
1434
+ this.network = network;
2465
1435
  }
2466
1436
  set maxAngleBearing(maxAngleBearing) {
2467
1437
  this._maxAngleBearing = maxAngleBearing;
@@ -2480,14 +1450,14 @@ const _GeoGraphProjectionHandler = class {
2480
1450
  return [false, false, false];
2481
1451
  }
2482
1452
  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;
1453
+ let checkNode1 = Level.intersect(location.level, edge.node1.coords.level);
1454
+ let checkNode2 = Level.intersect(location.level, edge.node2.coords.level);
1455
+ checkNode1 = checkNode1 || edge.node1.io && location.level === null;
1456
+ checkNode2 = checkNode2 || edge.node2.io && location.level === null;
2487
1457
  if (!useMultiLevelSegments) {
2488
1458
  checkEdge = checkEdge && !Level.isRange(edge.level);
2489
- checkNode1 = checkNode1 && !Level.isRange(edge.vertex1.coords.level);
2490
- checkNode2 = checkNode2 && !Level.isRange(edge.vertex2.coords.level);
1459
+ checkNode1 = checkNode1 && !Level.isRange(edge.node1.coords.level);
1460
+ checkNode2 = checkNode2 && !Level.isRange(edge.node2.coords.level);
2491
1461
  }
2492
1462
  if (useBearing) {
2493
1463
  if (checkEdge) {
@@ -2512,8 +1482,11 @@ const _GeoGraphProjectionHandler = class {
2512
1482
  }
2513
1483
  }
2514
1484
  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");
1485
+ if (this.network === null) {
1486
+ throw new Error("Network has not been set yet");
1487
+ }
1488
+ if (!(location instanceof Coordinates)) {
1489
+ throw new TypeError("location is not an instance of Coordinates");
2517
1490
  }
2518
1491
  if (useBearing && (!("bearing" in location && location.bearing !== null) || !this._maxAngleBearing)) {
2519
1492
  return null;
@@ -2524,7 +1497,7 @@ const _GeoGraphProjectionHandler = class {
2524
1497
  const isProjectionBetter = (distanceOfNewProjection) => {
2525
1498
  return distanceOfNewProjection < distanceFromNearestElement && (!useDistance || distanceOfNewProjection <= this._maxDistance);
2526
1499
  };
2527
- for (const edge of this.graph.edges) {
1500
+ for (const edge of this.network.edges) {
2528
1501
  const [checkEdge, checkNode1, checkNode2] = this._shouldProjectOnEdgeAndNodes(
2529
1502
  edge,
2530
1503
  location,
@@ -2533,38 +1506,38 @@ const _GeoGraphProjectionHandler = class {
2533
1506
  acceptEdgeFn
2534
1507
  );
2535
1508
  if (checkNode1) {
2536
- const distNode1 = location.distanceTo(edge.vertex1.coords);
1509
+ const distNode1 = location.distanceTo(edge.node1.coords);
2537
1510
  if (isProjectionBetter(distNode1) || distNode1 <= EPS_MM) {
2538
1511
  distanceFromNearestElement = distNode1;
2539
- nearestElement = edge.vertex1;
2540
- _GeoGraphProjectionHandler._assignLatLngLevel(edge.vertex1.coords, projection);
2541
- _GeoGraphProjectionHandler._handleLevelsWithIONodes(projection, location, edge.vertex1);
1512
+ nearestElement = edge.node1;
1513
+ _MapMatching._assignLatLngLevel(edge.node1.coords, projection);
1514
+ _MapMatching._handleLevelsWithIONodes(projection, location, edge.node1);
2542
1515
  if (distNode1 <= EPS_MM) {
2543
1516
  break;
2544
1517
  }
2545
1518
  }
2546
1519
  }
2547
1520
  if (checkNode2) {
2548
- const distNode2 = location.distanceTo(edge.vertex2.coords);
1521
+ const distNode2 = location.distanceTo(edge.node2.coords);
2549
1522
  if (isProjectionBetter(distNode2) || distNode2 <= EPS_MM) {
2550
1523
  distanceFromNearestElement = distNode2;
2551
- nearestElement = edge.vertex2;
2552
- _GeoGraphProjectionHandler._assignLatLngLevel(edge.vertex2.coords, projection);
2553
- _GeoGraphProjectionHandler._handleLevelsWithIONodes(projection, location, edge.vertex2);
1524
+ nearestElement = edge.node2;
1525
+ _MapMatching._assignLatLngLevel(edge.node2.coords, projection);
1526
+ _MapMatching._handleLevelsWithIONodes(projection, location, edge.node2);
2554
1527
  if (distNode2 <= EPS_MM) {
2555
1528
  break;
2556
1529
  }
2557
1530
  }
2558
1531
  }
2559
1532
  if (checkEdge) {
2560
- const segmentProjection = location.getSegmentProjection(edge.vertex1.coords, edge.vertex2.coords);
1533
+ const segmentProjection = location.getSegmentProjection(edge.node1.coords, edge.node2.coords);
2561
1534
  if (segmentProjection) {
2562
1535
  const distEdge = location.distanceTo(segmentProjection);
2563
1536
  if (isProjectionBetter(distEdge)) {
2564
1537
  distanceFromNearestElement = distEdge;
2565
1538
  nearestElement = edge;
2566
- _GeoGraphProjectionHandler._assignLatLngLevel(segmentProjection, projection);
2567
- _GeoGraphProjectionHandler._updateProjectionLevelFromEdge(edge, projection);
1539
+ _MapMatching._assignLatLngLevel(segmentProjection, projection);
1540
+ _MapMatching._updateProjectionLevelFromEdge(edge, projection);
2568
1541
  }
2569
1542
  }
2570
1543
  }
@@ -2575,7 +1548,7 @@ const _GeoGraphProjectionHandler = class {
2575
1548
  if (projection instanceof UserPosition && projection.accuracy !== null) {
2576
1549
  projection.accuracy += distanceFromNearestElement;
2577
1550
  }
2578
- return new GeoGraphProjection(
1551
+ return new GraphProjection(
2579
1552
  location,
2580
1553
  distanceFromNearestElement,
2581
1554
  projection,
@@ -2583,59 +1556,74 @@ const _GeoGraphProjectionHandler = class {
2583
1556
  );
2584
1557
  }
2585
1558
  };
2586
- let GeoGraphProjectionHandler = _GeoGraphProjectionHandler;
2587
- __publicField(GeoGraphProjectionHandler, "_updateProjectionLevelFromEdge", (_edge, _projection) => {
1559
+ let MapMatching = _MapMatching;
1560
+ __publicField(MapMatching, "_updateProjectionLevelFromEdge", (_edge, _projection) => {
2588
1561
  _projection.level = Level.clone(_edge.level);
2589
1562
  });
2590
- class GeoGraphItinerary extends GeoGraph {
2591
- constructor(start, end, vertices, edges, edgesWeights) {
2592
- super(vertices, edges);
1563
+ class GraphItinerary {
1564
+ constructor(start, end, nodes, edges, edgesWeights) {
1565
+ __publicField(this, "start");
1566
+ __publicField(this, "end");
1567
+ __publicField(this, "nodes");
1568
+ __publicField(this, "edges");
1569
+ __publicField(this, "edgesWeights");
2593
1570
  this.start = start;
2594
1571
  this.end = end;
1572
+ this.nodes = nodes;
1573
+ this.edges = edges;
2595
1574
  this.edgesWeights = edgesWeights;
2596
1575
  }
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
- );
1576
+ static fromNetworkNodes(start, end, networkNodes, edgesWeights) {
1577
+ const nodes = networkNodes.map((node) => {
1578
+ const newNode = node.clone();
1579
+ newNode.edges = [];
1580
+ if (newNode.io) {
1581
+ newNode.coords = newNode.coords.clone();
1582
+ newNode.coords.level = null;
1583
+ }
1584
+ return newNode;
2603
1585
  });
2604
1586
  const edges = [];
2605
- networkVertices.forEach((vertex, idx, arr) => {
1587
+ networkNodes.forEach((node, idx, arr) => {
2606
1588
  if (idx === 0) {
2607
1589
  return;
2608
1590
  }
2609
- const prevVertex = arr[idx - 1];
2610
- const edge = GeoGraphEdge.getEdgeByVertices(prevVertex.edges, prevVertex, vertex);
1591
+ const prevNode = arr[idx - 1];
1592
+ const edge = getEdgeByNodes(prevNode.edges, prevNode, node);
2611
1593
  if (!edge) {
2612
1594
  Logger__default.default.error("Cannot retrieve edge to create itinerary");
2613
1595
  return;
2614
1596
  }
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
- ));
1597
+ const newEdge = new GraphEdge(
1598
+ nodes[idx - 1],
1599
+ nodes[idx],
1600
+ edge.level,
1601
+ edge.builtFrom
1602
+ );
1603
+ newEdge.isOneway = edge.isOneway;
1604
+ edges.push(newEdge);
2620
1605
  });
2621
- return new GeoGraphItinerary(start, end, vertices, edges, edgesWeights);
1606
+ return new GraphItinerary(start, end, nodes, edges, edgesWeights);
2622
1607
  }
2623
1608
  }
2624
1609
  class NoRouteFoundError extends Error {
2625
- constructor(start, end, details = null) {
1610
+ constructor(start, end, details) {
2626
1611
  super();
1612
+ __publicField(this, "details");
1613
+ __publicField(this, "end");
1614
+ __publicField(this, "start");
2627
1615
  this.start = start;
2628
1616
  this.end = end;
2629
1617
  this.details = details;
2630
1618
  }
2631
1619
  get startStr() {
2632
- if (this.start instanceof GeoGraphVertex) {
1620
+ if (this.start instanceof GraphNode) {
2633
1621
  return `GraphNode ${this.start.coords.toString()}`;
2634
1622
  }
2635
1623
  return this.start.toString();
2636
1624
  }
2637
1625
  get endStr() {
2638
- if (this.end instanceof GeoGraphVertex) {
1626
+ if (this.end instanceof GraphNode) {
2639
1627
  return `GraphNode ${this.end.coords.toString()}`;
2640
1628
  }
2641
1629
  return this.end.toString();
@@ -2648,142 +1636,159 @@ class NoRouteFoundError extends Error {
2648
1636
  return message;
2649
1637
  }
2650
1638
  }
2651
- const DEFAULT_OPTIONS = {
2652
- projectionMaxDistance: 50,
2653
- weightEdgeFn: (edge) => edge.length,
2654
- acceptEdgeFn: () => true
2655
- };
2656
- class GeoGraphRouter {
2657
- constructor(graph) {
1639
+ class GraphRouterOptions {
1640
+ constructor() {
1641
+ __publicField(this, "projectionMaxDistance", 50);
1642
+ __publicField(this, "weightEdgeFn", (edge) => edge.length);
1643
+ __publicField(this, "acceptEdgeFn", () => true);
1644
+ }
1645
+ }
1646
+ class GraphRouter {
1647
+ constructor(network) {
2658
1648
  __publicField(this, "_mapMatching");
2659
- __publicField(this, "_graph");
1649
+ __publicField(this, "_network");
2660
1650
  __publicField(this, "disabledEdges", /* @__PURE__ */ new Set());
2661
- this._graph = graph;
2662
- this._mapMatching = new GeoGraphProjectionHandler(graph);
1651
+ this._network = network;
1652
+ this._mapMatching = new MapMatching(network);
2663
1653
  }
2664
- getShortestPath(start, end, options = DEFAULT_OPTIONS) {
1654
+ getShortestPath(start, end, options = new GraphRouterOptions()) {
1655
+ if (!(start instanceof GraphNode) && !(start instanceof Coordinates)) {
1656
+ throw new Error("Unknown start type");
1657
+ }
1658
+ if (!(end instanceof GraphNode) && !(end instanceof Coordinates)) {
1659
+ throw new Error("Unknown end type");
1660
+ }
2665
1661
  const { acceptEdgeFn, weightEdgeFn, projectionMaxDistance } = options;
2666
1662
  this._mapMatching.maxDistance = projectionMaxDistance;
2667
- const createdVertices = [];
2668
- const retrieveOrCreateNearestVertex = (point) => {
2669
- if (point instanceof GeoGraphVertex) {
1663
+ const createdNodes = [];
1664
+ const retrieveOrCreateNearestNode = (point) => {
1665
+ if (point instanceof GraphNode) {
2670
1666
  return point;
2671
1667
  }
2672
- const closeVertex = this._graph.getVertexByCoords(point);
2673
- if (closeVertex) {
2674
- return closeVertex;
1668
+ const closeNode = this._network.getNodeByCoords(point);
1669
+ if (closeNode) {
1670
+ return closeNode;
2675
1671
  }
2676
1672
  const proj = this._mapMatching.getProjection(point, true, false, false, acceptEdgeFn);
2677
1673
  if (!proj) {
2678
- let message = `Point ${point.toString()} is too far from the graph > ${this._mapMatching.maxDistance.toFixed(0)} meters.`;
1674
+ let message = `Point ${point.toString()} is too far from the network > ${this._mapMatching.maxDistance.toFixed(0)} meters.`;
2679
1675
  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)}.`;
1676
+ message += ` If it is a multi-level map, please verify if you have a network at level ${Level.toString(point.level)}.`;
2681
1677
  }
2682
1678
  throw new NoRouteFoundError(start, end, message);
2683
1679
  }
2684
- if (proj.nearestElement instanceof GeoGraphVertex) {
1680
+ if (proj.nearestElement instanceof GraphNode) {
2685
1681
  return proj.nearestElement;
2686
1682
  }
2687
- const vertexCreated = this.createVertexInsideEdge(
1683
+ const nodeCreated = this.createNodeInsideEdge(
2688
1684
  proj.nearestElement,
2689
1685
  proj.coords
2690
1686
  );
2691
- createdVertices.push(vertexCreated);
2692
- return vertexCreated;
1687
+ createdNodes.push(nodeCreated);
1688
+ return nodeCreated;
2693
1689
  };
2694
- const removeCreatedVertices = () => {
2695
- while (createdVertices.length) {
2696
- this.removeVertexFromPreviouslyCreatedEdge(createdVertices.pop());
1690
+ const removeCreatedNodes = () => {
1691
+ while (createdNodes.length) {
1692
+ this.removeNodeFromPreviouslyCreatedEdge(createdNodes.pop());
2697
1693
  }
2698
1694
  };
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;
1695
+ const startNode = retrieveOrCreateNearestNode(start);
1696
+ const endNode = retrieveOrCreateNearestNode(end);
1697
+ const startCoords = start instanceof GraphNode ? start.coords : start;
1698
+ const endCoords = end instanceof GraphNode ? end.coords : end;
2703
1699
  let graphItinerary;
2704
- if (startVertex === endVertex) {
2705
- graphItinerary = GeoGraphItinerary.fromGraphVertices(
1700
+ if (startNode === endNode) {
1701
+ graphItinerary = GraphItinerary.fromNetworkNodes(
2706
1702
  startCoords,
2707
1703
  endCoords,
2708
- [startVertex],
1704
+ [startNode],
2709
1705
  []
2710
1706
  );
2711
1707
  } else {
2712
- graphItinerary = this.getShortestPathBetweenGeoGraphVertices(
2713
- startVertex,
2714
- endVertex,
2715
- weightEdgeFn,
2716
- acceptEdgeFn
1708
+ graphItinerary = this.getShortestPathBetweenGraphNodes(
1709
+ startNode,
1710
+ endNode,
1711
+ acceptEdgeFn,
1712
+ weightEdgeFn
2717
1713
  );
2718
1714
  }
2719
1715
  graphItinerary.start = startCoords;
2720
1716
  graphItinerary.end = endCoords;
2721
- removeCreatedVertices();
2722
- if (!graphItinerary.vertices.length) {
1717
+ removeCreatedNodes();
1718
+ if (!graphItinerary.nodes.length) {
2723
1719
  throw new NoRouteFoundError(start, end);
2724
1720
  }
2725
1721
  return graphItinerary;
2726
1722
  }
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);
1723
+ createNodeInsideEdge(edge, point) {
1724
+ const a = edge.node1;
1725
+ const b = edge.node2;
1726
+ const m = new GraphNode(point, edge.builtFrom);
1727
+ m.coords.level = edge.level;
1728
+ const u = edge.clone();
1729
+ u.node1 = a;
1730
+ u.node2 = m;
1731
+ const v = edge.clone();
1732
+ v.node1 = m;
1733
+ v.node2 = b;
2734
1734
  a.edges = a.edges.filter((_edge) => _edge !== edge);
2735
1735
  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(
1736
+ this._network.nodes.push(m);
1737
+ this._network.edges.push(u, v);
1738
+ this._network.edges = this._network.edges.filter(
2739
1739
  (_edge) => _edge !== edge
2740
1740
  );
2741
1741
  return m;
2742
1742
  }
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(
1743
+ removeNodeFromPreviouslyCreatedEdge(_node) {
1744
+ const u = _node.edges[0];
1745
+ const v = _node.edges[1];
1746
+ u.node1.edges = u.node1.edges.filter((edge) => edge !== u);
1747
+ v.node1.edges = v.node1.edges.filter((edge) => edge !== v);
1748
+ const oldEdge = u.clone();
1749
+ oldEdge.node1 = u.node1;
1750
+ oldEdge.node2 = v.node2;
1751
+ this._network.edges.push(oldEdge);
1752
+ this._network.nodes = this._network.nodes.filter((node) => node !== _node);
1753
+ this._network.edges = this._network.edges.filter(
2754
1754
  (edge) => edge !== u && edge !== v
2755
1755
  );
2756
1756
  }
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;
1757
+ getShortestPathBetweenGraphNodes(start, end, acceptEdgeFn, weightFn) {
1758
+ const distanceMap = {}, checking = {}, vertexList = {}, vertexNodes = {}, parentVertices = {}, path = [];
1759
+ let vertexId = 1;
1760
+ this._network.nodes.forEach((vertex) => {
1761
+ vertex.uniqueRouterId = vertexId;
1762
+ vertexNodes[vertexId] = vertex;
1763
+ distanceMap[vertexId] = Infinity;
1764
+ checking[vertexId] = null;
1765
+ vertexList[vertexId] = true;
1766
+ vertexId++;
2764
1767
  });
2765
- distanceMap[start.id] = 0;
1768
+ const startVertex = Object.values(vertexNodes).find((vertex) => start.equals(vertex));
1769
+ const endVertex = Object.values(vertexNodes).find((vertex) => end.equals(vertex));
1770
+ distanceMap[startVertex.uniqueRouterId] = 0;
2766
1771
  while (Object.keys(vertexList).length > 0) {
2767
1772
  const keys = Object.keys(vertexList).map(Number);
2768
1773
  const current = Number(
2769
- keys.reduce((_checking, vertexId) => {
2770
- return distanceMap[_checking] > distanceMap[vertexId] ? vertexId : _checking;
1774
+ keys.reduce((_checking, vertexId2) => {
1775
+ return distanceMap[_checking] > distanceMap[vertexId2] ? vertexId2 : _checking;
2771
1776
  }, keys[0])
2772
1777
  );
2773
- this._graph.edges.filter((edge) => {
2774
- if (acceptEdgeFn && !acceptEdgeFn(edge) || this.disabledEdges.has(edge)) {
1778
+ this._network.edges.filter((edge) => {
1779
+ if (!acceptEdgeFn(edge) || this.disabledEdges.has(edge)) {
2775
1780
  return false;
2776
1781
  }
2777
- const from = edge.vertex1.id, to = edge.vertex2.id;
1782
+ const from = edge.node1.uniqueRouterId, to = edge.node2.uniqueRouterId;
2778
1783
  return from === current || to === current;
2779
1784
  }).forEach((edge) => {
2780
1785
  let to, from, reversed = false;
2781
- if (edge.vertex1.id === current) {
2782
- to = edge.vertex2.id;
2783
- from = edge.vertex1.id;
1786
+ if (edge.node1.uniqueRouterId === current) {
1787
+ to = edge.node2.uniqueRouterId;
1788
+ from = edge.node1.uniqueRouterId;
2784
1789
  } else {
2785
- to = edge.vertex1.id;
2786
- from = edge.vertex2.id;
1790
+ to = edge.node1.uniqueRouterId;
1791
+ from = edge.node2.uniqueRouterId;
2787
1792
  reversed = true;
2788
1793
  }
2789
1794
  if (edge.isOneway && reversed) {
@@ -2799,34 +1804,38 @@ class GeoGraphRouter {
2799
1804
  delete vertexList[current];
2800
1805
  }
2801
1806
  const edgesWeights = [];
2802
- let endId = end.id;
2803
- while (typeof parentVertices[endId] !== "undefined") {
2804
- path.unshift(vertices[endId]);
1807
+ let endId = endVertex.uniqueRouterId;
1808
+ while (parentVertices[endId]) {
1809
+ path.unshift(vertexNodes[endId]);
2805
1810
  edgesWeights.unshift(distanceMap[endId] - distanceMap[parentVertices[endId]]);
2806
1811
  endId = parentVertices[endId];
2807
1812
  }
2808
1813
  if (path.length !== 0) {
2809
1814
  path.unshift(start);
2810
1815
  }
2811
- return GeoGraphItinerary.fromGraphVertices(start.coords, end.coords, path, edgesWeights);
1816
+ this._network.nodes.forEach((vertex) => {
1817
+ delete vertex.uniqueRouterId;
1818
+ });
1819
+ return GraphItinerary.fromNetworkNodes(start.coords, end.coords, path, edgesWeights);
2812
1820
  }
2813
1821
  }
2814
- __publicField(GeoGraphRouter, "DEFAULT_OPTIONS", DEFAULT_OPTIONS);
2815
1822
  exports.AbsoluteHeading = AbsoluteHeading;
2816
1823
  exports.Attitude = Attitude;
2817
1824
  exports.BoundingBox = BoundingBox;
2818
1825
  exports.Constants = Constants;
2819
1826
  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
1827
  exports.GeoRef = GeoRef;
2828
1828
  exports.GeoRelativePosition = GeoRelativePosition;
1829
+ exports.GraphEdge = GraphEdge;
1830
+ exports.GraphItinerary = GraphItinerary;
1831
+ exports.GraphNode = GraphNode;
1832
+ exports.GraphProjection = GraphProjection;
1833
+ exports.GraphRouter = GraphRouter;
1834
+ exports.GraphRouterOptions = GraphRouterOptions;
1835
+ exports.GraphUtils = GraphUtils;
2829
1836
  exports.Level = Level;
1837
+ exports.MapMatching = MapMatching;
1838
+ exports.Network = Network;
2830
1839
  exports.NoRouteFoundError = NoRouteFoundError;
2831
1840
  exports.RelativePosition = RelativePosition;
2832
1841
  exports.UserPosition = UserPosition;