ua-browser 1.3.0 → 1.4.0-beta.0
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/README.en.md +226 -0
- package/README.md +93 -85
- package/dist/index.cjs +306 -60
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +83 -17
- package/dist/index.d.ts +83 -17
- package/dist/index.min.js +2 -2
- package/dist/index.min.js.map +1 -1
- package/dist/index.mjs +304 -61
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/README.zh-CN.md +0 -200
package/dist/index.cjs
CHANGED
|
@@ -4,13 +4,14 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
// package.json
|
|
6
6
|
var package_default = {
|
|
7
|
-
version: "1.
|
|
7
|
+
version: "1.4.0-beta.0"};
|
|
8
8
|
|
|
9
9
|
// src/constants/browsers.ts
|
|
10
10
|
var BROWSER_DEFS = [
|
|
11
11
|
// ── Generic / low-priority base browsers ──────────────────────────────────
|
|
12
12
|
{ name: "Safari", priority: 10, detect: /Safari/, versionPattern: /Version\/([\d.]+)/ },
|
|
13
13
|
{ name: "Chrome", priority: 20, detect: /(Chrome|CriOS)/, versionPattern: [/Chrome\/([\d.]+)/, /CriOS\/([\d.]+)/] },
|
|
14
|
+
{ name: "Arc", priority: 35, detect: /Arc\//, versionPattern: /Arc\/([\d.]+)/ },
|
|
14
15
|
{ name: "IE", priority: 30, detect: /(MSIE|Trident)/, versionPattern: [/MSIE ([\d.]+)/, /rv:([\d.]+)/] },
|
|
15
16
|
{ name: "Edge", priority: 40, detect: /(Edge|Edg\/|EdgA|EdgiOS)/, versionPattern: [/Edge\/([\d.]+)/, /Edg\/([\d.]+)/, /EdgA\/([\d.]+)/, /EdgiOS\/([\d.]+)/] },
|
|
16
17
|
{ name: "Firefox", priority: 50, detect: /(Firefox|FxiOS)/, versionPattern: [/Firefox\/([\d.]+)/, /FxiOS\/([\d.]+)/] },
|
|
@@ -20,7 +21,7 @@ var BROWSER_DEFS = [
|
|
|
20
21
|
{ name: "Vivaldi", priority: 80, detect: /Vivaldi/, versionPattern: /Vivaldi\/([\d.]+)/ },
|
|
21
22
|
{ name: "Yandex", priority: 90, detect: /YaBrowser/, versionPattern: /YaBrowser\/([\d.]+)/ },
|
|
22
23
|
{ name: "Samsung Internet", priority: 92, detect: /SamsungBrowser/, versionPattern: /SamsungBrowser\/([\d.]+)/ },
|
|
23
|
-
{ name: "DuckDuckGo", priority: 94, detect: /DuckDuckGo\//, versionPattern: /DuckDuckGo\/([\d.]+)/ },
|
|
24
|
+
{ name: "DuckDuckGo", priority: 94, detect: /(DuckDuckGo|Ddg)\//, versionPattern: [/DuckDuckGo\/([\d.]+)/, /Ddg\/([\d.]+)/] },
|
|
24
25
|
{ name: "Puffin", priority: 96, detect: /Puffin\//, versionPattern: /Puffin\/([\d.]+)/ },
|
|
25
26
|
{ name: "Coc Coc", priority: 130, detect: /coc_coc_browser/, versionPattern: /coc_coc_browser\/([\d.]+)/ },
|
|
26
27
|
{ name: "Kindle", priority: 140, detect: /(Kindle|Silk\/)/, versionPattern: /Version\/([\d.]+)/ },
|
|
@@ -64,7 +65,7 @@ var BROWSER_DEFS = [
|
|
|
64
65
|
}
|
|
65
66
|
},
|
|
66
67
|
{ name: "UC", priority: 330, detect: /(UCBrowser|UBrowser|UCWEB)/, versionPattern: /UC?Browser\/([\d.]+)/ },
|
|
67
|
-
{ name: "QQBrowser", priority: 340, detect: /QQBrowser/, versionPattern: /QQBrowser\/([\d.]+)/ },
|
|
68
|
+
{ name: "QQBrowser", priority: 340, detect: /(MQQBrowser|QQBrowser)/, versionPattern: [/MQQBrowser\/([\d.]+)/, /QQBrowser\/([\d.]+)/] },
|
|
68
69
|
{ name: "QQ", priority: 345, detect: /QQ\//, versionPattern: /QQ\/([\d.]+)/ },
|
|
69
70
|
{ name: "Baidu", priority: 350, detect: /(Baidu|BIDUBrowser|baidubrowser|baiduboxapp|BaiduHD)/, versionPattern: [/BIDUBrowser[\s/]([\d.]+)/, /baiduboxapp\/([\d.]+)/] },
|
|
70
71
|
{ name: "Sogou", priority: 360, detect: /(MetaSr|Sogou)/, versionPattern: [/SE ([\d.X]+)/, /SogouMobileBrowser\/([\d.]+)/] },
|
|
@@ -212,6 +213,10 @@ var OS_DEFS = [
|
|
|
212
213
|
{ name: "Tizen", detect: /Tizen/, versionPattern: /Tizen ([\d.]+)/ },
|
|
213
214
|
{ name: "iOS", detect: /like Mac OS X/, versionPattern: /OS ([\d_]+) like/ },
|
|
214
215
|
{ name: "MacOS", detect: /Macintosh/, versionPattern: /Mac OS X -?([\d_.]+)/ },
|
|
216
|
+
// visionOS / tvOS must come AFTER iOS: their UAs also contain "like Mac OS X",
|
|
217
|
+
// so they need to override iOS via the last-match-wins iteration.
|
|
218
|
+
{ name: "visionOS", detect: /visionOS/, versionPattern: /visionOS ([\d_]+)/ },
|
|
219
|
+
{ name: "tvOS", detect: /Apple TV/, versionPattern: /OS ([\d_]+) like/ },
|
|
215
220
|
{ name: "Android", detect: /(Android|Adr)/, versionPattern: /(?:Android|Adr) ([\d.]+)/ },
|
|
216
221
|
// HarmonyOS must come after Android: HarmonyOS UAs include "Android", so Android matches
|
|
217
222
|
// first, then HarmonyOS overrides it. versionPattern tries direct extraction first (5.0+
|
|
@@ -289,24 +294,59 @@ var DEVICE_DEFS = [
|
|
|
289
294
|
|
|
290
295
|
// src/detectors/device.ts
|
|
291
296
|
function detectDevice(ua, nav) {
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
return "
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
return
|
|
297
|
+
var _a, _b;
|
|
298
|
+
function uaDetect() {
|
|
299
|
+
if (/PlayStation|Xbox|Nintendo/.test(ua)) return "Console";
|
|
300
|
+
if (/visionOS|Quest/.test(ua)) return "XR";
|
|
301
|
+
if (/(SMART-TV|HbbTV|SmartTV|TV Safari|Android TV|GoogleTV)/.test(ua)) return "TV";
|
|
302
|
+
if (/iPad/.test(ua)) return "Tablet";
|
|
303
|
+
if (/Android/.test(ua) && !/Mobile/.test(ua)) return "Tablet";
|
|
304
|
+
for (const def of DEVICE_DEFS) {
|
|
305
|
+
if (def.detect.test(ua)) return def.name;
|
|
306
|
+
}
|
|
307
|
+
return null;
|
|
303
308
|
}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
309
|
+
function hwDetect() {
|
|
310
|
+
var _a2, _b2, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
|
|
311
|
+
if (!nav) return null;
|
|
312
|
+
if (nav.webglRenderer) {
|
|
313
|
+
if (/^ANGLE\b/.test(nav.webglRenderer)) return "PC";
|
|
314
|
+
if (/Adreno/i.test(nav.webglRenderer) || /Mali[-\s]/i.test(nav.webglRenderer)) {
|
|
315
|
+
return ((_a2 = nav.screenWidth) != null ? _a2 : 0) >= 768 ? "Tablet" : "Mobile";
|
|
316
|
+
}
|
|
317
|
+
if (/Apple GPU/i.test(nav.webglRenderer)) {
|
|
318
|
+
const w = (_b2 = nav.screenWidth) != null ? _b2 : 0;
|
|
319
|
+
if (w <= 1366) return w >= 768 ? "Tablet" : "Mobile";
|
|
320
|
+
return "PC";
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
if (nav.platform === "MacIntel" && ((_c = nav.maxTouchPoints) != null ? _c : 0) > 1) {
|
|
324
|
+
return nav.screenWidth !== void 0 && nav.screenWidth < 768 ? "Mobile" : "Tablet";
|
|
325
|
+
}
|
|
326
|
+
if (nav.webglMaxTextureSize !== void 0 && nav.webglMaxTextureSize <= 8192 && ((_d = nav.maxTouchPoints) != null ? _d : 0) > 1 && ((_e = nav.screenWidth) != null ? _e : 9999) < 1367) {
|
|
327
|
+
return ((_f = nav.screenWidth) != null ? _f : 0) >= 768 ? "Tablet" : "Mobile";
|
|
328
|
+
}
|
|
329
|
+
if (((_g = nav.webglCompressedFormats) == null ? void 0 : _g.pvrtc) && !nav.webglCompressedFormats.s3tc) {
|
|
330
|
+
return ((_h = nav.screenWidth) != null ? _h : 0) >= 768 ? "Tablet" : "Mobile";
|
|
307
331
|
}
|
|
332
|
+
if (nav.safeAreaInsetTop !== void 0 && nav.safeAreaInsetTop > 0) {
|
|
333
|
+
return ((_i = nav.screenWidth) != null ? _i : 0) >= 768 ? "Tablet" : "Mobile";
|
|
334
|
+
}
|
|
335
|
+
if (nav.hasVibration || nav.hasDeviceMotion) {
|
|
336
|
+
return ((_j = nav.screenWidth) != null ? _j : 0) >= 768 ? "Tablet" : "Mobile";
|
|
337
|
+
}
|
|
338
|
+
if (((_k = nav.connection) == null ? void 0 : _k.effectiveType) && ["2g", "3g", "slow-2g"].includes(nav.connection.effectiveType)) {
|
|
339
|
+
return ((_l = nav.screenWidth) != null ? _l : 0) >= 768 ? "Tablet" : "Mobile";
|
|
340
|
+
}
|
|
341
|
+
if (((_m = nav.devicePixelRatio) != null ? _m : 0) > 2 && ((_n = nav.maxTouchPoints) != null ? _n : 0) > 1) {
|
|
342
|
+
return ((_o = nav.screenWidth) != null ? _o : 0) >= 768 ? "Tablet" : "Mobile";
|
|
343
|
+
}
|
|
344
|
+
if (nav.pointerType === "coarse" && nav.hoverCapability === false) {
|
|
345
|
+
return ((_p = nav.screenWidth) != null ? _p : 0) >= 768 ? "Tablet" : "Mobile";
|
|
346
|
+
}
|
|
347
|
+
return null;
|
|
308
348
|
}
|
|
309
|
-
return "PC";
|
|
349
|
+
return (_b = (_a = hwDetect()) != null ? _a : uaDetect()) != null ? _b : "PC";
|
|
310
350
|
}
|
|
311
351
|
|
|
312
352
|
// src/constants/bots.ts
|
|
@@ -322,28 +362,49 @@ var BOT_DEFS = [
|
|
|
322
362
|
{ name: "Sogou", detect: /(Sogou|sogou).*[Ss]pider/ },
|
|
323
363
|
{ name: "360Spider", detect: /360Spider/ },
|
|
324
364
|
{ name: "PetalBot", detect: /PetalBot/ },
|
|
365
|
+
{ name: "Applebot-Extended", detect: /Applebot-Extended/ },
|
|
325
366
|
{ name: "Applebot", detect: /Applebot/ },
|
|
326
|
-
// Social
|
|
367
|
+
// Social media crawlers
|
|
327
368
|
{ name: "Facebookbot", detect: /(facebookexternalhit|FacebookBot)/ },
|
|
328
369
|
{ name: "Twitterbot", detect: /Twitterbot/ },
|
|
329
370
|
{ name: "LinkedInBot", detect: /LinkedInBot/ },
|
|
371
|
+
{ name: "PinterestBot", detect: /Pinterest/ },
|
|
372
|
+
// Messaging link preview bots
|
|
373
|
+
{ name: "Slackbot", detect: /Slackbot/ },
|
|
374
|
+
{ name: "Discordbot", detect: /Discordbot/ },
|
|
375
|
+
{ name: "TelegramBot", detect: /TelegramBot/ },
|
|
376
|
+
{ name: "WhatsApp", detect: /WhatsApp/ },
|
|
330
377
|
// SEO tools
|
|
331
378
|
{ name: "SemrushBot", detect: /SemrushBot/ },
|
|
332
379
|
{ name: "AhrefsBot", detect: /AhrefsBot/ },
|
|
333
380
|
{ name: "MJ12bot", detect: /MJ12bot/ },
|
|
381
|
+
{ name: "ScreamingFrog", detect: /Screaming Frog/ },
|
|
382
|
+
{ name: "DataForSeoBot", detect: /DataForSeoBot/ },
|
|
334
383
|
// AI / LLM crawlers
|
|
335
384
|
{ name: "GPTBot", detect: /GPTBot/ },
|
|
385
|
+
{ name: "OAI-SearchBot", detect: /OAI-SearchBot/ },
|
|
386
|
+
{ name: "ChatGPT-User", detect: /ChatGPT-User/ },
|
|
336
387
|
{ name: "ClaudeBot", detect: /ClaudeBot/ },
|
|
337
388
|
{ name: "PerplexityBot", detect: /PerplexityBot/ },
|
|
338
389
|
{ name: "CCBot", detect: /CCBot/ },
|
|
339
390
|
{ name: "AdsBot", detect: /AdsBot-Google/ },
|
|
391
|
+
{ name: "Google-Extended", detect: /Google-Extended/ },
|
|
392
|
+
{ name: "Meta-ExternalAgent", detect: /meta-externalagent/i },
|
|
393
|
+
{ name: "Amazonbot", detect: /Amazonbot/ },
|
|
394
|
+
{ name: "Diffbot", detect: /Diffbot/ },
|
|
395
|
+
{ name: "cohere-ai", detect: /cohere-ai/ },
|
|
396
|
+
{ name: "YouBot", detect: /YouBot/ },
|
|
397
|
+
// Monitoring / archiving
|
|
398
|
+
{ name: "UptimeRobot", detect: /UptimeRobot/ },
|
|
399
|
+
{ name: "ia_archiver", detect: /ia_archiver/ },
|
|
340
400
|
// Generic catch-all (must be last)
|
|
341
401
|
{ name: "GenericBot", detect: /(bot|crawler|spider|crawling|scraper)/i }
|
|
342
402
|
];
|
|
343
403
|
|
|
344
404
|
// src/detectors/bot.ts
|
|
345
|
-
function detectBot(ua) {
|
|
346
|
-
|
|
405
|
+
function detectBot(ua, customDefs) {
|
|
406
|
+
const defs = customDefs ? [...BOT_DEFS.slice(0, -1), ...customDefs, BOT_DEFS[BOT_DEFS.length - 1]] : BOT_DEFS;
|
|
407
|
+
for (const def of defs) {
|
|
347
408
|
if (def.detect.test(ua)) {
|
|
348
409
|
return { isBot: true, botName: def.name };
|
|
349
410
|
}
|
|
@@ -353,7 +414,8 @@ function detectBot(ua) {
|
|
|
353
414
|
|
|
354
415
|
// src/constants/arch.ts
|
|
355
416
|
var ARCH_DEFS = [
|
|
356
|
-
|
|
417
|
+
// aarch64/arm64 explicit tokens + iOS devices (iPhone 5S+/iPad Air+ are exclusively arm64)
|
|
418
|
+
{ name: "arm64", detect: /(aarch64|arm64|ARM64|iPhone|iPad|iPod)/ },
|
|
357
419
|
{ name: "arm", detect: /\bARM\b/ },
|
|
358
420
|
{ name: "x86_64", detect: /(x86_64|Win64|WOW64|x64;|amd64)/i },
|
|
359
421
|
{ name: "x86", detect: /(i[36]86|i686|x86;)/ }
|
|
@@ -372,7 +434,7 @@ function detectArch(ua, ctx) {
|
|
|
372
434
|
}
|
|
373
435
|
const renderer = ctx == null ? void 0 : ctx.webglRenderer;
|
|
374
436
|
if (renderer) {
|
|
375
|
-
if (/Apple\s+(M\d|A\d{1,2}[A-Z]?)\b/i.test(renderer) || /APPLE M\d/i.test(renderer)) {
|
|
437
|
+
if (/Apple\s+(M\d|A\d{1,2}[A-Z]?)\b/i.test(renderer) || /APPLE M\d/i.test(renderer) || /^Apple GPU$/i.test(renderer)) {
|
|
376
438
|
return "arm64";
|
|
377
439
|
}
|
|
378
440
|
if (/\b(Intel|AMD|NVIDIA|Radeon)\b/i.test(renderer)) {
|
|
@@ -431,22 +493,95 @@ function getLanguage(nav) {
|
|
|
431
493
|
}
|
|
432
494
|
|
|
433
495
|
// src/parse.ts
|
|
496
|
+
var BRAND_TO_BROWSER = [
|
|
497
|
+
["Microsoft Edge", "Edge"],
|
|
498
|
+
["Opera", "Opera"],
|
|
499
|
+
["Vivaldi", "Vivaldi"],
|
|
500
|
+
["Google Chrome", "Chrome"],
|
|
501
|
+
["Chromium", "Chromium"]
|
|
502
|
+
];
|
|
503
|
+
function osFromHardware(ctx) {
|
|
504
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
505
|
+
const p = ((_a = ctx.platform) != null ? _a : "").toLowerCase();
|
|
506
|
+
const chPlatform = (_b = ctx.userAgentData) == null ? void 0 : _b.platform;
|
|
507
|
+
const platformVersion = (_c = ctx.highEntropyData) == null ? void 0 : _c.platformVersion;
|
|
508
|
+
const hasPlatformVersion = !!(platformVersion && platformVersion !== "0.0.0");
|
|
509
|
+
if (((_d = ctx.webglCompressedFormats) == null ? void 0 : _d.pvrtc) && !ctx.webglCompressedFormats.s3tc) return "iOS";
|
|
510
|
+
if (ctx.webglRenderer && /^ANGLE\b/.test(ctx.webglRenderer)) {
|
|
511
|
+
if (p.startsWith("mac") || chPlatform === "macOS") return "MacOS";
|
|
512
|
+
if (p.startsWith("win") || chPlatform === "Windows") return "Windows";
|
|
513
|
+
if (chPlatform === "Chrome OS") return "Chrome OS";
|
|
514
|
+
return null;
|
|
515
|
+
}
|
|
516
|
+
if (ctx.webglRenderer && (/Adreno/i.test(ctx.webglRenderer) || /Mali[-\s]/i.test(ctx.webglRenderer))) {
|
|
517
|
+
return "Android";
|
|
518
|
+
}
|
|
519
|
+
if (chPlatform && hasPlatformVersion) {
|
|
520
|
+
const chMap = {
|
|
521
|
+
Windows: "Windows",
|
|
522
|
+
macOS: "MacOS",
|
|
523
|
+
Android: "Android",
|
|
524
|
+
iOS: "iOS",
|
|
525
|
+
"Chrome OS": "Chrome OS"
|
|
526
|
+
};
|
|
527
|
+
const mapped = chMap[chPlatform];
|
|
528
|
+
if (mapped) return mapped;
|
|
529
|
+
}
|
|
530
|
+
if (p.startsWith("mac")) return "MacOS";
|
|
531
|
+
if (p.startsWith("win")) return "Windows";
|
|
532
|
+
if (p === "iphone" || p === "ipad" || p === "ipod") return "iOS";
|
|
533
|
+
if (((_e = ctx.safeAreaInsetTop) != null ? _e : 0) > 0) return "iOS";
|
|
534
|
+
if (chPlatform === "Chrome OS") return "Chrome OS";
|
|
535
|
+
if (chPlatform === "Android" && (p.includes("android") || /^linux arm/i.test((_f = ctx.platform) != null ? _f : ""))) {
|
|
536
|
+
return "Android";
|
|
537
|
+
}
|
|
538
|
+
if (p.includes("android") || /^linux arm/i.test((_g = ctx.platform) != null ? _g : "")) return "Android";
|
|
539
|
+
return null;
|
|
540
|
+
}
|
|
541
|
+
function platformFromUA(ua) {
|
|
542
|
+
if (/iPhone/.test(ua)) return "iPhone";
|
|
543
|
+
if (/iPad/.test(ua)) return "iPad";
|
|
544
|
+
if (/iPod/.test(ua)) return "iPod";
|
|
545
|
+
if (/Macintosh/.test(ua)) return "MacIntel";
|
|
546
|
+
if (/Windows NT/.test(ua)) return /Win64|WOW64/i.test(ua) ? "Win64" : "Win32";
|
|
547
|
+
if (/CrOS/.test(ua)) return "Linux x86_64";
|
|
548
|
+
if (/Android/.test(ua)) return /aarch64|arm64/i.test(ua) ? "Linux aarch64" : "Linux armv8l";
|
|
549
|
+
if (/Linux/.test(ua)) {
|
|
550
|
+
if (/x86_64/i.test(ua)) return "Linux x86_64";
|
|
551
|
+
if (/aarch64|arm64/i.test(ua)) return "Linux aarch64";
|
|
552
|
+
return "Linux";
|
|
553
|
+
}
|
|
554
|
+
return "unknown";
|
|
555
|
+
}
|
|
556
|
+
function languageFromUA(ua) {
|
|
557
|
+
const re = /[;(]\s*([a-z]{2,3}(?:[-_][A-Za-z]{2,4})+)\s*[;)]/g;
|
|
558
|
+
let m;
|
|
559
|
+
while ((m = re.exec(ua)) !== null) {
|
|
560
|
+
const parts = m[1].replace(/_/g, "-").split("-");
|
|
561
|
+
if (parts.length >= 2) {
|
|
562
|
+
return `${parts[0].toLowerCase()}-${parts.slice(1).map((p) => p.toUpperCase()).join("-")}`;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
return "unknown";
|
|
566
|
+
}
|
|
434
567
|
function parseUA(ua, options = {}) {
|
|
435
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
568
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
|
|
436
569
|
const effectiveNav = (_a = options.ctx) != null ? _a : options.nav;
|
|
437
570
|
const effectiveWindowsVersion = (_c = (_b = options.ctx) == null ? void 0 : _b.windowsVersion) != null ? _c : options.windowsVersion;
|
|
438
571
|
const { browser: rawBrowser, version: rawVersion } = detectBrowser(ua);
|
|
439
|
-
const { os, osVersion: rawOsVersion } = detectOs(ua, effectiveWindowsVersion);
|
|
572
|
+
const { os: rawOs, osVersion: rawOsVersion } = detectOs(ua, effectiveWindowsVersion);
|
|
573
|
+
let os = rawOs;
|
|
440
574
|
let osVersion = rawOsVersion;
|
|
441
575
|
const device = detectDevice(ua, effectiveNav);
|
|
442
|
-
const arch = detectArch(ua, options.ctx);
|
|
576
|
+
const arch = detectArch(ua, (_d = options.ctx) != null ? _d : effectiveNav);
|
|
443
577
|
const nav = effectiveNav;
|
|
444
|
-
const { isBot, botName } = detectBot(ua);
|
|
578
|
+
const { isBot, botName } = detectBot(ua, options.customBotDefs);
|
|
445
579
|
const isHeadless = detectHeadless(ua);
|
|
446
|
-
const language = nav ? getLanguage(nav) : "
|
|
447
|
-
const platform = (
|
|
580
|
+
const language = options.language || ((nav == null ? void 0 : nav.language) || (nav == null ? void 0 : nav.browserLanguage) ? getLanguage(nav) : "") || languageFromUA(ua);
|
|
581
|
+
const platform = (nav == null ? void 0 : nav.platform) || platformFromUA(ua);
|
|
448
582
|
let browser = rawBrowser;
|
|
449
583
|
let version = rawVersion;
|
|
584
|
+
if ((_e = options.ctx) == null ? void 0 : _e.hasBrave) browser = "Brave";
|
|
450
585
|
if (nav) {
|
|
451
586
|
const chromeGlobal = typeof chrome !== "undefined" ? chrome : void 0;
|
|
452
587
|
const chromeMatch = /Chrome\/([\d]+)/.exec(ua);
|
|
@@ -466,7 +601,7 @@ function parseUA(ua, options = {}) {
|
|
|
466
601
|
}
|
|
467
602
|
}
|
|
468
603
|
if (is360) {
|
|
469
|
-
const saveDataEnabled = ((
|
|
604
|
+
const saveDataEnabled = ((_f = nav.connection) == null ? void 0 : _f.saveData) === true;
|
|
470
605
|
if (getMimeType(nav, "application/gameplugin") || !saveDataEnabled) {
|
|
471
606
|
browser = "360SE";
|
|
472
607
|
} else {
|
|
@@ -479,8 +614,8 @@ function parseUA(ua, options = {}) {
|
|
|
479
614
|
}
|
|
480
615
|
if (browser === "Baidu" && /(Opera|OPR|OPT)/.test(ua)) {
|
|
481
616
|
browser = "Opera";
|
|
482
|
-
const opVer = (
|
|
483
|
-
version = (
|
|
617
|
+
const opVer = (_h = (_g = /OPR\/([\d.]+)/.exec(ua)) != null ? _g : /OPT\/([\d.]+)/.exec(ua)) != null ? _h : /Opera\/([\d.]+)/.exec(ua);
|
|
618
|
+
version = (_i = opVer == null ? void 0 : opVer[1]) != null ? _i : "unknown";
|
|
484
619
|
}
|
|
485
620
|
if (browser === "Chrome" && /\S+Browser\//.test(ua)) {
|
|
486
621
|
const m = /(\S+Browser)\/([\d.]+)/.exec(ua);
|
|
@@ -503,10 +638,47 @@ function parseUA(ua, options = {}) {
|
|
|
503
638
|
osVersion = m[1];
|
|
504
639
|
}
|
|
505
640
|
}
|
|
641
|
+
if (os === "MacOS" && browser === "Safari") {
|
|
642
|
+
const m = /Version\/([\d.]+)/.exec(ua);
|
|
643
|
+
if (m && parseInt(m[1], 10) >= 26) {
|
|
644
|
+
osVersion = m[1];
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
if (options.ctx) {
|
|
648
|
+
const hwOs = osFromHardware(options.ctx);
|
|
649
|
+
if (hwOs !== null) {
|
|
650
|
+
if (hwOs !== rawOs) {
|
|
651
|
+
os = hwOs;
|
|
652
|
+
osVersion = "unknown";
|
|
653
|
+
}
|
|
654
|
+
if (os !== "Windows") {
|
|
655
|
+
const pv = (_j = options.ctx.highEntropyData) == null ? void 0 : _j.platformVersion;
|
|
656
|
+
if (pv && pv !== "0.0.0") {
|
|
657
|
+
const parts = pv.split(".").map(Number);
|
|
658
|
+
while (parts.length > 1 && parts[parts.length - 1] === 0) parts.pop();
|
|
659
|
+
if (parts[0]) osVersion = parts.join(".");
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
const fullVersionList = (_k = options.ctx.highEntropyData) == null ? void 0 : _k.fullVersionList;
|
|
664
|
+
if (fullVersionList) {
|
|
665
|
+
for (const [brand, browserName] of BRAND_TO_BROWSER) {
|
|
666
|
+
const entry = fullVersionList.find((e) => e.brand === brand);
|
|
667
|
+
if (entry == null ? void 0 : entry.version) {
|
|
668
|
+
browser = browserName;
|
|
669
|
+
version = entry.version;
|
|
670
|
+
break;
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
}
|
|
506
675
|
const engine = detectEngine(ua, browser, version);
|
|
676
|
+
const versionMajor = parseInt((_l = version.split(".")[0]) != null ? _l : "0", 10) || 0;
|
|
677
|
+
const connectionType = (_p = (_o = (_n = (_m = options.ctx) != null ? _m : options.nav) == null ? void 0 : _n.connection) == null ? void 0 : _o.effectiveType) != null ? _p : "unknown";
|
|
507
678
|
return {
|
|
508
679
|
browser,
|
|
509
680
|
version,
|
|
681
|
+
versionMajor,
|
|
510
682
|
engine,
|
|
511
683
|
os,
|
|
512
684
|
osVersion,
|
|
@@ -517,25 +689,11 @@ function parseUA(ua, options = {}) {
|
|
|
517
689
|
isBot,
|
|
518
690
|
botName,
|
|
519
691
|
language,
|
|
520
|
-
platform
|
|
692
|
+
platform,
|
|
693
|
+
connectionType
|
|
521
694
|
};
|
|
522
695
|
}
|
|
523
696
|
|
|
524
|
-
// src/utils/windows-version.ts
|
|
525
|
-
async function getWindowsVersion(nav) {
|
|
526
|
-
var _a;
|
|
527
|
-
if (!nav.userAgentData || nav.userAgentData.platform !== "Windows") {
|
|
528
|
-
return null;
|
|
529
|
-
}
|
|
530
|
-
try {
|
|
531
|
-
const data = await nav.userAgentData.getHighEntropyValues(["platformVersion"]);
|
|
532
|
-
const major = parseInt(((_a = data["platformVersion"]) == null ? void 0 : _a.split(".")[0]) || "0", 10);
|
|
533
|
-
return major >= 13 ? "11" : "10";
|
|
534
|
-
} catch (e) {
|
|
535
|
-
return null;
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
|
|
539
697
|
// src/utils/env-context.ts
|
|
540
698
|
var OS_FONTS = [
|
|
541
699
|
".AppleSystemUIFont",
|
|
@@ -563,21 +721,56 @@ function probeFonts() {
|
|
|
563
721
|
}
|
|
564
722
|
}
|
|
565
723
|
function getWebGLInfo() {
|
|
566
|
-
var _a;
|
|
724
|
+
var _a, _b;
|
|
567
725
|
try {
|
|
568
726
|
const canvas = document.createElement("canvas");
|
|
569
727
|
const gl = (_a = canvas.getContext("webgl")) != null ? _a : canvas.getContext("experimental-webgl");
|
|
570
728
|
if (!gl) return {};
|
|
571
729
|
const ext = gl.getExtension("WEBGL_debug_renderer_info");
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
730
|
+
const result = {
|
|
731
|
+
maxTextureSize: gl.getParameter(gl.MAX_TEXTURE_SIZE),
|
|
732
|
+
fragPrecision: (_b = gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT)) == null ? void 0 : _b.rangeMax,
|
|
733
|
+
compressedFormats: {
|
|
734
|
+
s3tc: !!gl.getExtension("WEBGL_compressed_texture_s3tc"),
|
|
735
|
+
pvrtc: !!gl.getExtension("WEBGL_compressed_texture_pvrtc"),
|
|
736
|
+
etc2: !!gl.getExtension("WEBGL_compressed_texture_etc"),
|
|
737
|
+
astc: !!gl.getExtension("WEBGL_compressed_texture_astc_ldr")
|
|
738
|
+
}
|
|
576
739
|
};
|
|
740
|
+
if (ext) {
|
|
741
|
+
result.renderer = gl.getParameter(ext.UNMASKED_RENDERER_WEBGL);
|
|
742
|
+
result.vendor = gl.getParameter(ext.UNMASKED_VENDOR_WEBGL);
|
|
743
|
+
}
|
|
744
|
+
return result;
|
|
577
745
|
} catch (e) {
|
|
578
746
|
return {};
|
|
579
747
|
}
|
|
580
748
|
}
|
|
749
|
+
function getSafeAreaInsetTop() {
|
|
750
|
+
try {
|
|
751
|
+
const el = document.createElement("div");
|
|
752
|
+
el.style.cssText = "position:fixed;top:env(safe-area-inset-top,0px);visibility:hidden;pointer-events:none";
|
|
753
|
+
document.body.appendChild(el);
|
|
754
|
+
const top = parseFloat(getComputedStyle(el).top);
|
|
755
|
+
document.body.removeChild(el);
|
|
756
|
+
return isNaN(top) ? 0 : top;
|
|
757
|
+
} catch (e) {
|
|
758
|
+
return 0;
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
function getAudioSampleRate() {
|
|
762
|
+
var _a;
|
|
763
|
+
try {
|
|
764
|
+
const AC = (_a = window.AudioContext) != null ? _a : window.webkitAudioContext;
|
|
765
|
+
if (!AC) return void 0;
|
|
766
|
+
const ac = new AC();
|
|
767
|
+
const rate = ac.sampleRate;
|
|
768
|
+
void ac.close();
|
|
769
|
+
return rate;
|
|
770
|
+
} catch (e) {
|
|
771
|
+
return void 0;
|
|
772
|
+
}
|
|
773
|
+
}
|
|
581
774
|
function getPointerType() {
|
|
582
775
|
try {
|
|
583
776
|
if (window.matchMedia("(pointer: coarse)").matches) return "coarse";
|
|
@@ -601,20 +794,44 @@ function deriveWindowsVersion(platformVersion) {
|
|
|
601
794
|
return isNaN(major) ? null : major >= 13 ? "11" : "10";
|
|
602
795
|
}
|
|
603
796
|
async function getEnvContext() {
|
|
797
|
+
var _a, _b, _c, _d, _e;
|
|
604
798
|
const base = getNavContext();
|
|
605
|
-
const ctx = {
|
|
799
|
+
const ctx = {
|
|
800
|
+
userAgent: base.userAgent,
|
|
801
|
+
platform: base.platform,
|
|
802
|
+
language: base.language,
|
|
803
|
+
maxTouchPoints: base.maxTouchPoints
|
|
804
|
+
};
|
|
805
|
+
if (base.browserLanguage !== void 0) ctx.browserLanguage = base.browserLanguage;
|
|
806
|
+
if (base.mimeTypes !== void 0) ctx.mimeTypes = base.mimeTypes;
|
|
807
|
+
if (base.connection !== void 0) ctx.connection = base.connection;
|
|
808
|
+
if (base.userAgentData !== void 0) ctx.userAgentData = base.userAgentData;
|
|
606
809
|
if (typeof navigator !== "undefined") {
|
|
607
810
|
ctx.hardwareConcurrency = navigator.hardwareConcurrency;
|
|
608
811
|
ctx.deviceMemory = navigator.deviceMemory;
|
|
609
812
|
}
|
|
610
813
|
if (typeof window !== "undefined") {
|
|
611
814
|
ctx.devicePixelRatio = window.devicePixelRatio;
|
|
815
|
+
ctx.screenWidth = (_a = window.screen) == null ? void 0 : _a.width;
|
|
816
|
+
ctx.screenHeight = (_b = window.screen) == null ? void 0 : _b.height;
|
|
817
|
+
ctx.safeAreaInsetTop = getSafeAreaInsetTop();
|
|
612
818
|
ctx.pointerType = getPointerType();
|
|
613
819
|
ctx.hoverCapability = getHoverCapability();
|
|
614
820
|
ctx.fontProbes = probeFonts();
|
|
615
|
-
|
|
821
|
+
ctx.audioSampleRate = getAudioSampleRate();
|
|
822
|
+
ctx.hasVibration = "vibrate" in navigator;
|
|
823
|
+
ctx.hasDeviceMotion = "DeviceMotionEvent" in window;
|
|
824
|
+
try {
|
|
825
|
+
ctx.hasBrave = (_e = await ((_d = (_c = navigator.brave) == null ? void 0 : _c.isBrave) == null ? void 0 : _d.call(_c))) != null ? _e : false;
|
|
826
|
+
} catch (e) {
|
|
827
|
+
ctx.hasBrave = false;
|
|
828
|
+
}
|
|
829
|
+
const { renderer, vendor, maxTextureSize, fragPrecision, compressedFormats } = getWebGLInfo();
|
|
616
830
|
if (renderer !== void 0) ctx.webglRenderer = renderer;
|
|
617
831
|
if (vendor !== void 0) ctx.webglVendor = vendor;
|
|
832
|
+
if (maxTextureSize !== void 0) ctx.webglMaxTextureSize = maxTextureSize;
|
|
833
|
+
if (fragPrecision !== void 0) ctx.webglFragPrecision = fragPrecision;
|
|
834
|
+
if (compressedFormats !== void 0) ctx.webglCompressedFormats = compressedFormats;
|
|
618
835
|
}
|
|
619
836
|
if (base.userAgentData) {
|
|
620
837
|
try {
|
|
@@ -641,6 +858,26 @@ async function getEnvContext() {
|
|
|
641
858
|
return ctx;
|
|
642
859
|
}
|
|
643
860
|
|
|
861
|
+
// src/utils/windows-version.ts
|
|
862
|
+
async function getWindowsVersion(nav) {
|
|
863
|
+
var _a;
|
|
864
|
+
if (!nav.userAgentData || nav.userAgentData.platform !== "Windows") {
|
|
865
|
+
return null;
|
|
866
|
+
}
|
|
867
|
+
try {
|
|
868
|
+
const data = await nav.userAgentData.getHighEntropyValues(["platformVersion"]);
|
|
869
|
+
const major = parseInt(((_a = data["platformVersion"]) == null ? void 0 : _a.split(".")[0]) || "0", 10);
|
|
870
|
+
return major >= 13 ? "11" : "10";
|
|
871
|
+
} catch (e) {
|
|
872
|
+
return null;
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
// src/utils/satisfies.ts
|
|
877
|
+
function satisfies(info, criteria) {
|
|
878
|
+
return Object.keys(criteria).every((key) => info[key] === criteria[key]);
|
|
879
|
+
}
|
|
880
|
+
|
|
644
881
|
// src/parse-headers.ts
|
|
645
882
|
var ACCEPT_CH = [
|
|
646
883
|
"Sec-CH-UA-Arch",
|
|
@@ -660,7 +897,7 @@ function deriveWindowsVersion2(platformVersion) {
|
|
|
660
897
|
return isNaN(major) ? null : major >= 13 ? "11" : "10";
|
|
661
898
|
}
|
|
662
899
|
function parseHeaders(headers) {
|
|
663
|
-
var _a, _b;
|
|
900
|
+
var _a, _b, _c, _d, _e;
|
|
664
901
|
const normalised = {};
|
|
665
902
|
for (const key of Object.keys(headers)) {
|
|
666
903
|
normalised[key.toLowerCase()] = headers[key];
|
|
@@ -670,11 +907,13 @@ function parseHeaders(headers) {
|
|
|
670
907
|
return Array.isArray(v) ? v[0] : v;
|
|
671
908
|
};
|
|
672
909
|
const ua = (_a = get("user-agent")) != null ? _a : "";
|
|
910
|
+
const rawLang = get("accept-language");
|
|
911
|
+
const language = rawLang ? (_d = (_c = (_b = rawLang.split(",")[0]) == null ? void 0 : _b.split(";")[0]) == null ? void 0 : _c.trim()) != null ? _d : "" : "";
|
|
673
912
|
const architecture = unquote(get("sec-ch-ua-arch"));
|
|
674
913
|
const bitness = unquote(get("sec-ch-ua-bitness"));
|
|
675
914
|
const model = unquote(get("sec-ch-ua-model"));
|
|
676
915
|
const platformVersion = unquote(get("sec-ch-ua-platform-version"));
|
|
677
|
-
const platform = (
|
|
916
|
+
const platform = (_e = unquote(get("sec-ch-ua-platform"))) != null ? _e : "";
|
|
678
917
|
const highEntropyData = {};
|
|
679
918
|
if (architecture !== void 0) highEntropyData.architecture = architecture;
|
|
680
919
|
if (bitness !== void 0) highEntropyData.bitness = bitness;
|
|
@@ -685,7 +924,7 @@ function parseHeaders(headers) {
|
|
|
685
924
|
const ctx = {
|
|
686
925
|
userAgent: ua,
|
|
687
926
|
platform,
|
|
688
|
-
language
|
|
927
|
+
language,
|
|
689
928
|
maxTouchPoints: isMobile ? 1 : 0,
|
|
690
929
|
highEntropyData: Object.keys(highEntropyData).length > 0 ? highEntropyData : void 0,
|
|
691
930
|
windowsVersion
|
|
@@ -695,10 +934,14 @@ function parseHeaders(headers) {
|
|
|
695
934
|
|
|
696
935
|
// src/index.ts
|
|
697
936
|
var { version: VERSION } = package_default;
|
|
698
|
-
function uaBrowser(
|
|
937
|
+
function uaBrowser() {
|
|
699
938
|
const nav = getNavContext();
|
|
700
|
-
return parseUA(
|
|
939
|
+
return parseUA(nav.userAgent, { nav });
|
|
701
940
|
}
|
|
941
|
+
uaBrowser.detect = async (ua) => {
|
|
942
|
+
const ctx = await getEnvContext();
|
|
943
|
+
return parseUA(ua != null ? ua : ctx.userAgent, { ctx });
|
|
944
|
+
};
|
|
702
945
|
uaBrowser.isWebview = isWebview;
|
|
703
946
|
uaBrowser.getLanguage = () => getLanguage(getNavContext());
|
|
704
947
|
uaBrowser.VERSION = VERSION;
|
|
@@ -709,7 +952,9 @@ exports.VERSION = VERSION;
|
|
|
709
952
|
exports.default = src_default;
|
|
710
953
|
exports.detectArch = detectArch;
|
|
711
954
|
exports.detectBot = detectBot;
|
|
955
|
+
exports.detectBrowser = detectBrowser;
|
|
712
956
|
exports.detectHeadless = detectHeadless;
|
|
957
|
+
exports.detectOS = detectOs;
|
|
713
958
|
exports.getEnvContext = getEnvContext;
|
|
714
959
|
exports.getLanguage = getLanguage;
|
|
715
960
|
exports.getNavContext = getNavContext;
|
|
@@ -717,5 +962,6 @@ exports.getWindowsVersion = getWindowsVersion;
|
|
|
717
962
|
exports.isWebview = isWebview;
|
|
718
963
|
exports.parseHeaders = parseHeaders;
|
|
719
964
|
exports.parseUA = parseUA;
|
|
965
|
+
exports.satisfies = satisfies;
|
|
720
966
|
//# sourceMappingURL=index.cjs.map
|
|
721
967
|
//# sourceMappingURL=index.cjs.map
|