@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.
- package/dist/index.js +410 -1401
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +410 -1401
- package/dist/index.mjs.map +1 -1
- package/index.ts +19 -9
- package/package.json +5 -6
- package/src/Utils.ts +4 -4
- package/src/coordinates/Coordinates.ts +7 -16
- package/src/coordinates/Level.spec.ts +1 -6
- package/src/coordinates/Level.ts +6 -15
- package/src/graph/GraphEdge.spec.ts +74 -0
- package/src/graph/GraphEdge.ts +134 -0
- package/src/graph/GraphNode.spec.ts +200 -0
- package/src/graph/GraphNode.ts +174 -0
- package/src/graph/GraphProjection.ts +23 -0
- package/src/graph/GraphUtils.ts +21 -0
- package/src/graph/{GeoGraphProjectionHandler.spec.ts → MapMatching.spec.ts} +73 -74
- package/src/graph/{GeoGraphProjectionHandler.ts → MapMatching.ts} +44 -39
- package/src/graph/Network.spec.ts +145 -0
- package/src/graph/Network.ts +175 -0
- package/src/router/GraphItinerary.spec.ts +14 -0
- package/src/router/GraphItinerary.ts +80 -0
- package/src/router/GraphRouter.spec.ts +298 -0
- package/src/router/GraphRouter.ts +283 -0
- package/src/router/GraphRouterOptions.ts +14 -0
- package/src/{graph → router}/NoRouteFoundError.ts +14 -9
- package/src/types.ts +3 -3
- package/tests/CommonTest.ts +72 -69
- package/src/graph/GeoGraph.spec.ts +0 -278
- package/src/graph/GeoGraph.ts +0 -170
- package/src/graph/GeoGraphEdge.spec.ts +0 -51
- package/src/graph/GeoGraphEdge.ts +0 -98
- package/src/graph/GeoGraphItinerary.spec.ts +0 -14
- package/src/graph/GeoGraphItinerary.ts +0 -61
- package/src/graph/GeoGraphProjection.ts +0 -24
- package/src/graph/GeoGraphRouter.spec.ts +0 -297
- package/src/graph/GeoGraphRouter.ts +0 -267
- package/src/graph/GeoGraphVertex.spec.ts +0 -54
- 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"
|
|
84
|
-
throw Error(`argument must be a
|
|
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
|
|
91
|
-
const
|
|
92
|
-
const
|
|
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 [
|
|
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:
|
|
496
|
-
lng:
|
|
497
|
-
...this.alt !== null && { alt:
|
|
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 [
|
|
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
|
-
|
|
1117
|
-
|
|
1118
|
-
(
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
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
|
-
|
|
1963
|
-
|
|
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
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
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
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
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
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
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
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
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
|
-
|
|
2147
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2181
|
-
|
|
1196
|
+
_checkIO() {
|
|
1197
|
+
this.io = this.coords.level !== null && this.edges.some((edge) => edge.level === null);
|
|
1198
|
+
return true;
|
|
2182
1199
|
}
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
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
|
|
2205
|
-
constructor(
|
|
2206
|
-
|
|
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
|
-
|
|
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
|
|
2215
|
-
|
|
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
|
|
2219
|
-
return this.
|
|
1236
|
+
get node2() {
|
|
1237
|
+
return this._node2;
|
|
2220
1238
|
}
|
|
2221
|
-
set
|
|
2222
|
-
|
|
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.
|
|
2249
|
-
this._bearing = this.
|
|
1270
|
+
this._length = this.node1.distanceTo(this.node2);
|
|
1271
|
+
this._bearing = this.node1.bearingTo(this.node2);
|
|
2250
1272
|
this._computedSizeAndBearing = true;
|
|
2251
1273
|
}
|
|
2252
|
-
|
|
2253
|
-
|
|
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
|
-
|
|
2298
|
-
|
|
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
|
|
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
|
-
|
|
2309
|
-
const
|
|
2310
|
-
|
|
2311
|
-
|
|
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
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
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
|
-
|
|
2356
|
-
return
|
|
1309
|
+
getNodeByCoords(coords) {
|
|
1310
|
+
return this.nodes.find((node) => node.coords.equals(coords));
|
|
2357
1311
|
}
|
|
2358
|
-
|
|
2359
|
-
return
|
|
1312
|
+
getEdgeByNodes(node1, node2) {
|
|
1313
|
+
return getEdgeByNodes(this.edges, node1, node2);
|
|
2360
1314
|
}
|
|
2361
1315
|
getBoundingBox(extendedMeasure) {
|
|
2362
|
-
if (!this.
|
|
1316
|
+
if (!this.nodes.length) {
|
|
2363
1317
|
return null;
|
|
2364
1318
|
}
|
|
2365
|
-
const boundingBox = BoundingBox.fromCoordinates(this.
|
|
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
|
-
|
|
1355
|
+
nodes: this.nodes.map((node) => node.toJson()),
|
|
2374
1356
|
edges: this.edges.map((edge) => {
|
|
2375
|
-
const
|
|
2376
|
-
const
|
|
1357
|
+
const node1Idx = this.nodes.indexOf(edge.node1);
|
|
1358
|
+
const node2Idx = this.nodes.indexOf(edge.node2);
|
|
2377
1359
|
if (edge.isOneway) {
|
|
2378
|
-
return [
|
|
1360
|
+
return [node1Idx, node2Idx, edge.level, true];
|
|
2379
1361
|
}
|
|
2380
|
-
if (edge.level
|
|
2381
|
-
return [
|
|
1362
|
+
if (edge.level) {
|
|
1363
|
+
return [node1Idx, node2Idx, edge.level];
|
|
2382
1364
|
}
|
|
2383
|
-
return [
|
|
1365
|
+
return [node1Idx, node2Idx];
|
|
2384
1366
|
})
|
|
2385
1367
|
};
|
|
2386
1368
|
}
|
|
2387
1369
|
static fromCompressedJson(json) {
|
|
2388
|
-
const
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
const edge = new
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
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
|
|
1384
|
+
return network;
|
|
2402
1385
|
}
|
|
2403
1386
|
static fromCoordinates(segments) {
|
|
2404
|
-
const
|
|
2405
|
-
const
|
|
2406
|
-
const
|
|
2407
|
-
if (
|
|
2408
|
-
return
|
|
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
|
|
2411
|
-
|
|
2412
|
-
return
|
|
1393
|
+
const newNode = new GraphNode(coords, null);
|
|
1394
|
+
network.nodes.push(newNode);
|
|
1395
|
+
return newNode;
|
|
2413
1396
|
};
|
|
2414
|
-
const
|
|
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
|
|
1399
|
+
let previousNode = null;
|
|
2421
1400
|
for (const coords of segment) {
|
|
2422
|
-
const
|
|
2423
|
-
if (
|
|
2424
|
-
const edge =
|
|
2425
|
-
|
|
1401
|
+
const currentNode = getOrCreateNode(coords);
|
|
1402
|
+
if (previousNode) {
|
|
1403
|
+
const edge = createEdgeFromNodes(currentNode, previousNode);
|
|
1404
|
+
network.edges.push(edge);
|
|
2426
1405
|
}
|
|
2427
|
-
|
|
1406
|
+
previousNode = currentNode;
|
|
2428
1407
|
}
|
|
2429
1408
|
}
|
|
2430
|
-
return
|
|
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
|
|
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
|
|
2460
|
-
constructor(
|
|
2461
|
-
__publicField(this, "
|
|
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.
|
|
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.
|
|
2484
|
-
let checkNode2 = Level.intersect(location.level, edge.
|
|
2485
|
-
checkNode1 = checkNode1 || edge.
|
|
2486
|
-
checkNode2 = checkNode2 || edge.
|
|
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.
|
|
2490
|
-
checkNode2 = checkNode2 && !Level.isRange(edge.
|
|
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.
|
|
2516
|
-
throw new Error("
|
|
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.
|
|
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.
|
|
1509
|
+
const distNode1 = location.distanceTo(edge.node1.coords);
|
|
2537
1510
|
if (isProjectionBetter(distNode1) || distNode1 <= EPS_MM) {
|
|
2538
1511
|
distanceFromNearestElement = distNode1;
|
|
2539
|
-
nearestElement = edge.
|
|
2540
|
-
|
|
2541
|
-
|
|
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.
|
|
1521
|
+
const distNode2 = location.distanceTo(edge.node2.coords);
|
|
2549
1522
|
if (isProjectionBetter(distNode2) || distNode2 <= EPS_MM) {
|
|
2550
1523
|
distanceFromNearestElement = distNode2;
|
|
2551
|
-
nearestElement = edge.
|
|
2552
|
-
|
|
2553
|
-
|
|
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.
|
|
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
|
-
|
|
2567
|
-
|
|
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
|
|
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
|
|
2587
|
-
__publicField(
|
|
1559
|
+
let MapMatching = _MapMatching;
|
|
1560
|
+
__publicField(MapMatching, "_updateProjectionLevelFromEdge", (_edge, _projection) => {
|
|
2588
1561
|
_projection.level = Level.clone(_edge.level);
|
|
2589
1562
|
});
|
|
2590
|
-
class
|
|
2591
|
-
constructor(start, end,
|
|
2592
|
-
|
|
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
|
|
2598
|
-
const
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
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
|
-
|
|
1587
|
+
networkNodes.forEach((node, idx, arr) => {
|
|
2606
1588
|
if (idx === 0) {
|
|
2607
1589
|
return;
|
|
2608
1590
|
}
|
|
2609
|
-
const
|
|
2610
|
-
const edge =
|
|
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
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
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
|
|
1606
|
+
return new GraphItinerary(start, end, nodes, edges, edgesWeights);
|
|
2622
1607
|
}
|
|
2623
1608
|
}
|
|
2624
1609
|
class NoRouteFoundError extends Error {
|
|
2625
|
-
constructor(start, end, details
|
|
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
|
|
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
|
|
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
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
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, "
|
|
1649
|
+
__publicField(this, "_network");
|
|
2660
1650
|
__publicField(this, "disabledEdges", /* @__PURE__ */ new Set());
|
|
2661
|
-
this.
|
|
2662
|
-
this._mapMatching = new
|
|
1651
|
+
this._network = network;
|
|
1652
|
+
this._mapMatching = new MapMatching(network);
|
|
2663
1653
|
}
|
|
2664
|
-
getShortestPath(start, end, 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
|
|
2668
|
-
const
|
|
2669
|
-
if (point instanceof
|
|
1663
|
+
const createdNodes = [];
|
|
1664
|
+
const retrieveOrCreateNearestNode = (point) => {
|
|
1665
|
+
if (point instanceof GraphNode) {
|
|
2670
1666
|
return point;
|
|
2671
1667
|
}
|
|
2672
|
-
const
|
|
2673
|
-
if (
|
|
2674
|
-
return
|
|
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
|
|
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
|
|
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
|
|
1680
|
+
if (proj.nearestElement instanceof GraphNode) {
|
|
2685
1681
|
return proj.nearestElement;
|
|
2686
1682
|
}
|
|
2687
|
-
const
|
|
1683
|
+
const nodeCreated = this.createNodeInsideEdge(
|
|
2688
1684
|
proj.nearestElement,
|
|
2689
1685
|
proj.coords
|
|
2690
1686
|
);
|
|
2691
|
-
|
|
2692
|
-
return
|
|
1687
|
+
createdNodes.push(nodeCreated);
|
|
1688
|
+
return nodeCreated;
|
|
2693
1689
|
};
|
|
2694
|
-
const
|
|
2695
|
-
while (
|
|
2696
|
-
this.
|
|
1690
|
+
const removeCreatedNodes = () => {
|
|
1691
|
+
while (createdNodes.length) {
|
|
1692
|
+
this.removeNodeFromPreviouslyCreatedEdge(createdNodes.pop());
|
|
2697
1693
|
}
|
|
2698
1694
|
};
|
|
2699
|
-
const
|
|
2700
|
-
const
|
|
2701
|
-
const startCoords = start instanceof
|
|
2702
|
-
const endCoords = end instanceof
|
|
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 (
|
|
2705
|
-
graphItinerary =
|
|
1700
|
+
if (startNode === endNode) {
|
|
1701
|
+
graphItinerary = GraphItinerary.fromNetworkNodes(
|
|
2706
1702
|
startCoords,
|
|
2707
1703
|
endCoords,
|
|
2708
|
-
[
|
|
1704
|
+
[startNode],
|
|
2709
1705
|
[]
|
|
2710
1706
|
);
|
|
2711
1707
|
} else {
|
|
2712
|
-
graphItinerary = this.
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
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
|
-
|
|
2722
|
-
if (!graphItinerary.
|
|
1717
|
+
removeCreatedNodes();
|
|
1718
|
+
if (!graphItinerary.nodes.length) {
|
|
2723
1719
|
throw new NoRouteFoundError(start, end);
|
|
2724
1720
|
}
|
|
2725
1721
|
return graphItinerary;
|
|
2726
1722
|
}
|
|
2727
|
-
|
|
2728
|
-
const a = edge.
|
|
2729
|
-
const b = edge.
|
|
2730
|
-
const m = new
|
|
2731
|
-
|
|
2732
|
-
const u =
|
|
2733
|
-
|
|
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.
|
|
2737
|
-
this.
|
|
2738
|
-
this.
|
|
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
|
-
|
|
2744
|
-
const u =
|
|
2745
|
-
const v =
|
|
2746
|
-
u.
|
|
2747
|
-
v.
|
|
2748
|
-
const
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
this.
|
|
2752
|
-
this.
|
|
2753
|
-
this.
|
|
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
|
-
|
|
2758
|
-
const distanceMap = {}, checking = {}, vertexList = {},
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
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
|
-
|
|
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,
|
|
2770
|
-
return distanceMap[_checking] > distanceMap[
|
|
1774
|
+
keys.reduce((_checking, vertexId2) => {
|
|
1775
|
+
return distanceMap[_checking] > distanceMap[vertexId2] ? vertexId2 : _checking;
|
|
2771
1776
|
}, keys[0])
|
|
2772
1777
|
);
|
|
2773
|
-
this.
|
|
2774
|
-
if (
|
|
1778
|
+
this._network.edges.filter((edge) => {
|
|
1779
|
+
if (!acceptEdgeFn(edge) || this.disabledEdges.has(edge)) {
|
|
2775
1780
|
return false;
|
|
2776
1781
|
}
|
|
2777
|
-
const from = edge.
|
|
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.
|
|
2782
|
-
to = edge.
|
|
2783
|
-
from = edge.
|
|
1786
|
+
if (edge.node1.uniqueRouterId === current) {
|
|
1787
|
+
to = edge.node2.uniqueRouterId;
|
|
1788
|
+
from = edge.node1.uniqueRouterId;
|
|
2784
1789
|
} else {
|
|
2785
|
-
to = edge.
|
|
2786
|
-
from = edge.
|
|
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 =
|
|
2803
|
-
while (
|
|
2804
|
-
path.unshift(
|
|
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
|
-
|
|
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;
|