PageSourceSearch

https://beup-team.ru/js/browserDetect.pca7lg7x9e.js

js beup-team.ru collected 2026-09-30 11:29:53 UTC 55,783 bytes, 1,259 lines download raw bytes

1export function browserDetect(dotNetObjectRef) {
2    var parser = new UAParser();
3    var result = parser.getResult();
4
5    var gl = getGlRenderer();
6
7    var isMobile = navigator.userAgent.toLowerCase().indexOf('mobile') > -1 ?? (isiOS()),
8        isTablet = navigator.userAgent.toLowerCase().indexOf('tablet') > -1 ?? (isiPadOS() || isiPadPro()),
9        isAndroid = navigator.userAgent.toLowerCase().indexOf('android') > -1,
10        isiPhone = isiOS(),
11        isiPad = isiPadOS() || isiPadPro();
12
13    var agent = window.navigator.userAgent;
14    var timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
15
16    var deviceVendor = result.device.vendor ?? '';
17    if (deviceVendor === '' && (isiPad || isiPhone || isiPadPro()))
18        deviceVendor = 'Apple Inc.';
19
20    var deviceModel = result.device.model ?? '';
21    var deviceType = result.device.type ?? '';
22
23    if (deviceModel === 'iPad' || isiPad) {
24        deviceType = 'iPad';
25        deviceModel = getModels().toString();
26    }
27    else if (deviceModel === 'iPhone' || isiPhone) {
28        deviceType = 'iPhone';
29        deviceModel = getModels().toString();
30    }
31
32    var osName = parser.getOS().name;
33    var osVersion = parser.getOS().version;
34
35    var winVer = '';
36
37    if (typeof navigator.userAgentData !== 'undefined') {
38        navigator.userAgentData.getHighEntropyValues(["platformVersion"])
39            .then(ua => {
40                if (navigator.userAgentData.platform === "Windows") {
41                    var majorPlatformVersion = parseInt(ua.platformVersion.split('.')[0]);
42                    if (majorPlatformVersion >= 13) {
43                        winVer = "11 or later";
44                    }
45                    else {
46                        switch (majorPlatformVersion) {
47                            case 0:
48                                winVer = "7/8/8.1";
49                                break;
50                            case 1:
51                                winVer = "10 (1507)";
52                                break;
53                            case 2:
54                                winVer = "10 (1511)";
55                                break;
56                            case 3:
57                                winVer = "10 (1607)";
58                                break;
59                            case 4:
60                                winVer = "10 (1703)";
61                                break;
62                            case 5:
63                                winVer = "10 (1709)";
64                                break;
65                            case 6:
66                                winVer = "10 (1803)";
67                                break;
68                            case 7:
69                                winVer = "10 (1809)";
70                                break;
71                            case 8:
72                                winVer = "10 (1903 or 10 1909)";
73                                break;
74                            case 10:
75                                winVer = "10 (2004 or 20H2 or 21H1 or 21H2)";
76                                break;
77                            default:
78                                break;
79                        }
80                    }
81
82                    osVersion = winVer;
83
84                    dotNetObjectRef.invokeMethodAsync('OSUpdateString', winVer).then(null, function (err) {
85                        throw new Error(err);
86                    });
87                }
88                else if (navigator.userAgentData.platform === "macOS") {
89                    var macVer = ua.platformVersion;
90                    dotNetObjectRef.invokeMethodAsync('OSUpdateString', macVer).then(null, function (err) {
91                        throw new Error(err);
92                    });
93                }
94            });
95
96        navigator.userAgentData.getHighEntropyValues(["architecture", "bitness"])
97            .then(ua => {
98                if (navigator.userAgentData.platform === "Windows") {
99                    var winCPU = '';
100                    if (ua.architecture === 'x86') {
101                        if (ua.bitness === '64') {
102                            winCPU = "x86_64";
103                        }
104                        else if (ua.bitness === '32') {
105                            winCPU = "x86";
106                        }
107                    }
108                    else if (ua.architecture === 'arm') {
109                        if (ua.bitness === '64') {
110                            winCPU = "ARM64";
111                        }
112                        else if (ua.bitness === '32') {
113                            winCPU = "ARM32";
114                        }
115                    }
116
117                    dotNetObjectRef.invokeMethodAsync('OSArchitectureUpdateString', winCPU).then(null, function (err) {
118                        throw new Error(err);
119                    });
120                }
121                else if (navigator.userAgentData.platform === "macOS") {
122                    var macCPU = ua.architecture + ' ' + ua.bitness;
123                    dotNetObjectRef.invokeMethodAsync('OSArchitectureUpdateString', macCPU).then(null, function (err) {
124                        throw new Error(err);
125                    });
126                }
127            });
128    }
129
130    var rtn = {
131        BrowserMajor: result.browser.major ?? '',
132        BrowserName: result.browser.name ?? '',
133        BrowserVersion: result.browser.version ?? '',
134        CPUArchitect: result.cpu.architecture ?? '',
135        DeviceModel: deviceModel,
136        DeviceType: deviceType,
137        DeviceVendor: deviceVendor,
138        EngineName: result.engine.name ?? '',
139        EngineVersion: result.engine.version ?? '',
140        GPURenderer: gl.glRenderer,
141        GPUVendor: gl.glVendor,
142        IsDesktop: isDesktop(),
143        IsMobile: isMobile ?? false,
144        IsTablet: isTablet ?? false,
145        IsAndroid: isAndroid ?? false,
146        IsIPhone: isiPhone ?? false,
147        IsIPad: isiPad ?? false,
148        isIpadPro: isiPadPro(),
149        OSName: osName,
150        OSVersion: osVersion,
151        ScreenResolution: (window.screen.width * window.devicePixelRatio) + 'x' + (window.screen.height * window.devicePixelRatio),
152        TimeZone: timeZone,
153        UserAgent: agent
154    };
155
156    return rtn;
157}
158
159function isiOS() {
160    if (/iPhone|iPod/.test(navigator.platform)) {
161        return true;
162    } else {
163        return false;
164    }
165}
166
167function isiPadOS() {
168    if (/iPad/.test(navigator.platform)) {
169        return true;
170    } else {
171        return false;
172    }
173}
174
175function isiPadPro() {
176    var ratio = window.devicePixelRatio || 1;
177    var screen = {
178        width: window.screen.width * ratio,
179        height: window.screen.height * ratio
180    };
181
182    return (screen.width === 2048 && screen.height === 2732) ||
183        (screen.width === 2732 && screen.height === 2048) ||
184        (screen.width === 1536 && screen.height === 2048) ||
185        (screen.width === 2048 && screen.height === 1536);
186}
187
188function isDesktop() {
189    if ((navigator.userAgent.match(/iPhone/i)) ||
190        (navigator.userAgent.match(/(up.browser|up.link|mmp|symbian|smartphone|midp|wap|vodafone|o2|pocket|kindle|mobile|pda|psp|treo)/i)) ||
191        (navigator.userAgent.match(/iPod/i)) ||
192        (navigator.userAgent.match(/operamini/i)) ||
193        (navigator.userAgent.match(/blackberry/i)) ||
194        (navigator.userAgent.match(/(palmos|palm|hiptop|avantgo|plucker|xiino|blazer|elaine)/i)) ||
195        (navigator.userAgent.match(/(windowsce; ppc;|windows ce;smartphone;|windows ce; iemobile) /i)) ||
196        (navigator.userAgent.match(/android/i)) || isiOS() || isiPadOS() || isiPadPro()) {
197        return false;
198    }
199    else {
200        return true;
201    }
202}
203
204function OSVersion() {
205    var rtn = "";
206
207    var userAgent = window.navigator.userAgent;
208
209    if (userAgent.indexOf("Windows NT 10.0") > 0) {
210        rtn = "Windows 10/11";
211    }
212    else if (userAgent.indexOf("Windows NT 6.3") > 0) {
213        rtn = "Windows 8.1";
214    }
215    else if (userAgent.indexOf("Windows NT 6.2") > 0) {
216        rtn = "Windows 8";
217    }
218    else if (userAgent.indexOf("Windows NT 6.1") > 0) {
219        rtn = "Windows 7";
220    }
221    else if (userAgent.indexOf("Windows NT 6.0") > 0) {
222        rtn = "Windows Vista";
223    }
224    else if (userAgent.indexOf("Windows NT 5.2") > 0) {
225        rtn = "Windows Server 2003; Windows XP x64 Edition";
226    }
227    else if (userAgent.indexOf("Windows NT 5.1") > 0) {
228        rtn = "Windows XP";
229    }
230    else if (userAgent.indexOf("Windows NT 5.01") > 0) {
231        rtn = "Windows 2000, Service Pack 1 (SP1)";
232    }
233    else if (userAgent.indexOf("Windows NT 5.0") > 0) {
234        rtn = "Windows 2000";
235    }
236    else if (userAgent.indexOf("Windows NT 4.0") > 0) {
237        rtn = "Microsoft Windows NT 4.0";
238    }
239    else if (userAgent.indexOf("Win 9x 4.90") > 0) {
240        rtn = "Windows Millennium Edition (Windows Me)";
241    }
242    else if (userAgent.indexOf("Windows 98") > 0) {
243        rtn = "Windows 98";
244    }
245    else if (userAgent.indexOf("Windows 95") > 0) {
246        rtn = "Windows 95";
247    }
248    else if (userAgent.indexOf("Windows CE") > 0) {
249        rtn = "Windows CE";
250    }
251    else if (userAgent.indexOf("iPhone OS") > 0) {
252        rtn = "iPhone OS";
253    }
254    else if (userAgent.indexOf("Mac OS") > 0) {
255        rtn = "Max OS";
256    }
257    else if (userAgent.indexOf("Android") > 0) {
258        rtn = "Android";
259    }
260    else if (userAgent.indexOf("Silk") > 0) {
261        rtn = "Amazon Fire";
262    }
263    else if (userAgent.indexOf("facebook") > 0) {
264        rtn = "Facebook External Hit";
265    }
266    else if (userAgent.indexOf("Twitterbot") > 0) {
267        rtn = "Twitterbot";
268    }
269    else if (userAgent.indexOf("WhatsApp") > 0) {
270        rtn = "WhatsApp";
271    }
272    else {
273        //Others
274    }
275
276    return rtn;
277}
278
279var canvas, gl, glRenderer, models,
280    devices = [
281        ['a7', '640x1136', ['iPhone 5', 'iPhone 5s']],
282        ['a7', '1536x2048', ['iPad Air', 'iPad Mini 2', 'iPad Mini 3', 'iPad Pro 9.7']],
283        ['a8', '640x1136', ['iPod touch (6th gen)']],
284        ['a8', '750x1334', ['iPhone 6']],
285        ['a8', '1242x2208', ['iPhone 6 Plus']],
286        ['a8', '1536x2048', ['iPad Air 2', 'iPad Mini 4']],
287        ['a9', '640x1136', ['iPhone SE']],
288        ['a9', '750x1334', ['iPhone 6s']],
289        ['a9', '1242x2208', ['iPhone 6s Plus']],
290        ['a9x', '1536x2048', ['iPad Pro (1st gen 9.7-inch)']],
291        ['a9x', '2048x2732', ['iPad Pro (1st gen 12.9-inch)']],
292        ['a10', '750x1334', ['iPhone 7']],
293        ['a10', '1242x2208', ['iPhone 7 Plus']],
294        ['a10x', '1668x2224', ['iPad Pro (2th gen 10.5-inch)']],
295        ['a10x', '2048x2732', ['iPad Pro (2th gen 12.9-inch)']],
296        ['a11', '750x1334', ['iPhone 8']],
297        ['a11', '1242x2208', ['iPhone 8 Plus']],
298        ['a11', '1125x2436', ['iPhone X']],
299        ['a12', '828x1792', ['iPhone Xr']],
300        ['a12', '1125x2436', ['iPhone Xs']],
301        ['a12', '1242x2688', ['iPhone Xs Max']],
302        ['a12x', '1668x2388', ['iPad Pro (3rd gen 11-inch)']],
303        ['a12x', '2048x2732', ['iPad Pro (3rd gen 12.9-inch)']],
304        ['a15', '2556x1179', ['iPhone 14']],
305        ['a15', '2796x1290', ['iPhone 14 Max']]
306    ];
307
308function getCanvas() {
309    if (canvas == null) {
310        canvas = document.createElement('canvas');
311    }
312
313    return canvas;
314}
315
316function getGl() {
317    if (gl == null) {
318        gl = getCanvas().getContext('webgl');
319    }
320
321    return gl;
322}
323
324function getResolution() {
325    var ratio = window.devicePixelRatio || 1;
326    return (Math.min(screen.width, screen.height) * ratio)
327        + 'x' + (Math.max(screen.width, screen.height) * ratio);
328}
329
330function getGlRenderer() {
331    var glVendor = 'Unknown';
332
333    if (glRenderer == null) {
334        const gl = document.createElement("canvas").getContext("webgl");
335        // try to get the extensions
336        const ext = gl.getExtension("WEBGL_debug_renderer_info");
337
338        // if the extension exists, find out the info.
339        if (ext) {
340            glRenderer = gl.getParameter(ext.UNMASKED_RENDERER_WEBGL);
341            glVendor = gl.getParameter(ext.UNMASKED_VENDOR_WEBGL);
342        }
343        else {
344            glRenderer = "Unknown";
345        }
346    }
347
348    return { glRenderer, glVendor };
349}
350
351function getModels() {
352    if (models === undefined) {
353        var gpu = getGlRenderer();
354        var matches = gpu.glRenderer.toLowerCase().includes('apple');
355        var res = getResolution();
356
357        models = ['unknown'];
358
359        if (matches) {
360            for (var i = 0; i < devices.length; i++) {
361                var device = devices[i];
362
363                var res2 = res.split('x').reverse().join('x');
364                if (res == device[1] || res2 == device[1]) {
365                    models = device[2];
366                    break;
367                }
368            }
369        }
370    }
371
372    return models;
373}
374
375function getDeviceInfo() {
376    if (window.MobileDevice == undefined) {
377        window.MobileDevice = {};
378    }
379
380    window.MobileDevice.getGlRenderer = getGlRenderer;
381    window.MobileDevice.getModels = getModels;
382    window.MobileDevice.getResolution = getResolution;
383
384    var currentModels = getModels();
385    //var match = match.toLowerCase().replace(/\s+$/, '') + ' ';
386
387    for (var i = 0; i < currentModels.length; i++) {
388        var model = currentModels[i].toLowerCase() + ' ';
389
390        if (0 === model.indexOf(math)) {
391            return true;
392        }
393    }
394}
395
396(function (window, undefined) {
397    'use strict';
398
399    //////////////
400    // Constants
401    /////////////
402
403    var LIBVERSION = '0.7.31',
404        EMPTY = '',
405        UNKNOWN = '?',
406        FUNC_TYPE = 'function',
407        UNDEF_TYPE = 'undefined',
408        OBJ_TYPE = 'object',
409        STR_TYPE = 'string',
410        MAJOR = 'major',
411        MODEL = 'model',
412        NAME = 'name',
413        TYPE = 'type',
414        VENDOR = 'vendor',
415        VERSION = 'version',
416        ARCHITECTURE = 'architecture',
417        CONSOLE = 'console',
418        MOBILE = 'mobile',
419        TABLET = 'tablet',
420        SMARTTV = 'smarttv',
421        WEARABLE = 'wearable',
422        EMBEDDED = 'embedded',
423        UA_MAX_LENGTH = 275;
424
425    var AMAZON = 'Amazon',
426        APPLE = 'Apple',
427        ASUS = 'ASUS',
428        BLACKBERRY = 'BlackBerry',
429        BROWSER = 'Browser',
430        CHROME = 'Chrome',
431        EDGE = 'Edge',
432        FIREFOX = 'Firefox',
433        GOOGLE = 'Google',
434        HUAWEI = 'Huawei',
435        LG = 'LG',
436        MICROSOFT = 'Microsoft',
437        MOTOROLA = 'Motorola',
438        OPERA = 'Opera',
439        SAMSUNG = 'Samsung',
440        SONY = 'Sony',
441        XIAOMI = 'Xiaomi',
442        ZEBRA = 'Zebra',
443        FACEBOOK = 'Facebook';
444
445    ///////////
446    // Helper
447    //////////
448
449    var extend = function (regexes, extensions) {
450        var mergedRegexes = {};
451        for (var i in regexes) {
452            if (extensions[i] && extensions[i].length % 2 === 0) {
453                mergedRegexes[i] = extensions[i].concat(regexes[i]);
454            } else {
455                mergedRegexes[i] = regexes[i];
456            }
457        }
458        return mergedRegexes;
459    },
460        enumerize = function (arr) {
461            var enums = {};
462            for (var i = 0; i < arr.length; i++) {
463                enums[arr[i].toUpperCase()] = arr[i];
464            }
465            return enums;
466        },
467        has = function (str1, str2) {
468            return typeof str1 === STR_TYPE ? lowerize(str2).indexOf(lowerize(str1)) !== -1 : false;
469        },
470        lowerize = function (str) {
471            return str.toLowerCase();
472        },
473        majorize = function (version) {
474            return typeof (version) === STR_TYPE ? version.replace(/[^\d\.]/g, EMPTY).split('.')[0] : undefined;
475        },
476        trim = function (str, len) {
477            if (typeof (str) === STR_TYPE) {
478                str = str.replace(/^\s\s*/, EMPTY).replace(/\s\s*$/, EMPTY);
479                return typeof (len) === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH);
480            }
481        };
482
483    ///////////////
484    // Map helper
485    //////////////
486
487    var rgxMapper = function (ua, arrays) {
488
489        var i = 0, j, k, p, q, matches, match;
490
491        // loop through all regexes maps
492        while (i < arrays.length && !matches) {
493
494            var regex = arrays[i],       // even sequence (0,2,4,..)
495                props = arrays[i + 1];   // odd sequence (1,3,5,..)
496            j = k = 0;
497
498            // try matching uastring with regexes
499            while (j < regex.length && !matches) {
500
501                matches = regex[j++].exec(ua);
502
503                if (!!matches) {
504                    for (p = 0; p < props.length; p++) {
505                        match = matches[++k];
506                        q = props[p];
507                        // check if given property is actually array
508                        if (typeof q === OBJ_TYPE && q.length > 0) {
509                            if (q.length === 2) {
510                                if (typeof q[1] == FUNC_TYPE) {
511                                    // assign modified match
512                                    this[q[0]] = q[1].call(this, match);
513                                } else {
514                                    // assign given value, ignore regex match
515                                    this[q[0]] = q[1];
516                                }
517                            } else if (q.length === 3) {
518                                // check whether function or regex
519                                if (typeof q[1] === FUNC_TYPE && !(q[1].exec && q[1].test)) {
520                                    // call function (usually string mapper)
521                                    this[q[0]] = match ? q[1].call(this, match, q[2]) : undefined;
522                                } else {
523                                    // sanitize match using given regex
524                                    this[q[0]] = match ? match.replace(q[1], q[2]) : undefined;
525                                }
526                            } else if (q.length === 4) {
527                                this[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined;
528                            }
529                        } else {
530                            this[q] = match ? match : undefined;
531                        }
532                    }
533                }
534            }
535            i += 2;
536        }
537    },
538
539        strMapper = function (str, map) {
540
541            for (var i in map) {
542                // check if current value is array
543                if (typeof map[i] === OBJ_TYPE && map[i].length > 0) {
544                    for (var j = 0; j < map[i].length; j++) {
545                        if (has(map[i][j], str)) {
546                            return (i === UNKNOWN) ? undefined : i;
547                        }
548                    }
549                } else if (has(map[i], str)) {
550                    return (i === UNKNOWN) ? undefined : i;
551                }
552            }
553            return str;
554        };
555
vendor: 4,091 bytes, lines 556-637
556    ///////////////
557    // String map
558    //////////////
559
560    // Safari < 3.0
561    var oldSafariMap = {
562        '1.0': '/8',
563        '1.2': '/1',
564        '1.3': '/3',
565        '2.0': '/412',
566        '2.0.2': '/416',
567        '2.0.3': '/417',
568        '2.0.4': '/419',
569        '?': '/'
570    },
571        windowsVersionMap = {
572            'ME': '4.90',
573            'NT 3.11': 'NT3.51',
574            'NT 4.0': 'NT4.0',
575            '2000': 'NT 5.0',
576            'XP': ['NT 5.1', 'NT 5.2'],
577            'Vista': 'NT 6.0',
578            '7': 'NT 6.1',
579            '8': 'NT 6.2',
580            '8.1': 'NT 6.3',
581            '10': ['NT 6.4', 'NT 10.0'],
582            'RT': 'ARM'
583        };
584
585    //////////////
586    // Regex map
587    /////////////
588
589    var regexes = {
590
591        browser: [[
592
593            /\b(?:crmo|crios)\/([\w\.]+)/i                                      // Chrome for Android/iOS
594        ], [VERSION, [NAME, 'Chrome']], [
595            /edg(?:e|ios|a)?\/([\w\.]+)/i                                       // Microsoft Edge
596        ], [VERSION, [NAME, 'Edge']], [
597
598            // Presto based
599            /(opera mini)\/([-\w\.]+)/i,                                        // Opera Mini
600            /(opera [mobiletab]{3,6})\b.+version\/([-\w\.]+)/i,                 // Opera Mobi/Tablet
601            /(opera)(?:.+version\/|[\/ ]+)([\w\.]+)/i                           // Opera
602        ], [NAME, VERSION], [
603            /opios[\/ ]+([\w\.]+)/i                                             // Opera mini on iphone >= 8.0
604        ], [VERSION, [NAME, OPERA + ' Mini']], [
605            /\bopr\/([\w\.]+)/i                                                 // Opera Webkit
606        ], [VERSION, [NAME, OPERA]], [
607
608            // Mixed
609            /(kindle)\/([\w\.]+)/i,                                             // Kindle
610            /(lunascape|maxthon|netfront|jasmine|blazer)[\/ ]?([\w\.]*)/i,      // Lunascape/Maxthon/Netfront/Jasmine/Blazer
611            // Trident based
612            /(avant |iemobile|slim)(?:browser)?[\/ ]?([\w\.]*)/i,               // Avant/IEMobile/SlimBrowser
613            /(ba?idubrowser)[\/ ]?([\w\.]+)/i,                                  // Baidu Browser
614            /(?:ms|\()(ie) ([\w\.]+)/i,                                         // Internet Explorer
615
616            // Webkit/KHTML based                                               // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon
617            /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale|qqbrowserlite|qq)\/([-\w\.]+)/i,
618            // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ, aka ShouQ
619            /(weibo)__([\d\.]+)/i                                               // Weibo
620        ], [NAME, VERSION], [
621            /(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i                 // UCBrowser
622        ], [VERSION, [NAME, 'UC' + BROWSER]], [
623            /\bqbcore\/([\w\.]+)/i                                              // WeChat Desktop for Windows Built-in Browser
624        ], [VERSION, [NAME, 'WeChat(Win) Desktop']], [
625            /micromessenger\/([\w\.]+)/i                                        // WeChat
626        ], [VERSION, [NAME, 'WeChat']], [
627            /konqueror\/([\w\.]+)/i                                             // Konqueror
628        ], [VERSION, [NAME, 'Konqueror']], [
629            /trident.+rv[: ]([\w\.]{1,9})\b.+like gecko/i                       // IE11
630        ], [VERSION, [NAME, 'IE']], [
631            /yabrowser\/([\w\.]+)/i                                             // Yandex
632        ], [VERSION, [NAME, 'Yandex']], [
633            /(avast|avg)\/([\w\.]+)/i                                           // Avast/AVG Secure Browser
634        ], [[NAME, /(.+)/, '$1 Secure ' + BROWSER], VERSION], [
635            /\bfocus\/([\w\.]+)/i                                               // Firefox Focus
636        ], [VERSION, [NAME, FIREFOX + ' Focus']], [
637            /\bopt\/([\w\.]+)/i                                                 // Opera Touch
vendor: 4,336 bytes, lines 638-704
638        ], [VERSION, [NAME, OPERA + ' Touch']], [
639            /coc_coc\w+\/([\w\.]+)/i                                            // Coc Coc Browser
640        ], [VERSION, [NAME, 'Coc Coc']], [
641            /dolfin\/([\w\.]+)/i                                                // Dolphin
642        ], [VERSION, [NAME, 'Dolphin']], [
643            /coast\/([\w\.]+)/i                                                 // Opera Coast
644        ], [VERSION, [NAME, OPERA + ' Coast']], [
645            /miuibrowser\/([\w\.]+)/i                                           // MIUI Browser
646        ], [VERSION, [NAME, 'MIUI ' + BROWSER]], [
647            /fxios\/([-\w\.]+)/i                                                // Firefox for iOS
648        ], [VERSION, [NAME, FIREFOX]], [
649            /\bqihu|(qi?ho?o?|360)browser/i                                     // 360
650        ], [[NAME, '360 ' + BROWSER]], [
651            /(oculus|samsung|sailfish)browser\/([\w\.]+)/i
652        ], [[NAME, /(.+)/, '$1 ' + BROWSER], VERSION], [                      // Oculus/Samsung/Sailfish Browser
653            /(comodo_dragon)\/([\w\.]+)/i                                       // Comodo Dragon
654        ], [[NAME, /_/g, ' '], VERSION], [
655            /(electron)\/([\w\.]+) safari/i,                                    // Electron-based App
656            /(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i,                   // Tesla
657            /m?(qqbrowser|baiduboxapp|2345Explorer)[\/ ]?([\w\.]+)/i            // QQBrowser/Baidu App/2345 Browser
658        ], [NAME, VERSION], [
659            /(metasr)[\/ ]?([\w\.]+)/i,                                         // SouGouBrowser
660            /(lbbrowser)/i                                                      // LieBao Browser
661        ], [NAME], [
662
663            // WebView
664            /((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i       // Facebook App for iOS & Android
665        ], [[NAME, FACEBOOK], VERSION], [
666            /safari (line)\/([\w\.]+)/i,                                        // Line App for iOS
667            /\b(line)\/([\w\.]+)\/iab/i,                                        // Line App for Android
668            /(chromium|instagram)[\/ ]([-\w\.]+)/i                              // Chromium/Instagram
669        ], [NAME, VERSION], [
670            /\bgsa\/([\w\.]+) .*safari\//i                                      // Google Search Appliance on iOS
671        ], [VERSION, [NAME, 'GSA']], [
672
673            /headlesschrome(?:\/([\w\.]+)| )/i                                  // Chrome Headless
674        ], [VERSION, [NAME, CHROME + ' Headless']], [
675
676            / wv\).+(chrome)\/([\w\.]+)/i                                       // Chrome WebView
677        ], [[NAME, CHROME + ' WebView'], VERSION], [
678
679            /droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i           // Android Browser
680        ], [VERSION, [NAME, 'Android ' + BROWSER]], [
681
682            /(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i       // Chrome/OmniWeb/Arora/Tizen/Nokia
683        ], [NAME, VERSION], [
684
685            /version\/([\w\.]+) .*mobile\/\w+ (safari)/i                        // Mobile Safari
686        ], [VERSION, [NAME, 'Mobile Safari']], [
687            /version\/([\w\.]+) .*(mobile ?safari|safari)/i                     // Safari & Safari Mobile
688        ], [VERSION, NAME], [
689            /webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i                      // Safari < 3.0
690        ], [NAME, [VERSION, strMapper, oldSafariMap]], [
691
692            /(webkit|khtml)\/([\w\.]+)/i
693        ], [NAME, VERSION], [
694
695            // Gecko based
696            /(navigator|netscape\d?)\/([-\w\.]+)/i                              // Netscape
697        ], [[NAME, 'Netscape'], VERSION], [
698            /mobile vr; rv:([\w\.]+)\).+firefox/i                               // Firefox Reality
699        ], [VERSION, [NAME, FIREFOX + ' Reality']], [
700            /ekiohf.+(flow)\/([\w\.]+)/i,                                       // Flow
701            /(swiftfox)/i,                                                      // Swiftfox
702            /(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror|klar)[\/ ]?([\w\.\+]+)/i,
703            // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror/Klar
704            /(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([-\w\.]+)$/i,
705            // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix
706            /(firefox)\/([\w\.]+)/i,                                            // Other Firefox-based
707            /(mozilla)\/([\w\.]+) .+rv\:.+gecko\/\d+/i,                         // Mozilla
708
709            // Other
710            /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir|obigo|mosaic|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i,
711            // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Sleipnir/Obigo/Mosaic/Go/ICE/UP.Browser
712            /(links) \(([\w\.]+)/i                                              // Links
713        ], [NAME, VERSION]
714        ],
715
716        cpu: [[
717
718            /(?:(amd|x(?:(?:86|64)[-_])?|wow|win)64)[;\)]/i                     // AMD64 (x64)
719        ], [[ARCHITECTURE, 'amd64']], [
720
721            /(ia32(?=;))/i                                                      // IA32 (quicktime)
722        ], [[ARCHITECTURE, lowerize]], [
723
724            /((?:i[346]|x)86)[;\)]/i                                            // IA32 (x86)
725        ], [[ARCHITECTURE, 'ia32']], [
726
727            /\b(aarch64|arm(v?8e?l?|_?64))\b/i                                 // ARM64
728        ], [[ARCHITECTURE, 'arm64']], [
729
730            /\b(arm(?:v[67])?ht?n?[fl]p?)\b/i                                   // ARMHF
731        ], [[ARCHITECTURE, 'armhf']], [
732
733            // PocketPC mistakenly identified as PowerPC
734            /windows (ce|mobile); ppc;/i
735        ], [[ARCHITECTURE, 'arm']], [
736
737            /((?:ppc|powerpc)(?:64)?)(?: mac|;|\))/i                            // PowerPC
738        ], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [
739
740            /(sun4\w)[;\)]/i                                                    // SPARC
741        ], [[ARCHITECTURE, 'sparc']], [
742
743            /((?:avr32|ia64(?=;))|68k(?=\))|\barm(?=v(?:[1-7]|[5-7]1)l?|;|eabi)|(?=atmel )avr|(?:irix|mips|sparc)(?:64)?\b|pa-risc)/i
744            // IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC
745        ], [[ARCHITECTURE, lowerize]]
746        ],
747
748        device: [[
749
vendor: 20,329 bytes, lines 750-1110
750            //////////////////////////
751            // MOBILES & TABLETS
752            // Ordered by popularity
753            /////////////////////////
754
755            // Samsung
756            /\b(sch-i[89]0\d|shw-m380s|sm-[pt]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus 10)/i
757        ], [MODEL, [VENDOR, SAMSUNG], [TYPE, TABLET]], [
758            /\b((?:s[cgp]h|gt|sm)-\w+|galaxy nexus)/i,
759            /samsung[- ]([-\w]+)/i,
760            /sec-(sgh\w+)/i
761        ], [MODEL, [VENDOR, SAMSUNG], [TYPE, MOBILE]], [
762
763            // Apple
764            /\((ip(?:hone|od)[\w ]*);/i                                         // iPod/iPhone
765        ], [MODEL, [VENDOR, APPLE], [TYPE, MOBILE]], [
766            /\((ipad);[-\w\),; ]+apple/i,                                       // iPad
767            /applecoremedia\/[\w\.]+ \((ipad)/i,
768            /\b(ipad)\d\d?,\d\d?[;\]].+ios/i
769        ], [MODEL, [VENDOR, APPLE], [TYPE, TABLET]], [
770
771            // Huawei
772            /\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i
773        ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [
774            /(?:huawei|honor)([-\w ]+)[;\)]/i,
775            /\b(nexus 6p|\w{2,4}-[atu]?[ln][01259x][012359][an]?)\b(?!.+d\/s)/i
776        ], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [
777
778            // Xiaomi
779            /\b(poco[\w ]+)(?: bui|\))/i,                                       // Xiaomi POCO
780            /\b; (\w+) build\/hm\1/i,                                           // Xiaomi Hongmi 'numeric' models
781            /\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i,                             // Xiaomi Hongmi
782            /\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i,                   // Xiaomi Redmi
783            /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\))/i // Xiaomi Mi
784        ], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [
785            /\b(mi[-_ ]?(?:pad)(?:[\w_ ]+))(?: bui|\))/i                        // Mi Pad tablets
786        ], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, TABLET]], [
787
788            // OPPO
789            /; (\w+) bui.+ oppo/i,
790            /\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i
791        ], [MODEL, [VENDOR, 'OPPO'], [TYPE, MOBILE]], [
792
793            // Vivo
794            /vivo (\w+)(?: bui|\))/i,
795            /\b(v[12]\d{3}\w?[at])(?: bui|;)/i
796        ], [MODEL, [VENDOR, 'Vivo'], [TYPE, MOBILE]], [
797
798            // Realme
799            /\b(rmx[12]\d{3})(?: bui|;|\))/i
800        ], [MODEL, [VENDOR, 'Realme'], [TYPE, MOBILE]], [
801
802            // Motorola
803            /\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w ]+build\//i,
804            /\bmot(?:orola)?[- ](\w*)/i,
805            /((?:moto[\w\(\) ]+|xt\d{3,4}|nexus 6)(?= bui|\)))/i
806        ], [MODEL, [VENDOR, MOTOROLA], [TYPE, MOBILE]], [
807            /\b(mz60\d|xoom[2 ]{0,2}) build\//i
808        ], [MODEL, [VENDOR, MOTOROLA], [TYPE, TABLET]], [
809
810            // LG
811            /((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i
812        ], [MODEL, [VENDOR, LG], [TYPE, TABLET]], [
813            /(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i,
814            /\blg[-e;\/ ]+((?!browser|netcast|android tv)\w+)/i,
815            /\blg-?([\d\w]+) bui/i
816        ], [MODEL, [VENDOR, LG], [TYPE, MOBILE]], [
817
818            // Lenovo
819            /(ideatab[-\w ]+)/i,
820            /lenovo ?(s[56]000[-\w]+|tab(?:[\w ]+)|yt[-\d\w]{6}|tb[-\d\w]{6})/i
821        ], [MODEL, [VENDOR, 'Lenovo'], [TYPE, TABLET]], [
822
823            // Nokia
824            /(?:maemo|nokia).*(n900|lumia \d+)/i,
825            /nokia[-_ ]?([-\w\.]*)/i
826        ], [[MODEL, /_/g, ' '], [VENDOR, 'Nokia'], [TYPE, MOBILE]], [
827
828            // Google
829            /(pixel c)\b/i                                                      // Google Pixel C
830        ], [MODEL, [VENDOR, GOOGLE], [TYPE, TABLET]], [
831            /droid.+; (pixel[\daxl ]{0,6})(?: bui|\))/i                         // Google Pixel
832        ], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [
833
834            // Sony
835            /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
836        ], [MODEL, [VENDOR, SONY], [TYPE, MOBILE]], [
837            /sony tablet [ps]/i,
838            /\b(?:sony)?sgp\w+(?: bui|\))/i
839        ], [[MODEL, 'Xperia Tablet'], [VENDOR, SONY], [TYPE, TABLET]], [
840
841            // OnePlus
842            / (kb2005|in20[12]5|be20[12][59])\b/i,
843            /(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i
844        ], [MODEL, [VENDOR, 'OnePlus'], [TYPE, MOBILE]], [
845
846            // Amazon
847            /(alexa)webm/i,
848            /(kf[a-z]{2}wi)( bui|\))/i,                                         // Kindle Fire without Silk
849            /(kf[a-z]+)( bui|\)).+silk\//i                                      // Kindle Fire HD
850        ], [MODEL, [VENDOR, AMAZON], [TYPE, TABLET]], [
851            /((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i                     // Fire Phone
852        ], [[MODEL, /(.+)/g, 'Fire Phone $1'], [VENDOR, AMAZON], [TYPE, MOBILE]], [
853
854            // BlackBerry
855            /(playbook);[-\w\),; ]+(rim)/i                                      // BlackBerry PlayBook
856        ], [MODEL, VENDOR, [TYPE, TABLET]], [
857            /\b((?:bb[a-f]|st[hv])100-\d)/i,
858            /\(bb10; (\w+)/i                                                    // BlackBerry 10
859        ], [MODEL, [VENDOR, BLACKBERRY], [TYPE, MOBILE]], [
860
861            // Asus
862            /(?:\b|asus_)(transfo[prime ]{4,10} \w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i
863        ], [MODEL, [VENDOR, ASUS], [TYPE, TABLET]], [
864            / (z[bes]6[027][012][km][ls]|zenfone \d\w?)\b/i
865        ], [MODEL, [VENDOR, ASUS], [TYPE, MOBILE]], [
866
867            // HTC
868            /(nexus 9)/i                                                        // HTC Nexus 9
869        ], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [
870            /(htc)[-;_ ]{1,2}([\w ]+(?=\)| bui)|\w+)/i,                         // HTC
871
872            // ZTE
873            /(zte)[- ]([\w ]+?)(?: bui|\/|\))/i,
874            /(alcatel|geeksphone|nexian|panasonic|sony(?!-bra))[-_ ]?([-\w]*)/i         // Alcatel/GeeksPhone/Nexian/Panasonic/Sony
875        ], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [
876
877            // Acer
878            /droid.+; ([ab][1-7]-?[0178a]\d\d?)/i
879        ], [MODEL, [VENDOR, 'Acer'], [TYPE, TABLET]], [
880
881            // Meizu
882            /droid.+; (m[1-5] note) bui/i,
883            /\bmz-([-\w]{2,})/i
884        ], [MODEL, [VENDOR, 'Meizu'], [TYPE, MOBILE]], [
885
886            // Sharp
887            /\b(sh-?[altvz]?\d\d[a-ekm]?)/i
888        ], [MODEL, [VENDOR, 'Sharp'], [TYPE, MOBILE]], [
889
890            // MIXED
891            /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron)[-_ ]?([-\w]*)/i,
892            // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron
893            /(hp) ([\w ]+\w)/i,                                                 // HP iPAQ
894            /(asus)-?(\w+)/i,                                                   // Asus
895            /(microsoft); (lumia[\w ]+)/i,                                      // Microsoft Lumia
896            /(lenovo)[-_ ]?([-\w]+)/i,                                          // Lenovo
897            /(jolla)/i,                                                         // Jolla
898            /(oppo) ?([\w ]+) bui/i                                             // OPPO
899        ], [VENDOR, MODEL, [TYPE, MOBILE]], [
900
901            /(archos) (gamepad2?)/i,                                            // Archos
902            /(hp).+(touchpad(?!.+tablet)|tablet)/i,                             // HP TouchPad
903            /(kindle)\/([\w\.]+)/i,                                             // Kindle
904            /(nook)[\w ]+build\/(\w+)/i,                                        // Nook
905            /(dell) (strea[kpr\d ]*[\dko])/i,                                   // Dell Streak
906            /(le[- ]+pan)[- ]+(\w{1,9}) bui/i,                                  // Le Pan Tablets
907            /(trinity)[- ]*(t\d{3}) bui/i,                                      // Trinity Tablets
908            /(gigaset)[- ]+(q\w{1,9}) bui/i,                                    // Gigaset Tablets
909            /(vodafone) ([\w ]+)(?:\)| bui)/i                                   // Vodafone
910        ], [VENDOR, MODEL, [TYPE, TABLET]], [
911
912            /(surface duo)/i                                                    // Surface Duo
913        ], [MODEL, [VENDOR, MICROSOFT], [TYPE, TABLET]], [
914            /droid [\d\.]+; (fp\du?)(?: b|\))/i                                 // Fairphone
915        ], [MODEL, [VENDOR, 'Fairphone'], [TYPE, MOBILE]], [
916            /(u304aa)/i                                                         // AT&T
917        ], [MODEL, [VENDOR, 'AT&T'], [TYPE, MOBILE]], [
918            /\bsie-(\w*)/i                                                      // Siemens
919        ], [MODEL, [VENDOR, 'Siemens'], [TYPE, MOBILE]], [
920            /\b(rct\w+) b/i                                                     // RCA Tablets
921        ], [MODEL, [VENDOR, 'RCA'], [TYPE, TABLET]], [
922            /\b(venue[\d ]{2,7}) b/i                                            // Dell Venue Tablets
923        ], [MODEL, [VENDOR, 'Dell'], [TYPE, TABLET]], [
924            /\b(q(?:mv|ta)\w+) b/i                                              // Verizon Tablet
925        ], [MODEL, [VENDOR, 'Verizon'], [TYPE, TABLET]], [
926            /\b(?:barnes[& ]+noble |bn[rt])([\w\+ ]*) b/i                       // Barnes & Noble Tablet
927        ], [MODEL, [VENDOR, 'Barnes & Noble'], [TYPE, TABLET]], [
928            /\b(tm\d{3}\w+) b/i
929        ], [MODEL, [VENDOR, 'NuVision'], [TYPE, TABLET]], [
930            /\b(k88) b/i                                                        // ZTE K Series Tablet
931        ], [MODEL, [VENDOR, 'ZTE'], [TYPE, TABLET]], [
932            /\b(nx\d{3}j) b/i                                                   // ZTE Nubia
933        ], [MODEL, [VENDOR, 'ZTE'], [TYPE, MOBILE]], [
934            /\b(gen\d{3}) b.+49h/i                                              // Swiss GEN Mobile
935        ], [MODEL, [VENDOR, 'Swiss'], [TYPE, MOBILE]], [
936            /\b(zur\d{3}) b/i                                                   // Swiss ZUR Tablet
937        ], [MODEL, [VENDOR, 'Swiss'], [TYPE, TABLET]], [
938            /\b((zeki)?tb.*\b) b/i                                              // Zeki Tablets
939        ], [MODEL, [VENDOR, 'Zeki'], [TYPE, TABLET]], [
940            /\b([yr]\d{2}) b/i,
941            /\b(dragon[- ]+touch |dt)(\w{5}) b/i                                // Dragon Touch Tablet
942        ], [[VENDOR, 'Dragon Touch'], MODEL, [TYPE, TABLET]], [
943            /\b(ns-?\w{0,9}) b/i                                                // Insignia Tablets
944        ], [MODEL, [VENDOR, 'Insignia'], [TYPE, TABLET]], [
945            /\b((nxa|next)-?\w{0,9}) b/i                                        // NextBook Tablets
946        ], [MODEL, [VENDOR, 'NextBook'], [TYPE, TABLET]], [
947            /\b(xtreme\_)?(v(1[045]|2[015]|[3469]0|7[05])) b/i                  // Voice Xtreme Phones
948        ], [[VENDOR, 'Voice'], MODEL, [TYPE, MOBILE]], [
949            /\b(lvtel\-)?(v1[12]) b/i                                           // LvTel Phones
950        ], [[VENDOR, 'LvTel'], MODEL, [TYPE, MOBILE]], [
951            /\b(ph-1) /i                                                        // Essential PH-1
952        ], [MODEL, [VENDOR, 'Essential'], [TYPE, MOBILE]], [
953            /\b(v(100md|700na|7011|917g).*\b) b/i                               // Envizen Tablets
954        ], [MODEL, [VENDOR, 'Envizen'], [TYPE, TABLET]], [
955            /\b(trio[-\w\. ]+) b/i                                              // MachSpeed Tablets
956        ], [MODEL, [VENDOR, 'MachSpeed'], [TYPE, TABLET]], [
957            /\btu_(1491) b/i                                                    // Rotor Tablets
958        ], [MODEL, [VENDOR, 'Rotor'], [TYPE, TABLET]], [
959            /(shield[\w ]+) b/i                                                 // Nvidia Shield Tablets
960        ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, TABLET]], [
961            /(sprint) (\w+)/i                                                   // Sprint Phones
962        ], [VENDOR, MODEL, [TYPE, MOBILE]], [
963            /(kin\.[onetw]{3})/i                                                // Microsoft Kin
964        ], [[MODEL, /\./g, ' '], [VENDOR, MICROSOFT], [TYPE, MOBILE]], [
965            /droid.+; (cc6666?|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i             // Zebra
966        ], [MODEL, [VENDOR, ZEBRA], [TYPE, TABLET]], [
967            /droid.+; (ec30|ps20|tc[2-8]\d[kx])\)/i
968        ], [MODEL, [VENDOR, ZEBRA], [TYPE, MOBILE]], [
969
970            ///////////////////
971            // CONSOLES
972            ///////////////////
973
974            /(ouya)/i,                                                          // Ouya
975            /(nintendo) ([wids3utch]+)/i                                        // Nintendo
976        ], [VENDOR, MODEL, [TYPE, CONSOLE]], [
977            /droid.+; (shield) bui/i                                            // Nvidia
978        ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, CONSOLE]], [
979            /(playstation [345portablevi]+)/i                                   // Playstation
980        ], [MODEL, [VENDOR, SONY], [TYPE, CONSOLE]], [
981            /\b(xbox(?: one)?(?!; xbox))[\); ]/i                                // Microsoft Xbox
982        ], [MODEL, [VENDOR, MICROSOFT], [TYPE, CONSOLE]], [
983
984            ///////////////////
985            // SMARTTVS
986            ///////////////////
987
988            /smart-tv.+(samsung)/i                                              // Samsung
989        ], [VENDOR, [TYPE, SMARTTV]], [
990            /hbbtv.+maple;(\d+)/i
991        ], [[MODEL, /^/, 'SmartTV'], [VENDOR, SAMSUNG], [TYPE, SMARTTV]], [
992            /(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i        // LG SmartTV
993        ], [[VENDOR, LG], [TYPE, SMARTTV]], [
994            /(apple) ?tv/i                                                      // Apple TV
995        ], [VENDOR, [MODEL, APPLE + ' TV'], [TYPE, SMARTTV]], [
996            /crkey/i                                                            // Google Chromecast
997        ], [[MODEL, CHROME + 'cast'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
998            /droid.+aft(\w)( bui|\))/i                                          // Fire TV
999        ], [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]], [
1000            /\(dtv[\);].+(aquos)/i                                              // Sharp
1001        ], [MODEL, [VENDOR, 'Sharp'], [TYPE, SMARTTV]], [
1002            /(bravia[\w- ]+) bui/i                                              // Sony
1003        ], [MODEL, [VENDOR, SONY], [TYPE, SMARTTV]], [
1004            /\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i,                          // Roku
1005            /hbbtv\/\d+\.\d+\.\d+ +\([\w ]*; *(\w[^;]*);([^;]*)/i               // HbbTV devices
1006        ], [[VENDOR, trim], [MODEL, trim], [TYPE, SMARTTV]], [
1007            /\b(android tv|smart[- ]?tv|opera tv|tv; rv:)\b/i                   // SmartTV from Unidentified Vendors
1008        ], [[TYPE, SMARTTV]], [
1009
1010            ///////////////////
1011            // WEARABLES
1012            ///////////////////
1013
1014            /((pebble))app/i                                                    // Pebble
1015        ], [VENDOR, MODEL, [TYPE, WEARABLE]], [
1016            /droid.+; (glass) \d/i                                              // Google Glass
1017        ], [MODEL, [VENDOR, GOOGLE], [TYPE, WEARABLE]], [
1018            /droid.+; (wt63?0{2,3})\)/i
1019        ], [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]], [
1020            /(quest( 2)?)/i                                                     // Oculus Quest
1021        ], [MODEL, [VENDOR, FACEBOOK], [TYPE, WEARABLE]], [
1022
1023            ///////////////////
1024            // EMBEDDED
1025            ///////////////////
1026
1027            /(tesla)(?: qtcarbrowser|\/[-\w\.]+)/i                              // Tesla
1028        ], [VENDOR, [TYPE, EMBEDDED]], [
1029
1030            ////////////////////
1031            // MIXED (GENERIC)
1032            ///////////////////
1033
1034            /droid .+?; ([^;]+?)(?: bui|\) applew).+? mobile safari/i           // Android Phones from Unidentified Vendors
1035        ], [MODEL, [TYPE, MOBILE]], [
1036            /droid .+?; ([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i       // Android Tablets from Unidentified Vendors
1037        ], [MODEL, [TYPE, TABLET]], [
1038            /\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i                      // Unidentifiable Tablet
1039        ], [[TYPE, TABLET]], [
1040            /(phone|mobile(?:[;\/]| safari)|pda(?=.+windows ce))/i              // Unidentifiable Mobile
1041        ], [[TYPE, MOBILE]], [
1042            /(android[-\w\. ]{0,9});.+buil/i                                    // Generic Android Device
1043        ], [MODEL, [VENDOR, 'Generic']]
1044        ],
1045
1046        engine: [[
1047
1048            /windows.+ edge\/([\w\.]+)/i                                       // EdgeHTML
1049        ], [VERSION, [NAME, EDGE + 'HTML']], [
1050
1051            /webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i                         // Blink
1052        ], [VERSION, [NAME, 'Blink']], [
1053
1054            /(presto)\/([\w\.]+)/i,                                             // Presto
1055            /(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna
1056            /ekioh(flow)\/([\w\.]+)/i,                                          // Flow
1057            /(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i,                           // KHTML/Tasman/Links
1058            /(icab)[\/ ]([23]\.[\d\.]+)/i                                       // iCab
1059        ], [NAME, VERSION], [
1060
1061            /rv\:([\w\.]{1,9})\b.+(gecko)/i                                     // Gecko
1062        ], [VERSION, NAME]
1063        ],
1064
1065        os: [[
1066
1067            // Windows
1068            /microsoft (windows) (vista|xp)/i                                   // Windows (iTunes)
1069        ], [NAME, VERSION], [
1070            /(windows) nt 6\.2; (arm)/i,                                        // Windows RT
1071            /(windows (?:phone(?: os)?|mobile))[\/ ]?([\d\.\w ]*)/i,            // Windows Phone
1072            /(windows)[\/ ]?([ntce\d\. ]+\w)(?!.+xbox)/i
1073        ], [NAME, [VERSION, strMapper, windowsVersionMap]], [
1074            /(win(?=3|9|n)|win 9x )([nt\d\.]+)/i
1075        ], [[NAME, 'Windows'], [VERSION, strMapper, windowsVersionMap]], [
1076
1077            // iOS/macOS
1078            /ip[honead]{2,4}\b(?:.*os ([\w]+) like mac|; opera)/i,              // iOS
1079            /cfnetwork\/.+darwin/i
1080        ], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [
1081            /(mac os x) ?([\w\. ]*)/i,
1082            /(macintosh|mac_powerpc\b)(?!.+haiku)/i                             // Mac OS
1083        ], [[NAME, 'Mac OS'], [VERSION, /_/g, '.']], [
1084
1085            // Mobile OSes
1086            /droid ([\w\.]+)\b.+(android[- ]x86)/i                              // Android-x86
1087        ], [VERSION, NAME], [                                               // Android/WebOS/QNX/Bada/RIM/Maemo/MeeGo/Sailfish OS
1088            /(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish)[-\/ ]?([\w\.]*)/i,
1089            /(blackberry)\w*\/([\w\.]*)/i,                                      // Blackberry
1090            /(tizen|kaios)[\/ ]([\w\.]+)/i,                                     // Tizen/KaiOS
1091            /\((series40);/i                                                    // Series 40
1092        ], [NAME, VERSION], [
1093            /\(bb(10);/i                                                        // BlackBerry 10
1094        ], [VERSION, [NAME, BLACKBERRY]], [
1095            /(?:symbian ?os|symbos|s60(?=;)|series60)[-\/ ]?([\w\.]*)/i         // Symbian
1096        ], [VERSION, [NAME, 'Symbian']], [
1097            /mozilla\/[\d\.]+ \((?:mobile|tablet|tv|mobile; [\w ]+); rv:.+ gecko\/([\w\.]+)/i // Firefox OS
1098        ], [VERSION, [NAME, FIREFOX + ' OS']], [
1099            /web0s;.+rt(tv)/i,
1100            /\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i                              // WebOS
1101        ], [VERSION, [NAME, 'webOS']], [
1102
1103            // Google Chromecast
1104            /crkey\/([\d\.]+)/i                                                 // Google Chromecast
1105        ], [VERSION, [NAME, CHROME + 'cast']], [
1106            /(cros) [\w]+ ([\w\.]+\w)/i                                         // Chromium OS
1107        ], [[NAME, 'Chromium OS'], VERSION], [
1108
1109            // Console
1110            /(nintendo|playstation) ([wids345portablevuch]+)/i,                 // Nintendo
1110/Playstation
1111            /(xbox); +xbox ([^\);]+)/i,                                         // Microsoft Xbox (360, One, X, S, Series X, Series S)
1112
1113            // Other
1114            /\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i,                            // Joli/Palm
1115            /(mint)[\/\(\) ]?(\w*)/i,                                           // Mint
1116            /(mageia|vectorlinux)[; ]/i,                                        // Mageia/VectorLinux
1117            /([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,
1118            // Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware/Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus/Raspbian/Plan9/Minix/RISCOS/Contiki/Deepin/Manjaro/elementary/Sabayon/Linspire
1119            /(hurd|linux) ?([\w\.]*)/i,                                         // Hurd/Linux
1120            /(gnu) ?([\w\.]*)/i,                                                // GNU
1121            /\b([-frentopcghs]{0,5}bsd|dragonfly)[\/ ]?(?!amd|[ix346]{1,2}86)([\w\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/GhostBSD/DragonFly
1122            /(haiku) (\w+)/i                                                    // Haiku
1123        ], [NAME, VERSION], [
1124            /(sunos) ?([\w\.\d]*)/i                                             // Solaris
1125        ], [[NAME, 'Solaris'], VERSION], [
1126            /((?:open)?solaris)[-\/ ]?([\w\.]*)/i,                              // Solaris
1127            /(aix) ((\d)(?=\.|\)| )[\w\.])*/i,                                  // AIX
1128            /\b(beos|os\/2|amigaos|morphos|openvms|fuchsia|hp-ux)/i,            // BeOS/OS2/AmigaOS/MorphOS/OpenVMS/Fuchsia/HP-UX
1129            /(unix) ?([\w\.]*)/i                                                // UNIX
1130        ], [NAME, VERSION]
1131        ]
1132    };
1133
1134    /////////////////
1135    // Constructor
1136    ////////////////
1137
1138    var UAParser = function (ua, extensions) {
1139
1140        if (typeof ua === OBJ_TYPE) {
1141            extensions = ua;
1142            ua = undefined;
1143        }
1144
1145        if (!(this instanceof UAParser)) {
1146            return new UAParser(ua, extensions).getResult();
1147        }
1148
1149        var _ua = ua || ((typeof window !== UNDEF_TYPE && window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : EMPTY);
1150        var _rgxmap = extensions ? extend(regexes, extensions) : regexes;
1151
1152        this.getBrowser = function () {
1153            var _browser = {};
1154            _browser[NAME] = undefined;
1155            _browser[VERSION] = undefined;
1156            rgxMapper.call(_browser, _ua, _rgxmap.browser);
1157            _browser.major = majorize(_browser.version);
1158            return _browser;
1159        };
1160        this.getCPU = function () {
1161            var _cpu = {};
1162            _cpu[ARCHITECTURE] = undefined;
1163            rgxMapper.call(_cpu, _ua, _rgxmap.cpu);
1164            return _cpu;
1165        };
1166        this.getDevice = function () {
1167            var _device = {};
1168            _device[VENDOR] = undefined;
1169            _device[MODEL] = undefined;
1170            _device[TYPE] = undefined;
1171            rgxMapper.call(_device, _ua, _rgxmap.device);
1172            return _device;
1173        };
1174        this.getEngine = function () {
1175            var _engine = {};
1176            _engine[NAME] = undefined;
1177            _engine[VERSION] = undefined;
1178            rgxMapper.call(_engine, _ua, _rgxmap.engine);
1179            return _engine;
1180        };
1181        this.getOS = function () {
1182            var _os = {};
1183            _os[NAME] = undefined;
1184            _os[VERSION] = undefined;
1185            rgxMapper.call(_os, _ua, _rgxmap.os);
1186            return _os;
1187        };
1188        this.getResult = function () {
1189            return {
1190                ua: this.getUA(),
1191                browser: this.getBrowser(),
1192                engine: this.getEngine(),
1193                os: this.getOS(),
1194                device: this.getDevice(),
1195                cpu: this.getCPU()
1196            };
1197        };
1198        this.getUA = function () {
1199            return _ua;
1200        };
1201        this.setUA = function (ua) {
1202            _ua = (typeof ua === STR_TYPE && ua.length > UA_MAX_LENGTH) ? trim(ua, UA_MAX_LENGTH) : ua;
1203            return this;
1204        };
1205        this.setUA(_ua);
1206        return this;
1207    };
1208
1209    UAParser.VERSION = LIBVERSION;
1210    UAParser.BROWSER = enumerize([NAME, VERSION, MAJOR]);
1211    UAParser.CPU = enumerize([ARCHITECTURE]);
1212    UAParser.DEVICE = enumerize([MODEL, VENDOR, TYPE, CONSOLE, MOBILE, SMARTTV, TABLET, WEARABLE, EMBEDDED]);
1213    UAParser.ENGINE = UAParser.OS = enumerize([NAME, VERSION]);
1214
1215    ///////////
1216    // Export
1217    //////////
1218
1219    // check js environment
1220    if (typeof (exports) !== UNDEF_TYPE) {
1221        // nodejs env
1222        if (typeof module !== UNDEF_TYPE && module.exports) {
1223            exports = module.exports = UAParser;
1224        }
1225        exports.UAParser = UAParser;
1226    } else {
1227        // requirejs env (optional)
1228        if (typeof (define) === FUNC_TYPE && define.amd) {
1229            define(function () {
1230                return UAParser;
1231            });
1232        } else if (typeof window !== UNDEF_TYPE) {
1233            // browser env
1234            window.UAParser = UAParser;
1235        }
1236    }
1237
1238    // jQuery/Zepto specific (optional)
1239    // Note:
1240    //   In AMD env the global scope should be kept clean, but jQuery is an exception.
1241    //   jQuery always exports to global scope, unless jQuery.noConflict(true) is used,
1242    //   and we should catch that.
1243    var $ = typeof window !== UNDEF_TYPE && (window.jQuery || window.Zepto);
1244    if ($ && !$.ua) {
1245        var parser = new UAParser();
1246        $.ua = parser.getResult();
1247        $.ua.get = function () {
1248            return parser.getUA();
1249        };
1250        $.ua.set = function (ua) {
1251            parser.setUA(ua);
1252            var result = parser.getResult();
1253            for (var prop in result) {
1254                $.ua[prop] = result[prop];
1255            }
1256        };
1257    }
1258
1259})(typeof window === 'object' ? window : this);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.