diff --git a/data/browsers-chrome.php b/data/browsers-chrome.php index 3e8ef9e..4afce43 100644 --- a/data/browsers-chrome.php +++ b/data/browsers-chrome.php @@ -3,9 +3,9 @@ namespace WhichBrowser\Data; Chrome::$DESKTOP = [ - '0.2.149' => 'stable', - '0.3.154' => 'stable', - '0.4.154' => 'stable', + '0.2.149' => 'beta', + '0.3.154' => 'beta', + '0.4.154' => 'beta', '1.0.154' => 'stable', '2.0.172' => 'stable', '3.0.195' => 'stable', diff --git a/data/id-android.php b/data/id-android.php index c05cb81..8780e1d 100644 --- a/data/id-android.php +++ b/data/id-android.php @@ -7,25 +7,24 @@ BrowserIds::$ANDROID_BROWSERS = [ 'com.agilebits.onepassword' => '1Password', 'com.browser2345' => '2345 Browser', + 'com.browser2345_ucc' => '2345 Browser', 'com.browser2345hd' => '2345 Browser HD', - 'com.qihoa.browser' => '360 Phone Browser', - 'com.qihoo.androidbrowser' => '360 Phone Browser', - 'com.qihoo.appstore' => '360 Phone Browser', - 'com.qihoo.browser' => '360 Phone Browser', - 'com.qihoo.browsertest' => '360 Phone Browser', - 'com.qihoo.express.browser' => '360 Phone Browser', - 'com.qihoo.expressbrowser' => '360 Phone Browser', - 'com.qihoo.haosou' => '360 Phone Browser', - 'com.qihoo.padbrowser' => '360 Phone Browser', - 'com.qihoo.padbrowser7' => '360 Phone Browser', - 'com.qihoo360.mobilesafe' => '360 Phone Browser', - 'com.qihoo360.mobilesafe_meizu' => '360 Phone Browser', - 'com.qihoo360.mobilesafe_mtk6573' => '360 Phone Browser', + 'air.stage.web.view' => 'Adobe AIR', + 'air.stagewebview' => 'Adobe AIR', + 'air.StageWebViewBridgeTest.debug' => 'Adobe AIR', + 'air.StageWebViewVideo.debug' => 'Adobe AIR', + 'com.adobe.phonegap.app' => 'Adobe Phonegap', + 'com.adobe.reader' => 'Adobe Reader', + 'com.adobe.shadow.android' => 'Adobe Shadow', + 'com.airwatch.browser' => 'AirWatch Browser', 'com.aliyun.mobile.browser' => 'Aliyun Browser', 'net.adgjm.angel' => 'Angel Browser', 'com.apc.browser' => 'APC', 'com.apc.browser.standard' => 'APC', 'com.apc.browser.standard6j8s' => 'APC', + 'com.apusapps.browser' => 'APUS Browser', + 'com.apusapps.browser.lark' => 'APUS Browser', + 'com.apusapps.browser.turbo' => 'APUS Browser', 'com.asus.browser' => 'Asus Browser', 'com.wAuroraWebBrowser' => 'Aurora Web Browser', 'bdmobile.android.app' => 'Baidu Browser', @@ -34,15 +33,21 @@ 'com.baidu.browser.apps' => 'Baidu Browser', 'com.baidu.browser.apps.lite' => 'Baidu Browser', 'com.baidu.browser.apps_mr' => 'Baidu Browser', + 'com.baidu.browser.apps_neo' => 'Baidu Browser', 'com.baidu.browser.apps_sj' => 'Baidu Browser', + 'com.baidu.browser.apps_yt' => 'Baidu Browser', 'com.baidu.browser.app_bw' => 'Baidu Browser', + 'com.baidu.browser.blink.apps' => 'Baidu Browser', 'com.baidu.browser.brower' => 'Baidu Browser', 'com.baidu.browser.chrome' => 'Baidu Browser', 'com.baidu.browser.inter' => 'Baidu Browser', + 'com.baidu.browser.inter.mini' => 'Baidu Browser', + 'com.baidu.browser.interyb' => 'Baidu Browser', 'com.baidu.browser.lab' => 'Baidu Browser', 'com.baidu.browser.pad' => 'Baidu Browser', 'com.baidu.browserhd.inter' => 'Baidu Browser', 'com.baidu.demo.webview' => 'Baidu Browser', + 'com.baidu.hi' => 'Baidu Browser', 'com.baidu.searchbox' => 'Baidu Browser', 'com.baidu.searchbox.pad' => 'Baidu Browser', 'com.baidu.searchbox_bbk' => 'Baidu Browser', @@ -51,8 +56,10 @@ 'com.baidu.searchbox_hisense' => 'Baidu Browser', 'com.baidu.searchbox_htc' => 'Baidu Browser', 'com.baidu.searchbox_huawei' => 'Baidu Browser', + 'com.baidu.searchbox_ktouch' => 'Baidu Browser', 'com.baidu.searchbox_lenovo' => 'Baidu Browser', 'com.baidu.searchbox_oppo' => 'Baidu Browser', + 'com.baidu.searchbox_samsung' => 'Baidu Browser', 'com.baidu.searchbox_sj' => 'Baidu Browser', 'com.baidu.searchbox_sony' => 'Baidu Browser', 'com.baidu.searchbox_tianyi' => 'Baidu Browser', @@ -65,17 +72,23 @@ 'com.ericsson.research.mario' => 'Bowser', 'com.dotsandlines.carbon' => 'Carbon', 'app.chameleon_browser' => 'Chameleon browser', + 'com.coship.mmcp' => 'Coship MMCP', + 'com.coship.tvos.web' => 'Coship MMCP', + 'com.coship.webapp' => 'Coship MMCP', 'net.daum.android.daum' => 'Daum', 'com.phikod.deviceportinfo' => 'Device Info Android', 'com.dolphin.browser.android.jp' => 'Dolphin', + 'com.dolphin.browser.id' => 'Dolphin', 'com.dolphin.browser.pad' => 'Dolphin', 'com.dolphin.browser.tuna' => 'Dolphin', + 'com.dolphin.web.browser.android' => 'Dolphin', 'mobi.mgeek.TunnyBrowser' => 'Dolphin', 'mobile.mgeek.TunnyBrowser' => 'Dolphin', 'com.dolphin.browser.xf' => 'Dolphin (Fighter Edition)', 'com.dolphin.browser.lab.cn' => 'Dolphin Beta', 'com.dolphin.browser.lab.en' => 'Dolphin Beta', 'com.dolphin.browser.express.web' => 'Dolphin Express', + 'com.dolphin.browser.express.web.beta' => 'Dolphin Express', 'com.dolphin.browser' => 'Dolphin Mini', 'com.dolphin.browser.cn' => 'Dolphin Mini', 'com.dolphin.browser.zero' => 'Dolphin Zero', @@ -121,6 +134,7 @@ 'nu.tommie.inbrowser' => 'InBrowser', 'nu.tommie.inbrowser.beta' => 'InBrowser Beta', 'com.infamous.browser' => 'Infamous Browser', + 'derek.iSurf' => 'iSurf', 'com.jerky.browser' => 'Javelin Incognito Browser', 'com.jerky.browser2' => 'Javelin Incognito Browser', 'com.adsi.kioware.client.mobile.app' => 'KioWare Kiosk', @@ -132,8 +146,13 @@ 'com.lenovo.lps.simple' => 'Lenovo Browser', 'com.light.browser' => 'Light Browser', 'acr.browser.barebones' => 'Lightning Browser', + 'acr.browser.butterfly' => 'Lightning Browser', + 'acr.browser.lightning' => 'Lightning Browser', + 'acr.browser.lightning2' => 'Lightning Browser', 'acr.browser.lightningq16w' => 'Lightning Browser', - 'acr.browser.lightning' => 'Lightning Browser+', + 'acr.browser.spartancompany' => 'Lightning Browser', + 'acr.browser.spartancompanypaid' => 'Lightning Browser', + 'acr.browser.thunder' => 'Lightning Browser', 'com.MoNTE.Lime' => 'Lime', 'com.alphonso.pulse' => 'LinkedIn Pulse', 'com.logio.logos' => 'Logos Browser', @@ -164,6 +183,7 @@ 'jp.co.inos.c1Browser' => 'MDM Browser', 'com.ilegendsoft.mercury' => 'Mercury', 'com.dmkho.mbm' => 'MiniBrowser Mobile', + 'com.dmkho.mbmbeta' => 'MiniBrowser Mobile', 'com.mseven.msecure' => 'mSecure', 'com.visvanoid.secretbrowse' => 'My Internet', 'com.fevdev.nakedbrowser' => 'Naked Browser', @@ -188,6 +208,8 @@ 'com.browser.nowadvanced' => 'Now Browser', 'com.browser.nowbasic' => 'Now Browser', 'com.browser.nowpro' => 'Now Browser', + 'com.browser.nowpro412t' => 'Now Browser', + 'com.wNewVisionBrowser' => 'NVision Browser', 'com.compal.android.browser' => 'Ocean Browser', 'com.maskyn.oldbrowser' => 'Old But Gold Internet Browser', 'com.tencent.ibibo.mtt' => 'One Browser', @@ -211,6 +233,19 @@ 'com.hat.privatebrowser' => 'Private Browser', 'com.JamesBecwar.FreePrivateBrowser' => 'Private Browser', 'com.JamesBecwar.PrivateBrowser' => 'Private Browser', + 'com.qihoa.browser' => 'Qihoo 360 Browser', + 'com.qihoo.androidbrowser' => 'Qihoo 360 Browser', + 'com.qihoo.appstore' => 'Qihoo 360 Browser', + 'com.qihoo.browser' => 'Qihoo 360 Browser', + 'com.qihoo.browsertest' => 'Qihoo 360 Browser', + 'com.qihoo.express.browser' => 'Qihoo 360 Browser', + 'com.qihoo.expressbrowser' => 'Qihoo 360 Browser', + 'com.qihoo.haosou' => 'Qihoo 360 Browser', + 'com.qihoo.padbrowser' => 'Qihoo 360 Browser', + 'com.qihoo.padbrowser7' => 'Qihoo 360 Browser', + 'com.qihoo360.mobilesafe' => 'Qihoo 360 Browser', + 'com.qihoo360.mobilesafe_meizu' => 'Qihoo 360 Browser', + 'com.qihoo360.mobilesafe_mtk6573' => 'Qihoo 360 Browser', 'com.tencent.android.pad' => 'QQ Browser', 'com.tencent.blink' => 'QQ Browser', 'com.tencent.hd.qq' => 'QQ Browser', @@ -248,6 +283,7 @@ 'jp.co.fenrir.android.sleipnir_ngp' => 'Sleipnir', 'jp.co.fenrir.android.sleipnir_test' => 'Sleipnir', 'jp.gocro.smartnews.android' => 'SmartNews', + 'com.cmcc.sofabrowser' => 'Sofa Browser', 'sogou.mobile.explorer' => 'Sogou Mobile', 'com.solo.browser' => 'Solo', 'com.sonymobile.smallbrowser' => 'Sony Small Browser', diff --git a/data/models-android.php b/data/models-android.php index dcea159..ceef210 100644 --- a/data/models-android.php +++ b/data/models-android.php @@ -519,6 +519,7 @@ 'Z160' => [ 'Acer', 'Liquid Z4' ], 'Z4' => [ 'Acer', 'Liquid Z4' ], 'Z200' => [ 'Acer', 'Liquid Z200' ], + 'Z205' => [ 'Acer', 'Liquid Z205' ], 'Z220' => [ 'Acer', 'Liquid Z220' ], 'Z410' => [ 'Acer', 'Liquid Z410' ], 'Z500' => [ 'Acer', 'Liquid Z500' ], @@ -577,6 +578,7 @@ 'T1-E' => [ 'Advan', 'Vandroid T1-E', DeviceType::TABLET ], 'ADVAN T1G' => [ 'Advan', 'Vandroid T1-G', DeviceType::TABLET ], 'ADVAN T1J' => [ 'Advan', 'Vandroid T1-J', DeviceType::TABLET ], + 'Vandroid T1J' => [ 'Advan', 'Vandroid T1-J', DeviceType::TABLET ], 'ADVAN T1J+' => [ 'Advan', 'Vandroid T1-J+', DeviceType::TABLET ], 'T1K Plus' => [ 'Advan', 'Vandroid T1-K Plus', DeviceType::TABLET ], 'ADVAN T1L' => [ 'Advan', 'Vandroid T1-L', DeviceType::TABLET ], @@ -769,7 +771,7 @@ '5042[ADEFGTWXY]!' => [ 'Alcatel', 'One Touch Pop 2 (4.5)' ], 'one ?touch 5050!' => [ 'Alcatel', 'One Touch Pop S3' ], '5050[ASYX]!' => [ 'Alcatel', 'One Touch Pop S3' ], - '5054[O]!' => [ 'Alcatel', 'One Touch Pixi 3 (5.5)' ], + '5054[OX]!' => [ 'Alcatel', 'One Touch Pixi 3 (5.5)' ], '5054[NW]!' => [ 'Alcatel', 'One Touch Fierce XL' ], '5065[ADJWX]!' => [ 'Alcatel', 'One Touch Pixi 3 (5)' ], 'one ?touch 6010!' => [ 'Alcatel', 'One Touch Star' ], @@ -918,7 +920,7 @@ 'AT107F' => [ 'Aluratek', 'Cinepad AT107F', DeviceType::TABLET ], 'AT108F' => [ 'Aluratek', 'Cinepad AT108F', DeviceType::TABLET ], 'AT197F' => [ 'Aluratek', 'Cinepad AT197F', DeviceType::TABLET ], - '(Amazon )?Kindle Fire!' => [ 'Amazon', 'Kindle Fire', DeviceType::TABLET ], // 1st generation or unknown variant using unofficial firmware + 'Amazon Kindle Fire!' => [ 'Amazon', 'Kindle Fire', DeviceType::TABLET ], // 1st generation or unknown variant using unofficial firmware 'Amazon Otter' => [ 'Amazon', 'Kindle Fire', DeviceType::TABLET ], // "Otter" 1st generation 7" (1024 x 600) 'Amazon OtterX' => [ 'Amazon', 'Kindle Fire', DeviceType::TABLET ], // "Otter" 1st generation 7" (1024 x 600) 'Amazon Otter2' => [ 'Amazon', 'Kindle Fire', DeviceType::TABLET ], // "Otter2" 2nd generation 7" (1024 x 600) @@ -927,7 +929,8 @@ 'soho' => [ 'Amazon', 'Kindle Fire HD (2013)', DeviceType::TABLET ], // "Soho" 3rd generation 7" HD (1280 x 800) 'thor' => [ 'Amazon', 'Kindle Fire HDX', DeviceType::TABLET ], // "Thor" 3rd generation 7" HDX (1920 x 1200) 'apollo' => [ 'Amazon', 'Kindle Fire HDX 8.9"', DeviceType::TABLET ], // "Apollo" 3rd generation 8.9" HDX (2560 x 1600) - 'KFOTE?!' => [ 'Amazon', 'Kindle Fire', DeviceType::TABLET, Flag::FIREOS ], // "Otter" 1st or 2nd generation 7" (1024 x 600) + 'Kindle Fire' => [ 'Amazon', 'Kindle Fire', DeviceType::TABLET, Flag::FIREOS ], // "Otter" 1st generation 7" (1024 x 600) + 'KFOTE?!' => [ 'Amazon', 'Kindle Fire', DeviceType::TABLET, Flag::FIREOS ], // "Otter2" 2nd generation 7" (1024 x 600) 'KFTT' => [ 'Amazon', 'Kindle Fire HD', DeviceType::TABLET, Flag::FIREOS ], // "Tate" 2nd generation 7" HD (1280 x 800) 'KFJW(I|A)!' => [ 'Amazon', 'Kindle Fire HD 8.9"', DeviceType::TABLET, Flag::FIREOS ], // "Jem" 2nd generation 8.9" HD (1920 x 1200) 'KFJMWI' => [ 'Amazon', 'Kindle Fire', DeviceType::TABLET, Flag::FIREOS ], // 3rd generation (1280 x 800) @@ -2380,8 +2383,12 @@ 'U25GT-C4' => [ 'Cube', 'U25GT C4', DeviceType::TABLET ], 'U25GT-C4W' => [ 'Cube', 'U25GT C4W', DeviceType::TABLET ], 'U25GT-C4WB' => [ 'Cube', 'U25GT C4WB', DeviceType::TABLET ], + 'U25GT-C4Y' => [ 'Cube', 'U25GT C4Y', DeviceType::TABLET ], 'U25GT2-H' => [ 'Cube', 'U25GT2 H', DeviceType::TABLET ], 'U27GT' => [ 'Cube', 'U27GT', DeviceType::TABLET ], + 'U27GT-C8' => [ 'Cube', 'U27GT C8', DeviceType::TABLET ], + 'U27GT-C8P' => [ 'Cube', 'U27GT C8P', DeviceType::TABLET ], + 'U27GT-SD' => [ 'Cube', 'U27GT SD', DeviceType::TABLET ], 'U28GT' => [ 'Cube', 'U28GT', DeviceType::TABLET ], 'U30GT' => [ 'Cube', 'U30GT', DeviceType::TABLET ], 'U30GT C4' => [ 'Cube', 'U30GT C4', DeviceType::TABLET ], @@ -2397,19 +2404,25 @@ 'U30GT 2' => [ 'Cube', 'U30GT2', DeviceType::TABLET ], 'U30GT-2' => [ 'Cube', 'U30GT2', DeviceType::TABLET ], 'U30GT 2MH' => [ 'Cube', 'U30GT2 MH', DeviceType::TABLET ], + 'U31GT' => [ 'Cube', 'U31GT', DeviceType::TABLET ], 'U35GT' => [ 'Cube', 'U35GT', DeviceType::TABLET ], 'U35GT-W' => [ 'Cube', 'U35GT W', DeviceType::TABLET ], 'U35GT2' => [ 'Cube', 'U35GT2', DeviceType::TABLET ], 'U39GT' => [ 'Cube', 'U39GT', DeviceType::TABLET ], + 'U39GT-W' => [ 'Cube', 'U39GT W', DeviceType::TABLET ], 'U39GT-3G' => [ 'Cube', 'U39GT 3G', DeviceType::TABLET ], 'U51GT' => [ 'Cube', 'U51GT', DeviceType::TABLET ], 'U51GT-S' => [ 'Cube', 'U51GT S', DeviceType::TABLET ], 'U51GT-W' => [ 'Cube', 'U51GT W', DeviceType::TABLET ], 'U51GT C4' => [ 'Cube', 'U51GT C4', DeviceType::TABLET ], + 'U51GT-C4' => [ 'Cube', 'U51GT C4', DeviceType::TABLET ], 'U51GT-C4B' => [ 'Cube', 'U51GT C4B', DeviceType::TABLET ], 'U51GT-C4BD' => [ 'Cube', 'U51GT C4BD', DeviceType::TABLET ], 'U51GT-C8' => [ 'Cube', 'U51GT C8', DeviceType::TABLET ], + 'U51GT-C8S' => [ 'Cube', 'U51GT C8S', DeviceType::TABLET ], 'U55GT' => [ 'Cube', 'U55GT', DeviceType::TABLET ], + 'U55GT C8' => [ 'Cube', 'U55GT C8', DeviceType::TABLET ], + 'U55GT S' => [ 'Cube', 'U55GT S', DeviceType::TABLET ], 'U59GT-C4' => [ 'Cube', 'U59GT C4', DeviceType::TABLET ], 'U65GT' => [ 'Cube', 'U65GT', DeviceType::TABLET ], ], @@ -4429,6 +4442,7 @@ 'MT2L03' => [ 'Huawei', 'Ascend Mate 2' ], 'HUAWEI MT7-(L09|J1|CL00|TL00|TL10|UL00)!' => [ 'Huawei', 'Ascend Mate 7' ], 'Z100-(L09|TL00)!' => [ 'Huawei', 'Ascend Mate 7' ], + 'HUAWEI NXT-AL10' => [ 'Huawei', 'Mate 8' ], 'M200-(UL00)!' => [ 'Huawei', 'Mate 8' ], 'unknown M200-L09' => [ 'Huawei', 'Mate 8' ], 'HUAWEI CRR-(L09|CL00|UL00|UL20)!' => [ 'Huawei', 'Mate S' ], @@ -4479,7 +4493,7 @@ 'HUAWEI U8951!' => [ 'Huawei', 'Ascend G510' ], 'Huawei ?U9000!' => [ 'Huawei', 'Ascend X' ], 'TIT-(AL00)!' => [ 'Huawei', 'Enjoy 5' ], - 'HUAWEI TIT-(AL00|U02)!' => [ 'Huawei', 'Enjoy 5' ], + 'HUAWEI TIT-(AL00|CL10|U02)!' => [ 'Huawei', 'Enjoy 5' ], 'HUAWEI HONOR 2' => [ 'Huawei', 'Honor 2' ], 'Huawei U9508' => [ 'Huawei', 'Honor 2' ], 'Huawei ?U9508!' => [ 'Huawei', 'Honor 2 Quad-core' ], @@ -4496,8 +4510,8 @@ 'Honor3c2G-T' => [ 'Huawei', 'Honor 3C' ], 'HUAWEI Honor 3c w' => [ 'Huawei', 'Honor 3C' ], 'CHM-(CL00|TL00H|TL00|U01|UL00)!' => [ 'Huawei', 'Honor Play 4C' ], - 'SCL-(L001|L004|AL00|CL00|TL00H)!' => [ 'Huawei', 'Honor 4A' ], - 'HUAWEI SCL-(L03|L04)!' => [ 'Huawei', 'Honor 4A' ], + 'SCL-(L01|L04|L001|L004|AL00|CL00|TL00|TL00H)!' => [ 'Huawei', 'Honor 4A' ], + 'HUAWEI SCL-(L02|L03|L04|L21|TL00)!' => [ 'Huawei', 'Honor 4A' ], 'CHE-(TL00|TL00H)!' => [ 'Huawei', 'Honor 4X' ], 'HW-Che1-CL10' => [ 'Huawei', 'Honor 4X' ], 'Che1-(L04|CL10|CL20)!' => [ 'Huawei', 'Honor 4X' ], @@ -4770,8 +4784,16 @@ 'Neon9' => [ 'i-Joy', 'Neon9', DeviceType::TABLET ], 'Planet II v2' => [ 'i-Joy', 'Planet II', DeviceType::TABLET ], 'Sygnus' => [ 'i-Joy', 'Sygnus', DeviceType::TABLET ], - 'MBR-1100' => [ 'iAdea', 'MBR-1100', DeviceType::SIGNAGE ], - 'XDS-0548' => [ 'iAdea', 'XDS-0548', DeviceType::SIGNAGE ], + 'NMP-302w' => [ 'IAdea', 'MBR-1100', DeviceType::SIGNAGE ], + 'MBR-1100' => [ 'IAdea', 'MBR-1100', DeviceType::SIGNAGE ], + 'XDK-1160' => [ 'IAdea', 'XDK-1160', DeviceType::SIGNAGE ], + 'XDK-1560' => [ 'IAdea', 'XDK-1560', DeviceType::SIGNAGE ], + 'XDS-0548' => [ 'IAdea', 'XDS-0548', DeviceType::SIGNAGE ], + 'XDS-1078' => [ 'IAdea', 'XDS-1078', DeviceType::SIGNAGE ], + 'XDS-2370' => [ 'IAdea', 'XDS-2370', DeviceType::SIGNAGE ], + 'XMP-6200' => [ 'IAdea', 'XMP-6200', DeviceType::SIGNAGE ], + 'XMP-6400' => [ 'IAdea', 'XMP-6400', DeviceType::SIGNAGE ], + 'XMP-7300' => [ 'IAdea', 'XMP-7300', DeviceType::SIGNAGE ], '(iBall )?Andi!!' => [ 'Andi3n' => [ 'iBall', 'Andi 3n' ], @@ -6657,6 +6679,7 @@ 'LG-ANDROID MINI BOX' => [ 'LG', 'Android Mini-Box', DeviceType::TELEVISION ], 'SH940C-LN' => [ 'LG', 'Smartbox HD', DeviceType::TELEVISION ], + 'SH940C-LN TV' => [ 'LG', 'Smartbox HD', DeviceType::TELEVISION ], 'TI320-DU' => [ 'LG', 'U+ tv G', DeviceType::TELEVISION, Flag::GOOGLETV ], 'TI320-DU TV' => [ 'LG', 'U+ tv G', DeviceType::TELEVISION, Flag::GOOGLETV ], 'SFR-G8800' => [ 'LG', 'SFR-G8800', DeviceType::TELEVISION, Flag::GOOGLETV ], @@ -7322,7 +7345,7 @@ 'XT1115!' => [ 'Motorola', 'Moto X Pro' ], 'XT1225' => [ 'Motorola', 'Moto Maxx' ], 'XT12(50|54)!' => [ 'Motorola', 'Droid Turbo' ], - 'XT15(24|26|27|28)!' => [ 'Motorola', 'Moto E (2015)' ], + 'XT15(23|24|26|27|28)!' => [ 'Motorola', 'Moto E (2015)' ], 'XT15(40|41|42|43|44|48|50)!' => [ 'Motorola', 'Moto G (2015)' ], 'XT15(62|63)!' => [ 'Motorola', 'Moto X Play' ], 'XT1565' => [ 'Motorola', 'Droid MAXX 2' ], @@ -9189,10 +9212,11 @@ 'SM-A[0-9]{3,3}!!' => [ 'SM-A300!' => [ 'Samsung', 'Galaxy A3' ], - 'SM-A310!' => [ 'Samsung', 'SM-A310' ], // Unannounced updated A3 + 'SM-A310!' => [ 'Samsung', 'Galaxy A3 (2015)' ], 'SM-A500!' => [ 'Samsung', 'Galaxy A5' ], - 'SM-A510!' => [ 'Samsung', 'SM-A510' ], // Unannounced updated A5 + 'SM-A510!' => [ 'Samsung', 'Galaxy A5 (2015)' ], 'SM-A700!' => [ 'Samsung', 'Galaxy A7' ], + 'SM-A710!' => [ 'Samsung', 'Galaxy A7 (2015)' ], 'SM-A800!' => [ 'Samsung', 'Galaxy A8' ], ], @@ -9262,6 +9286,7 @@ 'SM-G9098!' => [ 'Samsung', 'Galaxy G9098' ], 'SM-G909D' => [ 'Samsung', 'Galaxy S5' ], // Chinese dual sim variant 'SM-G910!' => [ 'Samsung', 'Galaxy Round' ], + 'SM-G919!' => [ 'Samsung', 'SM-G9198' ], 'SM-G920!' => [ 'Samsung', 'Galaxy S6' ], 'SM-G925!' => [ 'Samsung', 'Galaxy S6 Edge' ], 'SM-G928!' => [ 'Samsung', 'Galaxy S6 Edge+' ], @@ -9341,6 +9366,7 @@ 'SM-W[0-9]{4,4}!!' => [ 'SM-W2014' => [ 'Samsung', 'Galaxy W2014' ], 'SM-W2015' => [ 'Samsung', 'Galaxy Golden 2' ], + 'SM-W2016' => [ 'Samsung', 'Galaxy Golden 3' ], ], 'SPH-D[0-9]{3,3}!!' => [ @@ -9612,6 +9638,7 @@ 'SH-02D' => [ 'Sharp', 'Aquos slider SH-02D' ], 'SH-02E' => [ 'Sharp', 'Aquos Zeta SH-02E' ], 'SH-02F' => [ 'Sharp', 'Aquos EX SH-02F' ], + 'SH-02H' => [ 'Sharp', 'Aquos Compact SH-02H' ], 'SH-03C' => [ 'Sharp', 'Lynx 3D' ], 'SH-03F' => [ 'Sharp', 'SH-03F' ], 'SH-03G' => [ 'Sharp', 'Aquos Zeta SH-03G' ], @@ -9797,9 +9824,11 @@ 'Sonim XP5700' => [ 'Sonim', 'XP5700' ], 'Sonim-XP5700' => [ 'Sonim', 'XP5700' ], 'Sonim-XP6700' => [ 'Sonim', 'XP6700' ], + 'sonim/XP6700' => [ 'Sonim', 'XP6700' ], 'Sonim XP6711Z1' => [ 'Sonim', 'XP6711' ], 'Sonim XP7700' => [ 'Sonim', 'XP7700' ], 'Sonim-XP7700' => [ 'Sonim', 'XP7700' ], + 'sonim/XP7700' => [ 'Sonim', 'XP7700' ], ], 'OMS1 6' => [ 'Sony Ericsson', 'A8i' ], @@ -10687,6 +10716,7 @@ 'T98 4G??(C6R2)' => [ 'Teclast', 'T98', DeviceType::TABLET ], 'T720 SE' => [ 'Teclast', 'T720', DeviceType::TABLET ], 'T760 from moage.com' => [ 'Teclast', 'T760', DeviceType::TABLET ], + 'X10H(G3C5)' => [ 'Teclast', 'X10H', DeviceType::TABLET ], 'X10HD 3G(M6K6)' => [ 'Teclast', 'X10HD 3G', DeviceType::TABLET ], 'X16 Power(D6F7)' => [ 'Teclast', 'X16 Power', DeviceType::TABLET ], 'X16HD (K3J3)' => [ 'Teclast', 'X16HD', DeviceType::TABLET ], @@ -10917,6 +10947,13 @@ 'Folio 100' => [ 'Toshiba', 'Folio 100', DeviceType::TABLET ], 'folio100' => [ 'Toshiba', 'Folio 100', DeviceType::TABLET ], 'THRiVE' => [ 'Toshiba', 'THRiVE', DeviceType::TABLET ], + + 'Satellite!!' => [ + 'Satellite ([A-Z][0-9]{3,3}[A-Z]?)!' => [ 'Toshiba', 'Satellite $1', DeviceType::DESKTOP ], + 'Satellite ([A-Z][0-9]{2,2}-[A-Z]?)!' => [ 'Toshiba', 'Satellite $1', DeviceType::DESKTOP ], + 'Satellite Pro ([A-Z][0-9]{3,3})!' => [ 'Toshiba', 'Satellite Pro $1', DeviceType::DESKTOP ], + ], + 'StarTab 715x' => [ 'Touch+', 'Startab 715', DeviceType::TABLET ], 'TRACER OXYGEN GS1' => [ 'Tracer', 'Oxygen GS1' ], @@ -11241,6 +11278,7 @@ 'Xtreme-V30' => [ 'Voice', 'Xtreme V30' ], 'vollo Vi86' => [ 'VOLLO', 'Vi86' ], 'VOTO V5' => [ 'VOTO', 'V5' ], + 'VOTO VT868' => [ 'VOTO', 'VT868' ], 'VOTO VT888' => [ 'VOTO', 'VT888' ], 'VOTO W5300' => [ 'VOTO', 'W5300' ], 'VOTO X2' => [ 'VOTO', 'X2' ], @@ -11314,6 +11352,7 @@ 'Primo Walpad 8' => [ 'Walton', 'Primo Walpad 8', DeviceType::TABLET ], 'Walpad 8b' => [ 'Walton', 'Primo Walpad 8b', DeviceType::TABLET ], 'Primo Walpad 8W' => [ 'Walton', 'Primo Walpad 8W', DeviceType::TABLET ], + 'Walpad 8x' => [ 'Walton', 'Primo Walpad 8x', DeviceType::TABLET ], 'xPAD-70' => [ 'WayteQ', 'xPAD-70', DeviceType::TABLET ], 'xTAB-7X' => [ 'WayteQ', 'xTAB-7X', DeviceType::TABLET ], 'xTAB-9' => [ 'WayteQ', 'xTAB-9', DeviceType::TABLET ], @@ -11466,6 +11505,7 @@ 'Woxter Tablet PC 101IPS DUAL' => [ 'Woxter', 'Tablet PC 101 IPS Dual', DeviceType::TABLET ], 'Woxter SX100' => [ 'Woxter', 'SX 100', DeviceType::TABLET ], 'Woxter QX 70' => [ 'Woxter', 'QX 70', DeviceType::TABLET ], + 'Woxter QX78' => [ 'Woxter', 'QX 78', DeviceType::TABLET ], 'Woxter QX 90' => [ 'Woxter', 'QX 90', DeviceType::TABLET ], 'Woxter QX105' => [ 'Woxter', 'QX 105', DeviceType::TABLET ], 'Woxter Nimbus 97Q' => [ 'Woxter', 'Nimbus 97Q', DeviceType::TABLET ], @@ -11543,6 +11583,7 @@ 'HM NOTE 1S' => [ 'Xiaomi', 'Redmi Note 1' ], 'HM NOTE 1W' => [ 'Xiaomi', 'Redmi Note 1' ], 'Redmi Note 4G (LTE)' => [ 'Xiaomi', 'Redmi Note 1' ], + 'Xiaomi Note 4G' => [ 'Xiaomi', 'Redmi Note 1' ], '2013122' => [ 'Xiaomi', 'Redmi Note 1' ], 'Redmi Note 2' => [ 'Xiaomi', 'Redmi Note 2' ], 'Xiaomi Note2' => [ 'Xiaomi', 'Redmi Note 2' ], @@ -12399,6 +12440,7 @@ '6034R ORANGE Niva' => [ 'Orange', 'Nivo' ], 'Orange Niva' => [ 'Orange', 'Nivo' ], 'Orange Nura' => [ 'Orange', 'Nura' ], + 'Nura 2' => [ 'Orange', 'Nura 2' ], 'Orange Reyo' => [ 'Orange', 'Reyo' ], 'Orange Rono' => [ 'Orange', 'Rono' ], 'Orange Roya' => [ 'Orange', 'Roya' ], diff --git a/data/os-cfnetwork.php b/data/os-cfnetwork.php new file mode 100644 index 0000000..f185d07 --- /dev/null +++ b/data/os-cfnetwork.php @@ -0,0 +1,90 @@ + [ 'value' => '10.2' ], + '1.2.1' => [ 'value' => '10.3.2' ], + '1.2.2' => [ 'value' => '10.3.9' ], + '1.2.6' => [ 'value' => '10.3.9' ], + '128' => [ 'value' => '10.4' ], + '128.2' => [ 'value' => '10.4.2' ], + '129.5' => [ 'value' => '10.4.3' ], + '129.9' => [ 'value' => '10.4.4' ], + '129.10' => [ 'value' => '10.4.4' ], + '129.13' => [ 'value' => '10.4.6' ], + '129.16' => [ 'value' => '10.4.7' ], + '129.18' => [ 'value' => '10.4.8' ], + '129.20' => [ 'value' => '10.4.9' ], + '129.21' => [ 'value' => '10.4.10' ], + '129.22' => [ 'value' => '10.4.11' ], + '217' => [ 'value' => '10.5' ], + '220' => [ 'value' => '10.5.1' ], + '221.5' => [ 'value' => '10.5.2' ], + '330' => [ 'value' => '10.5.3' ], + '330.4' => [ 'value' => '10.5.4' ], + '339.5' => [ 'value' => '10.5.5' ], + '422.11' => [ 'value' => '10.5.6' ], + '438.12' => [ 'value' => '10.5.7' ], + '438.14' => [ 'value' => '10.5.8' ], + '454.4' => [ 'value' => '10.6.0' ], + '454.5' => [ 'value' => '10.6.2' ], + '454.9.4' => [ 'value' => '10.6.3' ], + '454.9.7' => [ 'value' => '10.6.4' ], + '454.11.5' => [ 'value' => '10.6.5' ], + '454.11.12' => [ 'value' => '10.6.7' ], + '454.12.4' => [ 'value' => '10.6.8' ], + '520.0.13' => [ 'value' => '10.7.1' ], + '520.2.5' => [ 'value' => '10.7.2' ], + '520.3.2' => [ 'value' => '10.7.3' ], + '520.4.3' => [ 'value' => '10.7.4' ], + '520.5.1' => [ 'value' => '10.7.5' ], + '596.1' => [ 'value' => '10.8.1' ], + '596.2.3' => [ 'value' => '10.8.2' ], + '596.3.3' => [ 'value' => '10.8.3' ], + '596.4.3' => [ 'value' => '10.8.4' ], + '596.5' => [ 'value' => '10.8.5' ], + '673.0.3' => [ 'value' => '10.9' ], + '673.2.1' => [ 'value' => '10.9.2' ], + '673.4' => [ 'value' => '10.9.3' ], + '720.0.9' => [ 'value' => '10.10' ], + '720.1.1' => [ 'value' => '10.10.1' ], + '720.2.4' => [ 'value' => '10.10.2' ], + '720.3.13' => [ 'value' => '10.10.3' ], + '720.4.4' => [ 'value' => '10.10.4' ], + '720.5.7' => [ 'value' => '10.10.5' ], + '760.0.5' => [ 'value' => '10.11' ], + '760.1.2' => [ 'value' => '10.11.1' ], + '760.2.6' => [ 'value' => '10.11.2' ], +]; + +CFNetwork::$IOS = [ + '459' => [ 'value' => '3.1.3' ], + '485.2' => [ 'value' => '4.0' ], + '485.10.2' => [ 'value' => '4.1' ], + '485.12.7' => [ 'value' => '4.2.1' ], + '485.12.30' => [ 'value' => '4.2.8' ], + '485.13.9' => [ 'value' => '4.3' ], + '548.0.3' => [ 'value' => '5.0' ], + '548.0.4' => [ 'value' => '5.0.1' ], + '548.1.4' => [ 'value' => '5.1' ], + '602' => [ 'value' => '6.0' ], + '609' => [ 'value' => '6.0' ], + '609.1.4' => [ 'value' => '6.1.2' ], + '671' => [ 'value' => '7.0' ], + '672.0.2' => [ 'value' => '7.0' ], + '672.0.8' => [ 'value' => '7.0.3' ], + '672.1.13' => [ 'value' => '7.1' ], + '672.1.14' => [ 'value' => '7.1.1' ], + '672.1.15' => [ 'value' => '7.1.2' ], + '711.0.6' => [ 'value' => '8.0' ], + '711.1.12' => [ 'value' => '8.1' ], + '711.1.16' => [ 'value' => '8.1.1' ], + '711.2.23' => [ 'value' => '8.2' ], + '711.3.18' => [ 'value' => '8.3' ], + '711.4.6' => [ 'value' => '8.4' ], + '711.5.6' => [ 'value' => '8.4.1' ], + '758.0.2' => [ 'value' => '9.0' ], + '758.1.6' => [ 'value' => '9.1' ], + '758.2.8' => [ 'value' => '9.2' ], +]; diff --git a/data/os-darwin.php b/data/os-darwin.php new file mode 100644 index 0000000..f504611 --- /dev/null +++ b/data/os-darwin.php @@ -0,0 +1,27 @@ + [ 'value' =>'10.0' ], + '5' => [ 'value' =>'10.1' ], + '6' => [ 'value' =>'10.2' ], + '7' => [ 'value' =>'10.3' ], + '8' => [ 'value' =>'10.4' ], + '9' => [ 'value' =>'10.5' ], + '10' => [ 'value' =>'10.6' ], + '11' => [ 'value' =>'10.7' ], + '12' => [ 'value' =>'10.8' ], + '13' => [ 'value' =>'10.9' ], + '14' => [ 'value' =>'10.10' ], + '15' => [ 'value' =>'10.11' ], +]; + +Darwin::$IOS = [ + '9' => [ 'value' =>'1' ], + '10' => [ 'value' =>'4' ], + '11' => [ 'value' =>'5' ], + '13' => [ 'value' =>'6' ], + '14' => [ 'value' =>'7' ], + '15' => [ 'value' =>'9' ], +]; diff --git a/data/profiles.php b/data/profiles.php index 367dd45..be707b8 100644 --- a/data/profiles.php +++ b/data/profiles.php @@ -74,6 +74,7 @@ 'http://support.acer.com/UAprofile/Acer_Z110_UAProfile.xml' => [ 'Acer', 'Liquid Z', 'Android', DeviceType::MOBILE ], 'http://support.acer.com/UAprofile/Acer_Z120_UAProfile.xml' => [ 'Acer', 'Liquid Z2', 'Android', DeviceType::MOBILE ], 'http://go.acer.com/?id=18020' => [ 'Acer', 'Liquid Z200', 'Android', DeviceType::MOBILE ], + 'http://go.acer.com/?id=83844' => [ 'Acer', 'Liquid Z205', 'Android', DeviceType::MOBILE ], 'http://global-download.acer.com/SupportFiles/Files/UAProfile/XML/Acer_Z130_JDQ39_Profile.xml' => [ 'Acer', 'Liquid Z3', 'Android', DeviceType::MOBILE ], 'http://go.acer.com/?id=17980' => [ 'Acer', 'Liquid Z4', 'Android', DeviceType::MOBILE ], 'http://go.acer.com/?id=18083' => [ 'Acer', 'Liquid Z410', 'Android', DeviceType::MOBILE ], @@ -265,6 +266,7 @@ 'http://www-ccpp.tcl-ta.com/files/ONE_TOUCH_4014D.xml' => [ 'Alcatel', 'One Touch Pixi 3 (4)', 'Android', DeviceType::MOBILE ], 'http://www-ccpp.tcl-ta.com/files/5065D.xml' => [ 'Alcatel', 'One Touch Pixi 3 (5)', 'Android', DeviceType::MOBILE ], 'http://www-ccpp.tcl-ta.com/files/5054O.xml' => [ 'Alcatel', 'One Touch Pixi 3 (5.5)', 'Android', DeviceType::MOBILE ], + 'http://www-ccpp.tcl-ta.com/files/5054X.xml' => [ 'Alcatel', 'One Touch Pixi 3 (5.5)', 'Android', DeviceType::MOBILE ], 'http://www-ccpp.tcl-ta.com/files/4045A.xml' => [ 'Alcatel', 'One Touch Pop 2 (4)', 'Android', DeviceType::MOBILE ], 'http://www-ccpp.tcl-ta.com/files/5042A.xml' => [ 'Alcatel', 'One Touch Pop 2 (4.5)', 'Android', DeviceType::MOBILE ], 'http://www-ccpp.tcl-ta.com/files/5042D.xml' => [ 'Alcatel', 'One Touch Pop 2 (4.5)', 'Android', DeviceType::MOBILE ], @@ -509,6 +511,7 @@ 'http://www.bluhelp.com/upload/xmlfiles/ADVANCE_3.5.XML' => [ 'BLU', 'Advance 3.5', 'Android', DeviceType::MOBILE ], 'http://www.bluhelp.com/upload/xmlfiles/ADVANCE4.0.xml' => [ 'BLU', 'Advance 4.0', 'Android', DeviceType::MOBILE ], 'http://www.bluhelp.com/upload/xmlfiles/ADVANCE_4.0.XML' => [ 'BLU', 'Advance 4.0', 'Android', DeviceType::MOBILE ], + 'http://www.bluhelp.com/upload/xmlfiles/Advance 4.0 L.xml' => [ 'BLU', 'Advance 4.0 L', 'Android', DeviceType::MOBILE ], 'http://www.zte.com.cn/mobile/uaprof/ZTE_U_V856_V3.xml' => [ 'BLU', 'Dash', 'Android', DeviceType::MOBILE ], 'http://ctmexico.com.mx/UA_DASH.xml' => [ 'BLU', 'Dash 3.5', 'Android', DeviceType::MOBILE ], 'http://www.bluhelp.com/upload/xmlfiles/DASH_3.5.XML' => [ 'BLU', 'Dash 3.5', 'Android', DeviceType::MOBILE ], @@ -546,6 +549,7 @@ 'http://www.bluhelp.com/upload/xmlfiles/STUDIO_G.xml' => [ 'BLU', 'Studio G', 'Android', DeviceType::MOBILE ], 'http://www.bluhelp.com/upload/xmlfiles/STUDIO5.0S_HD.xml' => [ 'BLU', 'Studio X', 'Android', DeviceType::MOBILE ], 'http://www.bluhelp.com/upload/xmlfiles/STUDIO_X.xml' => [ 'BLU', 'Studio X', 'Android', DeviceType::MOBILE ], + 'http://www.bluhelp.com/upload/xmlfiles/Studio_X_Plus.xml' => [ 'BLU', 'Studio X Plus', 'Android', DeviceType::MOBILE ], 'http://www.bluhelp.com/upload/xmlfiles/Touchbook_7.0_3G.xml' => [ 'BLU', 'Touch Book 7.0', 'Android', DeviceType::TABLET ], 'http://www.bmobile.eu.com/uaprofile/Bmobile_AX1030.xml' => [ 'Bmobile', 'AX1030', 'Android', DeviceType::MOBILE ], 'http://www.bmobile.eu.com/uaprofile/Bmobile_AX1060.xml' => [ 'Bmobile', 'AX1060', 'Android', DeviceType::MOBILE ], @@ -1183,6 +1187,7 @@ 'http://device.sprintpcs.com/HTC/831C-SPRINT/Bad Boyz Sprint ONE M8 Lollipop v30.rdf' => [ 'HTC', 'One (M8)', 'Android', DeviceType::MOBILE ], 'http://device.sprintpcs.com/HTC/831C-SPRINT/Bad Boyz Sprint ONE M8 Lollipop v32.rdf' => [ 'HTC', 'One (M8)', 'Android', DeviceType::MOBILE ], 'http://device.sprintpcs.com/HTC/831C-SPRINT/InsertCoin 716.rdf' => [ 'HTC', 'One (M8)', 'Android', DeviceType::MOBILE ], + 'http://device.sprintpcs.com/HTC/831C-SPRINT/InsertCoin 719.rdf' => [ 'HTC', 'One (M8)', 'Android', DeviceType::MOBILE ], 'http://device.sprintpcs.com/HTC/831C-SPRINT/ViperOneM8 430.rdf' => [ 'HTC', 'One (M8)', 'Android', DeviceType::MOBILE ], 'http://device.sprintpcs.com/HTC/831CH-Chameleon/15465413.rdf' => [ 'HTC', 'One (M8)', 'Android', DeviceType::MOBILE ], 'http://device.sprintpcs.com/HTC/831CH-Chameleon/42065410.rdf' => [ 'HTC', 'One (M8)', 'Android', DeviceType::MOBILE ], @@ -1825,6 +1830,7 @@ 'http://wap1.huawei.com/uaprof/HuaweiC8850v100CDMA.xml' => [ 'Huawei', 'C8850', 'Android', DeviceType::MOBILE ], 'http://wap1.huawei.com/uaprof/HuaweiU8687-Normal.xml' => [ 'Huawei', 'Chronos', 'Android', DeviceType::MOBILE ], 'http://wap1.huawei.com/uaprof/HUAWEI_TIT-AL00_UAProfile .xml' => [ 'Huawei', 'Enjoy 5', 'Android', DeviceType::MOBILE ], + 'http://wap1.huawei.com/uaprof/HUAWEI_TIT-CL10_UAProfile.xml' => [ 'Huawei', 'Enjoy 5', 'Android', DeviceType::MOBILE ], 'http://wap1.huawei.com/uaprof/HUAWEI_TIT-U02_UAProfile .xml' => [ 'Huawei', 'Enjoy 5', 'Android', DeviceType::MOBILE ], 'http://wap1.huawei.com/uaprof/HW_HUAWEI_CM990_1_20130108.xml' => [ 'Huawei', 'EvoluciĆ³n 3', 'Android', DeviceType::MOBILE ], 'http://wap1.huawei.com/uaprof/HuaweiUM840v100GPRS.xml' => [ 'Huawei', 'Evolution', 'Android', DeviceType::MOBILE ], @@ -1873,10 +1879,14 @@ 'http://wap1.huawei.com/uaprof/HW_SCL-CL00_1_20150420.xml' => [ 'Huawei', 'Honor 4A', 'Android', DeviceType::MOBILE ], 'http://wap1.huawei.com/uaprof/HW_SCL-L01_Europe_DRM-UAProfile.xml' => [ 'Huawei', 'Honor 4A', 'Android', DeviceType::MOBILE ], 'http://wap1.huawei.com/uaprof/HW_SCL-L01_UAProfile.xml' => [ 'Huawei', 'Honor 4A', 'Android', DeviceType::MOBILE ], + 'http://wap1.huawei.com/uaprof/HW_SCL-L02_UAProfile.xml' => [ 'Huawei', 'Honor 4A', 'Android', DeviceType::MOBILE ], 'http://wap1.huawei.com/uaprof/HW_SCL-L03_UAProfile-DRM.xml' => [ 'Huawei', 'Honor 4A', 'Android', DeviceType::MOBILE ], 'http://wap1.huawei.com/uaprof/HW_SCL-L04_UAProfile.xml' => [ 'Huawei', 'Honor 4A', 'Android', DeviceType::MOBILE ], 'http://wap1.huawei.com/uaprof/HW_SCL-L04_UAProfile_1MB.xml' => [ 'Huawei', 'Honor 4A', 'Android', DeviceType::MOBILE ], + 'http://wap1.huawei.com/uaprof/HW_SCL-L21_Europe_DRM-UAProfile.xml' => [ 'Huawei', 'Honor 4A', 'Android', DeviceType::MOBILE ], + 'http://wap1.huawei.com/uaprof/HW_SCL-L21_UAProfile.xml' => [ 'Huawei', 'Honor 4A', 'Android', DeviceType::MOBILE ], 'http://wap1.huawei.com/uaprof/HW_SCL-TL00H_UAProfile.xml' => [ 'Huawei', 'Honor 4A', 'Android', DeviceType::MOBILE ], + 'http://wap1.huawei.com/uaprof/HW_SCL-TL00_UAProfile.xml' => [ 'Huawei', 'Honor 4A', 'Android', DeviceType::MOBILE ], 'http://wap1.huawei.com/uaprof/HUAWEI_CHM-TL00H_UAProfile.xml' => [ 'Huawei', 'Honor 4C', 'Android', DeviceType::MOBILE ], 'http://wap1.huawei.com/uaprof/HUAWEI_CHM-U01_UAProfile.xml' => [ 'Huawei', 'Honor 4C', 'Android', DeviceType::MOBILE ], 'http://wap1.huawei.com/uaprof/HUAWEI_CHM-UL00_UAProfile.xml' => [ 'Huawei', 'Honor 4C', 'Android', DeviceType::MOBILE ], @@ -1986,6 +1996,7 @@ 'http://wap1.huawei.com/uaprof/HW_HUAWEI_H871G.xml' => [ 'Huawei', 'Magna', 'Android', DeviceType::MOBILE ], 'http://wap1.huawei.com/uaprof/HUAWEI_CRR_L09_UAProfile.xml' => [ 'Huawei', 'Mate 8', 'Android', DeviceType::MOBILE ], 'http://wap1.huawei.com/uaprof/HUAWEI_M200_L09_UAProfile.xml' => [ 'Huawei', 'Mate 8', 'Android', DeviceType::MOBILE ], + 'http://wap1.huawei.com/uaprof/HUAWEI_NXT-AL10_UAProfile.xml' => [ 'Huawei', 'Mate 8', 'Android', DeviceType::MOBILE ], 'http://wap1.huawei.com/uaprof/HUAWEI_CRR-UL00_UAProfile.xml' => [ 'Huawei', 'Mate S', 'Android', DeviceType::MOBILE ], 'http://wap1.huawei.com/uaprof/HUAWEI_CRR-UL20_UAProfile.xml' => [ 'Huawei', 'Mate S', 'Android', DeviceType::MOBILE ], 'http://wap1.huawei.com/uaprof/HUAWEI_CRR_L09_UAProfile_3G.xml' => [ 'Huawei', 'Mate S', 'Android', DeviceType::MOBILE ], @@ -2475,6 +2486,7 @@ 'http://uaprof.vtext.com/lg/vx9200/vx9200.xml' => [ 'LG', 'Env3', 'Brew', DeviceType::MOBILE ], 'http://gsm.lge.com/html/gsm/P870-M10-D1.xml' => [ 'LG', 'Escape', 'Android', DeviceType::MOBILE ], 'http://gsm.lge.com/html/gsm/P870-M6-D2.xml' => [ 'LG', 'Escape', 'Android', DeviceType::MOBILE ], + 'http://gsm.lge.com/html/gsm/AK1bQ_G8_-S9ccPj/H445-M10-D1.xml' => [ 'LG', 'Escape2', 'Android', DeviceType::MOBILE ], 'http://uaprof.metropcs.net/UAProf/LG-MS910.xml' => [ 'LG', 'Esteem', 'Android', DeviceType::MOBILE ], 'http://gsm.lge.com/html/gsm/LG-F2200.xml' => [ 'LG', 'F2200', null, DeviceType::MOBILE ], 'http://gsm.lge.com/html/gsm/LG-F3000.xml' => [ 'LG', 'F3000', null, DeviceType::MOBILE ], @@ -2740,6 +2752,7 @@ 'http://gsm.lge.com/html/gsm/D693n-M3-D1.xml' => [ 'LG', 'G3 Stylus', 'Android', DeviceType::MOBILE ], 'http://gsm.lge.com/html/gsm/D693TR-M5-D1.xml' => [ 'LG', 'G3 Stylus', 'Android', DeviceType::MOBILE ], 'http://gsm.lge.com/html/gsm/RNTp_ElEPgL_QrBQ/D690-M3-D1.xml' => [ 'LG', 'G3 Stylus', 'Android', DeviceType::MOBILE ], + 'http://device.sprintpcs.com/LG/LS885-SPRINT/LS885ZV6.rdf' => [ 'LG', 'G3 Vigor', 'Android', DeviceType::MOBILE ], 'http://gsm.lge.com/html/gsm/D631-M10-D1.xml' => [ 'LG', 'G3 Vista', 'Android', DeviceType::MOBILE ], 'http://device.sprintpcs.com/LG/LS991-Chameleon/latest' => [ 'LG', 'G4', 'Android', DeviceType::MOBILE ], 'http://gsm.lge.com/html/gsm/H815-M3-D1.xml' => [ 'LG', 'G4', 'Android', DeviceType::MOBILE ], @@ -2983,6 +2996,7 @@ 'http://gsm.lge.com/html/gsm/0W_43_22MIQ_HNMe/H340-M10-D1.xml' => [ 'LG', 'Leon', 'Android', DeviceType::MOBILE ], 'http://gsm.lge.com/html/gsm/0W_43_22MIQ_HNMe/H340-M3-D1.xml' => [ 'LG', 'Leon', 'Android', DeviceType::MOBILE ], 'http://gsm.lge.com/html/gsm/0W_43_22MIQ_HNMe/H340AR-M3-D1.xml' => [ 'LG', 'Leon', 'Android', DeviceType::MOBILE ], + 'http://gsm.lge.com/html/gsm/0W_43_22MIQ_HNMe/H340n-M10-D1.xml' => [ 'LG', 'Leon', 'Android', DeviceType::MOBILE ], 'http://gsm.lge.com/html/gsm/0W_43_22MIQ_HNMe/H340n-M3-D1.xml' => [ 'LG', 'Leon', 'Android', DeviceType::MOBILE ], 'http://gsm.lge.com/html/gsm/0W_43_22MIQ_HNMe/H340n-M5-D1.xml' => [ 'LG', 'Leon', 'Android', DeviceType::MOBILE ], 'http://gsm.lge.com/html/gsm/0W_43_22MIQ_HNMe/H340n-M6-D1.xml' => [ 'LG', 'Leon', 'Android', DeviceType::MOBILE ], @@ -3466,6 +3480,7 @@ 'http://gsm.lge.com/html/gsm/LG-U830.xml' => [ 'LG', 'U830 Chocolate', null, DeviceType::MOBILE ], 'http://gsm.lge.com/html/gsm/LG-U900.xml' => [ 'LG', 'U900', null, DeviceType::MOBILE ], 'http://gsm.lge.com/html/gsm/LG-U970.xml' => [ 'LG', 'U970 Shine', null, DeviceType::MOBILE ], + 'http://device.sprintpcs.com/LG/LG730-6100000231/LG730ZV5.rdf' => [ 'LG', 'Venice', 'Android', DeviceType::MOBILE ], 'http://device.sprintpcs.com/LG/LG730-BOOST/LG730ZV5.rdf' => [ 'LG', 'Venice', 'Android', DeviceType::MOBILE ], 'http://device.sprintpcs.com/LG/LG730-BOOST/LG730ZV6.rdf' => [ 'LG', 'Venice', 'Android', DeviceType::MOBILE ], 'http://device.sprintpcs.com/LG/LG730-BOOST/LG730ZV8.rdf' => [ 'LG', 'Venice', 'Android', DeviceType::MOBILE ], @@ -4836,6 +4851,7 @@ 'http://www.amobile.com.cn/ua/Amoi-NewYork.xml' => [ 'Orange', 'New York', null, ], 'http://www-ccpp.tcl-ta.com/files/Orange_Niva.xml' => [ 'Orange', 'Nivo', 'Android', DeviceType::MOBILE ], 'http://www-ccpp.tcl-ta.com/files/Orange_Nura.xml' => [ 'Orange', 'Nura', 'Android', DeviceType::MOBILE ], + 'http://www-ccpp.tcl-ta.com/files/Nura 2.xml' => [ 'Orange', 'Nura 2', 'Android', DeviceType::MOBILE ], 'http://www.zte.com.cn/mobile/uaprof/Orange_Reyo.xml' => [ 'Orange', 'Reyo', 'Android', DeviceType::MOBILE ], 'http://www.zte.com.cn/mobile/uaprof/Orange_Rono.xml' => [ 'Orange', 'Rono', 'Android', DeviceType::MOBILE ], 'http://www-ccpp.tcl-ta.com/files/Orange_Roya.xml' => [ 'Orange', 'Roya', 'Android', DeviceType::MOBILE ], @@ -4875,6 +4891,7 @@ 'http://mobileinternet.panasonicbox.com/UAprof/GD88/R1.xml' => [ 'Panasonic', 'GD88', null, DeviceType::MOBILE ], 'http://mobileinternet.panasonicbox.com/UAprof/GD88D/R1.xml' => [ 'Panasonic', 'GD88', null, DeviceType::MOBILE ], 'http://mobileinternet.panasonicbox.com/UAprof/GU87/R1.xml' => [ 'Panasonic', 'GU87', null, DeviceType::MOBILE ], + 'http://www-ccpp.tcl-ta.com/files/PANASONIC_P31.xml' => [ 'Panasonic', 'P31', 'Android', DeviceType::MOBILE ], 'http://www-ccpp.tcl-ta.com/files/Panasonic P51.xml' => [ 'Panasonic', 'P51', 'Android', DeviceType::MOBILE ], 'http://mobileinternet.panasonicbox.com/UAprof/SA7/RP1.xml' => [ 'Panasonic', 'SA7', null, DeviceType::MOBILE ], 'http://www-ccpp.tcl-ta.com/files/Panasonic_T31.xml' => [ 'Panasonic', 'T31', 'Android', DeviceType::MOBILE ], @@ -5813,6 +5830,7 @@ 'http://wap.samsungmobile.com/uaprof/SM-J200GU.xml' => [ 'Samsung', 'Galaxy J2', 'Android', DeviceType::MOBILE ], 'http://device.sprintpcs.com/Samsung/SM-J320P-Chameleon/latest' => [ 'Samsung', 'Galaxy J3', 'Android', DeviceType::MOBILE ], 'http://wap.samsungmobile.com/uaprof/SM-J500F.xml' => [ 'Samsung', 'Galaxy J5', 'Android', DeviceType::MOBILE ], + 'http://wap.samsungmobile.com/uaprof/SM-J500FN.xml' => [ 'Samsung', 'Galaxy J5', 'Android', DeviceType::MOBILE ], 'http://wap.samsungmobile.com/uaprof/SM-J500G.xml' => [ 'Samsung', 'Galaxy J5', 'Android', DeviceType::MOBILE ], 'http://wap.samsungmobile.com/uaprof/SM-J500H.xml' => [ 'Samsung', 'Galaxy J5', 'Android', DeviceType::MOBILE ], 'http://wap.samsungmobile.com/uaprof/SM-J500M.xml' => [ 'Samsung', 'Galaxy J5', 'Android', DeviceType::MOBILE ], @@ -6137,6 +6155,7 @@ 'http://wap.samsungmobile.com/uaprof/SGH-S959G.xml' => [ 'Samsung', 'Galaxy S II', 'Android', DeviceType::MOBILE ], 'http://wap.samsungmobile.com/uaprof/SGH-T989.xml' => [ 'Samsung', 'Galaxy S II', 'Android', DeviceType::MOBILE ], 'http://wap.samsungmobile.com/uaprof/soju.xml' => [ 'Samsung', 'Galaxy S II', 'Android', DeviceType::MOBILE ], + 'http://Ā­device.sprintpcs.com /Ā­HTC/HTCPN702-SPRINT/Ā­3046512.rdf' => [ 'Samsung', 'Galaxy S II', 'Android', DeviceType::MOBILE ], 'http://nmsc.ctvap.cn/uaprof/SCH/SCH_i929_1_20110901.xml' => [ 'Samsung', 'Galaxy S II Duos', 'Android', DeviceType::MOBILE ], 'http://nmsc.ctvap.cn/uaprof/SCH/SCH_i929_2_20120705.XML' => [ 'Samsung', 'Galaxy S II Duos', 'Android', DeviceType::MOBILE ], 'http://wap.samsungmobile.com/uaprof/GT-I9210.xml' => [ 'Samsung', 'Galaxy S II LTE', 'Android', DeviceType::MOBILE ], @@ -6371,6 +6390,7 @@ 'http://device.sprintpcs.com/Samsung/SM-G900P-SPRINT/OD3.rdf' => [ 'Samsung', 'Galaxy S5', 'Android', DeviceType::MOBILE ], 'http://device.sprintpcs.com/Samsung/SM-G900P-SPRINT/OF6.rdf' => [ 'Samsung', 'Galaxy S5', 'Android', DeviceType::MOBILE ], 'http://device.sprintpcs.com/Samsung/SM-G900P-SPRINT/OG1.rdf' => [ 'Samsung', 'Galaxy S5', 'Android', DeviceType::MOBILE ], + 'http://device.sprintpcs.com/Samsung/SM-G900P-SPRINT/OK4.rdf' => [ 'Samsung', 'Galaxy S5', 'Android', DeviceType::MOBILE ], 'http://device.sprintpcs.com/Samsung/SM-G900P-VIRGIN/NE5.rdf' => [ 'Samsung', 'Galaxy S5', 'Android', DeviceType::MOBILE ], 'http://device.sprintpcs.com/Samsung/SM-G900P-VIRGIN/NK4.rdf' => [ 'Samsung', 'Galaxy S5', 'Android', DeviceType::MOBILE ], 'http://device.sprintpcs.com/Samsung/SM-G900P-VIRGIN/OA6.rdf' => [ 'Samsung', 'Galaxy S5', 'Android', DeviceType::MOBILE ], @@ -8550,6 +8570,7 @@ 'http://nmsc.ctvap.cn/uaprof/YCT/YCT_TE600_1_20101228.xml' => [ 'YCT', 'TE600', 'Android', DeviceType::MOBILE ], 'http://www.ddmbrands.com/uaprof/yezz/andy_5EI.xml' => [ 'Yezz', 'Andy 5EI', 'Android', DeviceType::MOBILE ], 'http://www.ddmbrands.com/uaprof/yezz/andy_5EL.xml' => [ 'Yezz', 'Andy 5EL', 'Android', DeviceType::MOBILE ], + 'http://www.ddmbrands.com/uaprof/yezz/andy_C5EL.xml' => [ 'Yezz', 'Andy 5EL', 'Android', DeviceType::MOBILE ], 'http://www.lenovomobile.com/admin/module/product/DownFile/YUSUN LA2-T_UAprofile.xml' => [ 'YUSUN', 'LA2-T', 'Android', DeviceType::MOBILE ], 'http://uaprof.zebra.com/mc36.xml' => [ 'Zebra', 'MC36', 'Android', DeviceType::MOBILE ], 'http://211.42.201.70/ua_profile/ZMEM1070.xml' => [ 'Zonda', 'ZMEM1070', null, DeviceType::MOBILE ], diff --git a/detect.php b/detect.php index d6bc422..8ec924b 100644 --- a/detect.php +++ b/detect.php @@ -15,398 +15,8 @@ if (isset($_REQUEST['w'])) $options['width'] = intval($_REQUEST['w']); if (isset($_REQUEST['h'])) $options['height'] = intval($_REQUEST['h']); $detected = new WhichBrowser\Parser($options); - -?> - -var WhichBrowser = (function(){ - - var WhichBrowser = function() { this.initialize.apply(this, arguments) }; - WhichBrowser.prototype = { - initialize: function(options) { - this.options = { - }; - -toJavaScript(); ?> - }, - - a: function(s) { - return (/^[aeiou]/i.test(s) ? 'an ' : 'a ') + s; - }, - - isX: function() { - var valid = true; - var x = arguments[0]; - - if (arguments.length >= 2) { - valid = valid && this[x].name == arguments[1]; - } - - if (arguments.length >= 4 && this[x].version && valid) { - valid = valid && this[x].version.is(arguments[2], arguments[3]); - } - return valid; - }, - - isBrowser: function() { var a = Array.prototype.slice.call(arguments); a.unshift('browser'); return this.isX.apply(this, a); }, - isEngine: function() { var a = Array.prototype.slice.call(arguments); a.unshift('engine'); return this.isX.apply(this, a); }, - isOs: function() { var a = Array.prototype.slice.call(arguments); a.unshift('os'); return this.isX.apply(this, a); }, - - isDevice: function(d) { - return this.device.series == d || this.device.model == d; - }, - isType: function() { - var valid = false; - for (var a = 0; a < arguments.length; a++) valid = valid || arguments[a] == this.device.type; - return valid; - }, - - toJSON: function() { - return { - browser: this.browser.toJSON(), - os: this.os.toJSON(), - engine: this.engine.toJSON(), - device: this.device.toJSON() - }; - }, - - toString: function() { - var prefix = this.camouflage ? 'an unknown browser that imitates ' : ''; - var browser = this.browser.toString(); - var os = this.os.toString(); - var engine = this.engine.toString(); - var device = this.device.toString(); - - if (!device && !os && this.device.type == 'television') device = 'television'; - if (!device && this.device.type == 'emulator') device = 'emulator'; - - if (browser && os && device) return prefix + browser + ' on ' + this.a(device) + ' running ' + os; - if (browser && !os && device) return prefix + browser + ' on ' + this.a(device); - if (browser && os && !device) return prefix + browser + ' on ' + os; - if (!browser && os && device) return prefix + this.a(device) + ' running ' + os; - if (browser && !os && !device) return prefix + browser; - if (!browser && !os && device) return prefix + this.a(device); - if (this.device.type == 'desktop' && os && engine != '' && !device) return 'an unknown browser based on ' + engine + ' running on ' + os; - if (this.browser.stock && os && !device) return os; - if (this.browser.stock && engine != '' && !device) return 'an unknown browser based on ' + engine; - - return 'an unknown browser'; - } - }; - - var Using = function() { this.initialize.apply(this, Array.prototype.slice.call(arguments)) }; - Using.prototype = { - initialize: function(v) { - this.name = v.name || null; - this.version = v.version || null; - }, - - toJSON: function() { - return { - name: this.name, - version: (this.version) ? this.version.toJSON() : null, - }; - }, - - toString: function() { - return (this.name ? this.name + (this.version && !this.version.hidden ? ' ' + this.version.toString() : '') : ''); - } - }; - - var Family = function() { this.initialize.apply(this, Array.prototype.slice.call(arguments)) }; - Family.prototype = { - initialize: function(v) { - this.name = v.name || null; - this.version = v.version || null; - }, - - toJSON: function() { - return { - name: this.name, - version: (this.version) ? this.version.toJSON() : null, - }; - }, - - toString: function() { - return (this.name ? this.name + (this.version && !this.version.hidden ? ' ' + this.version.toString() : '') : ''); - } - }; + $template = file_get_contents(__DIR__ . '/templates/detect.js'); + echo str_replace('/* $detected->toJavaScript() */', $detected->toJavaScript(), $template); - var Browser = function() { this.initialize.apply(this, Array.prototype.slice.call(arguments)) }; - Browser.prototype = { - initialize: function(v) { - this.name = v.name || null; - this.alias = v.alias || null; - this.version = v.version || null; - this.using = v.using || null; - this.family = v.family || null; - - this.stock = v.stock || false; - this.channel = v.channel || null; - this.mode = v.mode || null; - this.hidden = v.hidden || false; - }, - - toJSON: function() { - return { - name: this.name, - alias: this.alias, - version: (this.version) ? this.version.toJSON() : null, - stock: this.stock, - channel: this.channel, - mode: this.mode, - hidden: this.hidden - }; - }, - - toString: function() { - var name = this.alias ? this.alias : (this.name ? this.name : ''); - if (name != '') return (name ? name + (this.channel ? ' ' + this.channel : '') + (this.version && !this.version.hidden ? ' ' + this.version.toString() : '') : ''); - if (this.using) return this.using.toString(); - return ''; - } - }; - - var Engine = function() { this.initialize.apply(this, Array.prototype.slice.call(arguments)) }; - Engine.prototype = { - initialize: function(v) { - this.name = v.name || null; - this.alias = v.alias || null; - this.version = v.version || null; - }, - - toJSON: function() { - return { - name: this.name, - version: (this.version) ? this.version.toJSON() : null - }; - }, - - toString: function() { - var name = this.alias ? this.alias : (this.name ? this.name : ''); - return name; - } - }; - - var Os = function() { this.initialize.apply(this, Array.prototype.slice.call(arguments)) }; - Os.prototype = { - initialize: function(v) { - this.name = v.name || null; - this.family = v.family || null; - this.alias = v.alias || null; - this.version = v.version || null; - }, - - toJSON: function() { - return { - name: this.name, - family: this.family, - alias: this.alias, - version: (this.version) ? this.version.toJSON() : null - }; - }, - - toString: function() { - var name = this.alias ? this.alias : (this.name ? this.name : ''); - return (name ? name + (this.version && !this.version.hidden ? ' ' + this.version.toString() : '') : ''); - } - }; - - var Device = function() { this.initialize.apply(this, Array.prototype.slice.call(arguments)) }; - Device.prototype = { - initialize: function(v) { - this.type = v.type || null; - this.identified = v.identified || false; - this.manufacturer = v.manufacturer || null; - this.model = v.model || null; - this.series = v.series || null; - }, - - toJSON: function() { - return { - type: this.type, - identified: this.identified, - manufacturer: this.manufacturer, - model: this.model, - series: this.series - }; - }, - - toString: function() { - if (this.identified) { - var manufacturer = this.manufacturer || ''; - var model = ((this.model || '') + ' ' + (this.series || '')).trim(); - - if (model.indexOf(manufacturer) === 0) { - manufacturer = ''; - } - - return (manufacturer + ' ' + model).trim(); - } - - return (this.model ? 'unrecognized device (' + this.model + ')' : ''); - } - }; - - var Version = function() { this.initialize.apply(this, Array.prototype.slice.call(arguments)) }; - Version.prototype = { - initialize: function(v) { - this.original = v.value || null; - this.alias = v.alias || null; - this.nickname = v.nickname || null; - this.details = v.details || null; - this.hidden = v.hidden || null; - this.builds = typeof v.builds != 'undefined' ? v.builds : true; - - this.major = 0; - this.minor = null; - this.revision = null; - this.build = null; - this.type = ''; - - var match; - if (match = /([0-9]+)(?:\.([0-9]+))?(?:\.([0-9]+))?(?:\.([0-9]+))?(?:([ab])([0-9]+))?/.exec(this.original)) { - if (typeof match[1] != 'undefined') { - this.major = match[1]; - } - - if (typeof match[2] != 'undefined') { - this.minor = match[2]; - } - - if (typeof match[3] != 'undefined') { - this.revision = match[3]; - } - - if (typeof match[4] != 'undefined') { - this.build = match[4]; - } - - if (typeof match[5] != 'undefined') { - switch(match[5]) { - case 'a': this.type = 'alpha'; break; - case 'b': this.type = 'beta'; break; - } - - if (typeof match[6] != 'undefined') { - this.build = match[6]; - } - } - } - }, - - is: function(v) { - var valid = false; - - if (arguments.length > 0) { - var operator = '='; - var compare = null; - - if (arguments.length == 1) { - compare = new Version({ value: arguments[0] }); - } - - if (arguments.length >= 2) { - operator = arguments[0]; - compare = new Version({ value: arguments[1] }); - } - - if (compare) { - var v1 = v2 = ''; - - if (compare.major && this.major) { - v1 += this.major; - v2 += compare.major; - - if (compare.minor && this.minor) { - v1 += '.' + ('0000' + this.minor).slice(-4); - v2 += '.' + ('0000' + compare.minor).slice(-4); - - if (compare.revision && this.revision) { - v1 += ('0000' + this.revision).slice(-4); - v2 += ('0000' + compare.revision).slice(-4); - } - } - } - - v1 = parseFloat(v1); - v2 = parseFloat(v2); - - switch (operator) { - case '<': valid = v1 < v2; break; - case '<=': valid = v1 <= v2; break; - case '=': valid = v1 == v2; break; - case '>': valid = v1 > v2; break; - case '>=': valid = v1 >= v2; break; - } - } - - return valid; - } - - return false; - }, - - valueOf: function() { - return parseFloat('' + this.major + '.' + ('0000' + this.minor).slice(-4) + ('0000' + this.revision).slice(-4)); - }, - - toJSON: function() { - var o = { - value: this.toString(), - details: this.details, - hidden: this.hidden, - original: this.original, - major: this.major, - minor: this.minor, - build: this.build, - revision: this.revision - }; - - if (this.type) o.type = this.type; - if (this.alias) o.alias = this.alias; - if (this.nickname) o.nickname = this.nickname; - - return o; - }, - - toString: function() { - if (this.alias) - return this.alias; - - var version = ''; - - if (this.nickname) { - version += this.nickname + ' '; - } - - if (this.major || this.minor) { - var v = []; - v.push(this.major); - if (this.minor != '' && this.minor != null) v.push(this.minor); - if (this.revision != '' && this.revision != null) v.push(this.revision); - if (this.type == '' && this.build) v.push(this.build); - if (this.details < 0) v.splice(this.details, 0 - this.details); - if (this.details > 0) v.splice(this.details, v.length - this.details); - - if (!this.builds) { - for (var i = 0; i < v.length; i++) { - if (v[i] > 999) { - v.splice(i, 1); - i--; - } - } - } - - version += v.join('.'); - - if (this.type != '') version += this.type[0] + (this.build ? this.build : ''); - } - - return version; - } - }; - - return WhichBrowser; -})(); diff --git a/index.php b/index.php index d09ba86..79cad7d 100644 --- a/index.php +++ b/index.php @@ -115,7 +115,7 @@ $local = false; $redirect = false; - if ($_SERVER['HTTP_HOST'] == '127.0.0.1:8080') { + if ($_SERVER['HTTP_HOST'] == '127.0.0.1:8080' || $_SERVER['HTTP_HOST'] == 'localhost:8080') { $working = true; $local = true; } diff --git a/src/Analyser/Corrections.php b/src/Analyser/Corrections.php index ae8dc2a..de402c8 100644 --- a/src/Analyser/Corrections.php +++ b/src/Analyser/Corrections.php @@ -92,19 +92,26 @@ private function correctVersionOfMobileInternetExplorer() private function hideBrowserBasedOnOperatingSystem() { + if ($this->data->os->name == 'Series60' && $this->data->browser->name == 'Internet Explorer') { + $this->data->browser->reset(); + $this->data->engine->reset(); + } + if ($this->data->os->name == 'Series80' && $this->data->browser->name == 'Internet Explorer') { - $this->data->browser->name = null; - $this->data->browser->version = null; + $this->data->browser->reset(); + $this->data->engine->reset(); } if ($this->data->os->name == 'Tizen' && $this->data->browser->name == 'Chrome') { - $this->data->browser->name = null; - $this->data->browser->version = null; + $this->data->browser->reset([ + 'family' => isset($this->data->browser->family) ? $this->data->browser->family : null + ]); } if ($this->data->os->name == 'Ubuntu Touch' && $this->data->browser->name == 'Chromium') { - $this->data->browser->name = null; - $this->data->browser->version = null; + $this->data->browser->reset([ + 'family' => isset($this->data->browser->family) ? $this->data->browser->family : null + ]); } } diff --git a/src/Analyser/Derive.php b/src/Analyser/Derive.php index 3e0a5d5..bf15769 100644 --- a/src/Analyser/Derive.php +++ b/src/Analyser/Derive.php @@ -42,7 +42,7 @@ private function &deriveDeviceSubType() $this->data->device->subtype = 'smart'; } - if (in_array($this->data->os->getName(), [ 'Android', 'Bada', 'BlackBerry', 'BlackBerry OS', 'Firefox OS', 'iOS', 'iPhone OS', 'Kin OS', 'Maemo', 'MeeGo', 'Palm OS', 'Sailfish', 'Series60', 'Tizen', 'Ubuntu', 'Windows Mobile', 'Windows Phone', 'webOS' ])) { + if (in_array($this->data->os->getName(), [ 'Android', 'Bada', 'BlackBerry', 'BlackBerry OS', 'Firefox OS', 'iOS', 'iPhone OS', 'Kin OS', 'Maemo', 'MeeGo', 'Palm OS', 'Sailfish', 'Series60', 'Series80', 'Tizen', 'Ubuntu Touch', 'Windows Mobile', 'Windows Phone', 'webOS' ])) { $this->data->device->subtype = 'smart'; } } @@ -89,6 +89,7 @@ private function deriveOperaDevices() { if ($this->data->browser->name == 'Opera' && $this->data->device->type == Constants\DeviceType::TELEVISION) { $this->data->browser->name = 'Opera Devices'; + $this->data->browser->version = null; if ($this->data->engine->getName() == 'Presto') { switch (implode('.', array_slice(explode('.', $this->data->engine->getVersion()), 0, 2))) { @@ -128,24 +129,9 @@ private function deriveOperaDevices() default: unset($this->data->browser->version); } - } else { - switch (explode('.', $this->data->browser->getVersion())[0]) { - case '17': - $this->data->browser->version = new Version([ 'value' => '4.0' ]); - break; - case '19': - $this->data->browser->version = new Version([ 'value' => '4.1' ]); - break; - case '22': - $this->data->browser->version = new Version([ 'value' => '4.2' ]); - break; - default: - unset($this->data->browser->version); - } } - unset($this->data->os->name); - unset($this->data->os->version); + $this->data->os->reset(); } } @@ -153,22 +139,24 @@ private function deriveOperaDevices() private function deriveBasedOnDeviceFlag() { - if ($this->data->device->flag == Constants\Flag::NOKIAX) { + $flag = $this->data->device->flag; + + if ($flag == Constants\Flag::NOKIAX) { $this->data->os->name = 'Nokia X Platform'; $this->data->os->family = new Family([ 'name' => 'Android' ]); unset($this->data->os->version); unset($this->data->device->flag); - return; } - if ($this->data->device->flag == Constants\Flag::FIREOS) { + if ($flag == Constants\Flag::FIREOS) { $this->data->os->name = 'FireOS'; $this->data->os->family = new Family([ 'name' => 'Android' ]); if (isset($this->data->os->version) && isset($this->data->os->version->value)) { switch ($this->data->os->version->value) { case '2.3.3': + case '2.3.4': $this->data->os->version = new Version([ 'value' => '1' ]); break; case '4.0.3': @@ -202,27 +190,24 @@ private function deriveBasedOnDeviceFlag() } unset($this->data->device->flag); - return; } - if ($this->data->device->flag == Constants\Flag::GOOGLETV) { + if ($flag == Constants\Flag::GOOGLETV) { $this->data->os->name = 'Google TV'; $this->data->os->family = new Family([ 'name' => 'Android' ]); unset($this->data->os->version); unset($this->data->device->flag); - return; } - if ($this->data->device->flag == Constants\Flag::ANDROIDTV) { + if ($flag == Constants\Flag::ANDROIDTV) { $this->data->os->name = 'Android TV'; $this->data->os->family = new Family([ 'name' => 'Android' ]); unset($this->data->device->flag); - return; } - if ($this->data->device->flag == Constants\Flag::ANDROIDWEAR) { + if ($flag == Constants\Flag::ANDROIDWEAR) { $this->data->os->name = 'Android Wear'; $this->data->os->family = new Family([ 'name' => 'Android' ]); unset($this->data->os->version); @@ -232,16 +217,13 @@ private function deriveBasedOnDeviceFlag() $this->data->browser->name = 'Wear Internet Browser'; $this->data->browser->using = null; } - - return; } - if ($this->data->device->flag == Constants\Flag::GOOGLEGLASS) { + if ($flag == Constants\Flag::GOOGLEGLASS) { $this->data->os->family = new Family([ 'name' => 'Android' ]); unset($this->data->os->name); unset($this->data->os->version); unset($this->data->device->flag); - return; } } @@ -298,80 +280,17 @@ private function deriveBasedOnOperatingSystem() $this->data->browser->hidden = true; } - /* Derive iOS and OS X versions from Darwin */ - - if ($this->data->os->name == 'Darwin' && $this->data->device->type == Constants\DeviceType::MOBILE) { - $this->data->os->name = 'iOS'; - - switch (strstr($this->data->os->getVersion(), '.', true)) { - case '9': - $this->data->os->version = new Version([ 'value' =>'1' ]); + /* Derive iOS and OS X aliases */ + + if ($this->data->os->name == 'iOS') { + if (!empty($this->data->os->version)) { + if ($this->data->os->version->is('<', '4')) { $this->data->os->alias = 'iPhone OS'; - break; - case '10': - $this->data->os->version = new Version([ 'value' =>'4' ]); - break; - case '11': - $this->data->os->version = new Version([ 'value' =>'5' ]); - break; - case '13': - $this->data->os->version = new Version([ 'value' =>'6' ]); - break; - case '14': - $this->data->os->version = new Version([ 'value' =>'7' ]); - break; - case '15': - $this->data->os->version = new Version([ 'value' =>'9' ]); - break; - default: - $this->data->os->version = null; + } } } - if ($this->data->os->name == 'Darwin' && $this->data->device->type == Constants\DeviceType::DESKTOP) { - $this->data->os->name = 'OS X'; - - switch (strstr($this->data->os->getVersion(), '.', true)) { - case '1': - $this->data->os->version = new Version([ 'value' =>'10.0' ]); - break; - case '5': - $this->data->os->version = new Version([ 'value' =>'10.1' ]); - break; - case '6': - $this->data->os->version = new Version([ 'value' =>'10.2' ]); - break; - case '7': - $this->data->os->version = new Version([ 'value' =>'10.3' ]); - break; - case '8': - $this->data->os->version = new Version([ 'value' =>'10.4' ]); - break; - case '9': - $this->data->os->version = new Version([ 'value' =>'10.5' ]); - break; - case '10': - $this->data->os->version = new Version([ 'value' =>'10.6' ]); - break; - case '11': - $this->data->os->version = new Version([ 'value' =>'10.7' ]); - break; - case '12': - $this->data->os->version = new Version([ 'value' =>'10.8' ]); - break; - case '13': - $this->data->os->version = new Version([ 'value' =>'10.9' ]); - break; - case '14': - $this->data->os->version = new Version([ 'value' =>'10.10' ]); - break; - case '15': - $this->data->os->version = new Version([ 'value' =>'10.11' ]); - break; - default: - $this->data->os->version = null; - } - + if ($this->data->os->name == 'OS X') { if (!empty($this->data->os->version)) { if ($this->data->os->version->is('<', '10.7')) { $this->data->os->alias = 'Mac OS X'; diff --git a/src/Analyser/Header/OperaMini.php b/src/Analyser/Header/OperaMini.php index 20989e7..d8525bd 100644 --- a/src/Analyser/Header/OperaMini.php +++ b/src/Analyser/Header/OperaMini.php @@ -3,6 +3,7 @@ namespace WhichBrowser\Analyser\Header; use WhichBrowser\Data; +use WhichBrowser\Constants; class OperaMini { @@ -15,35 +16,57 @@ public function __construct($header, &$data) $model = isset($parts[1]) ? $parts[1] : ''; if ($manufacturer != '?' && $model != '?') { - if (!$this->data->device->identified && $this->data->os->name == 'Bada') { - $device = Data\DeviceModels::identify('bada', $model); - if ($device->identified) { - $device->identified |= $this->data->device->identified; - $this->data->device = $device; + if ($this->data->device->identified < Constants\Id::PATTERN) { + if ($this->identifyBasedOnModel($model)) { + return; } + + $this->data->device->manufacturer = $manufacturer; + $this->data->device->model = $model; + $this->data->device->identified = true; } + } + } - if (!$this->data->device->identified && $this->data->os->name == 'BlackBerry OS') { - $device = Data\DeviceModels::identify('blackberry', $model); - if ($device->identified) { - $device->identified |= $this->data->device->identified; - $this->data->device = $device; - } + private function identifyBasedOnModel($model) + { + $device = Data\DeviceModels::identify('bada', $model); + if ($device->identified) { + $device->identified |= $this->data->device->identified; + $this->data->device = $device; + + if (!isset($this->data->os->name) || $this->data->os->name != 'Bada') { + $this->data->os->name = 'Bada'; + $this->data->os->version = null; } - if (!$this->data->device->identified && $this->data->os->name == 'Windows Mobile') { - $device = Data\DeviceModels::identify('wm', $model); - if ($device->identified) { - $device->identified |= $this->data->device->identified; - $this->data->device = $device; - } + return true; + } + + $device = Data\DeviceModels::identify('blackberry', $model); + if ($device->identified) { + $device->identified |= $this->data->device->identified; + $this->data->device = $device; + + if (!isset($this->data->os->name) || $this->data->os->name != 'BlackBerry OS') { + $this->data->os->name = 'BlackBerry OS'; + $this->data->os->version = null; } - if (!$this->data->device->identified) { - $this->data->device->manufacturer = $manufacturer; - $this->data->device->model = $model; - $this->data->device->identified = true; + return true; + } + + $device = Data\DeviceModels::identify('wm', $model); + if ($device->identified) { + $device->identified |= $this->data->device->identified; + $this->data->device = $device; + + if (!isset($this->data->os->name) || $this->data->os->name != 'Windows Mobile') { + $this->data->os->name = 'Windows Mobile'; + $this->data->os->version = null; } + + return true; } } } diff --git a/src/Analyser/Header/UCBrowserNew.php b/src/Analyser/Header/UCBrowserNew.php index b2bf29b..b780a30 100644 --- a/src/Analyser/Header/UCBrowserNew.php +++ b/src/Analyser/Header/UCBrowserNew.php @@ -11,10 +11,16 @@ public function __construct($header, &$data) { $this->data =& $data; - if (preg_match('/pr\(UCBrowser\/([0-9\.]+)/u', $header, $match)) { - $this->data->browser->name = 'UC Browser'; - $this->data->browser->version = new Version([ 'value' => $match[1], 'details' => 2 ]); - $this->data->browser->stock = false; + if (preg_match('/pr\(UCBrowser/u', $header)) { + if (!$this->data->isBrowser('UC Browser')) { + $this->data->browser->name = 'UC Browser'; + $this->data->browser->stock = false; + $this->data->browser->version = null; + + if (preg_match('/pr\(UCBrowser(?:\/([0-9\.]+))/u', $header, $match)) { + $this->data->browser->version = new Version([ 'value' => $match[1], 'details' => 2 ]); + } + } } /* Find os */ @@ -32,14 +38,14 @@ public function __construct($header, &$data) } if (preg_match('/pf\(Symbian\)/u', $header) && preg_match('/ov\(S60V([0-9])/u', $header, $match)) { - if (!isset($this->data->os->name) || $this->data->os->name != 'Series60') { + if (!$this->data->isOs('Series60')) { $this->data->os->name = 'Series60'; $this->data->os->version = new Version([ 'value' => $match[1] ]); } } if (preg_match('/pf\(Windows\)/u', $header) && preg_match('/ov\(wds ([0-9\.]+)/u', $header, $match)) { - if (!isset($this->data->os->name) || $this->data->os->name != 'Windows Phone') { + if (!$this->data->isOs('Windows Phone')) { $this->data->os->name = 'Windows Phone'; switch ($match[1]) { @@ -57,7 +63,7 @@ public function __construct($header, &$data) } if (preg_match('/pf\((?:42|44)\)/u', $header) && preg_match('/ov\((?:iPh OS )?(?:iOS )?([0-9\_]+)/u', $header, $match)) { - if (!isset($this->data->os->name) || $this->data->os->name != 'iOS') { + if (!$this->data->isOs('iOS')) { $this->data->os->name = 'iOS'; $this->data->os->version = new Version([ 'value' => str_replace('_', '.', $match[1]) ]); } @@ -70,7 +76,7 @@ public function __construct($header, &$data) } /* Find device */ - if (isset($this->data->os->name) && $this->data->os->name == 'Android') { + if ($this->data->isOs('Android')) { if (preg_match('/dv\((.*)\)/uU', $header, $match)) { $match[1] = preg_replace("/\s+Build/u", '', $match[1]); $device = Data\DeviceModels::identify('android', $match[1]); @@ -81,7 +87,7 @@ public function __construct($header, &$data) } } - if (isset($this->data->os->name) && $this->data->os->name == 'Series60') { + if ($this->data->isOs('Series60')) { if (preg_match('/dv\((?:Nokia)?([^\)]*)\)/iu', $header, $match)) { $device = Data\DeviceModels::identify('s60', $match[1]); @@ -91,7 +97,7 @@ public function __construct($header, &$data) } } - if (isset($this->data->os->name) && $this->data->os->name == 'Windows Phone') { + if ($this->data->isOs('Windows Phone')) { if (preg_match('/dv\(([^\)]*)\)/u', $header, $match)) { $device = Data\DeviceModels::identify('wp', substr(strstr($match[1], ' '), 1)); @@ -101,7 +107,7 @@ public function __construct($header, &$data) } } - if (isset($this->data->os->name) && $this->data->os->name == 'iOS') { + if ($this->data->isOs('iOS')) { if (preg_match('/dv\(([^\)]*)\)/u', $header, $match)) { $device = Data\DeviceModels::identify('ios', $match[1]); diff --git a/src/Analyser/Header/Useragent/Browser.php b/src/Analyser/Header/Useragent/Browser.php index 29d1eb0..9c86b33 100644 --- a/src/Analyser/Header/Useragent/Browser.php +++ b/src/Analyser/Header/Useragent/Browser.php @@ -92,24 +92,6 @@ private function detectSafari($ua) $this->data->browser->version = null; } } - - - if (isset($this->data->os->name) && $this->data->os->name == 'Darwin') { - if (preg_match("/^MobileSafari/iu", $ua)) { - $this->data->browser->name = 'Safari'; - $this->data->browser->version = null; - $this->data->browser->stock = true; - $this->data->browser->hidden = true; - - $this->data->device->type = Constants\DeviceType::MOBILE; - } elseif (preg_match("/^Safari/iu", $ua)) { - $this->data->browser->name = 'Safari'; - $this->data->browser->version = null; - $this->data->browser->stock = true; - - $this->data->device->type = Constants\DeviceType::DESKTOP; - } - } } if (preg_match('/(?:Apple-PubSub|AppleSyndication)\//u', $ua)) { @@ -146,11 +128,7 @@ private function detectChrome($ua) $channel = Data\Chrome::getChannel('mobile', $this->data->browser->version->value); if ($channel == 'stable') { - if (explode('.', $version)[1] == '0') { - $this->data->browser->version->details = 1; - } else { - $this->data->browser->version->details = 2; - } + $this->data->browser->version->details = 1; } elseif ($channel == 'beta') { $this->data->browser->channel = 'Beta'; } else { @@ -309,8 +287,11 @@ private function detectChrome($ua) /* Set the browser family */ - if ($this->data->isBrowser('Chrome')) { - $this->data->browser->family = new Family([ 'name' => $this->data->browser->name, 'version' => new Version([ 'value' => $this->data->browser->version->getMajor() ]) ]); + if ($this->data->isBrowser('Chrome') || $this->data->isBrowser('Chromium')) { + $this->data->browser->family = new Family([ + 'name' => 'Chrome', + 'version' => !empty($this->data->browser->version) ? new Version([ 'value' => $this->data->browser->version->getMajor() ]) : null + ]); } } @@ -658,6 +639,26 @@ private function detectFirefox($ua) $this->data->browser->channel = 'BonEcho'; } + if (preg_match('/Fennec/u', $ua)) { + $this->data->browser->stock = false; + $this->data->browser->name = 'Firefox Mobile'; + + if (preg_match('/Fennec\/([0-9ab.]*)/u', $ua, $match)) { + $this->data->browser->version = new Version([ 'value' => $match[1] ]); + } + + $this->data->browser->channel = 'Fennec'; + } + + if (preg_match('/Minimo/u', $ua)) { + $this->data->browser->stock = false; + $this->data->browser->name = 'Minimo'; + + if (preg_match('/Minimo\/([0-9ab.]*)/u', $ua, $match)) { + $this->data->browser->version = new Version([ 'value' => $match[1] ]); + } + } + if (preg_match('/Firebird/u', $ua)) { $this->data->browser->stock = false; $this->data->browser->name = 'Firebird'; @@ -675,8 +676,12 @@ private function detectFirefox($ua) /* Set the browser family */ - if ($this->data->isBrowser('Firefox')) { - $this->data->browser->family = new Family([ 'name' => $this->data->browser->name, 'version' => $this->data->browser->version ]); + if ($this->data->isBrowser('Firefox') || $this->data->isBrowser('Firefox Mobile') || $this->data->isBrowser('Firebird')) { + $this->data->browser->family = new Family([ 'name' => 'Firefox', 'version' => $this->data->browser->version ]); + } + + if ($this->data->isBrowser('Minimo')) { + $this->data->browser->family = new Family([ 'name' => 'Firefox' ]); } } @@ -1462,18 +1467,57 @@ private function detectSpecficBrowsers($ua) /* 360 Phone Browser */ if (preg_match('/360 (?:Aphone|Android Phone) Browser \((?:Version |V)?([0-9.]*)(?:beta)?\)/u', $ua, $match)) { - $this->data->browser->name = '360 Phone Browser'; + $this->data->browser->name = 'Qihoo 360 Browser'; + $this->data->browser->family = null; $this->data->browser->channel = ''; - $this->data->browser->version = null; $this->data->browser->version = new Version([ 'value' => $match[1] ]); - if (preg_match('/360\(android/u', $ua) && (!isset($this->data->os->name) || ($this->data->os->name != 'Android' && (!isset($this->data->os->family) || $this->data->os->family->getName() != 'Android')))) { - $this->data->os->name = 'Android'; - $this->data->os->version = null; + if (!$this->data->os->isFamily('Android')) { $this->data->device->type = Constants\DeviceType::MOBILE; + $this->data->os->reset([ + 'name' => 'Android' + ]); } } + if (preg_match('/360%20Browser\/([0-9\.]+)/u', $ua, $match)) { + $this->data->browser->name = 'Qihoo 360 Browser'; + $this->data->browser->family = null; + $this->data->browser->channel = ''; + $this->data->browser->version = new Version([ 'value' => $match[1] ]); + } + + if (preg_match('/QHBrowser\/([0-9\.]+)/u', $ua, $match)) { + $version = $match[1]; + if (preg_match('/^[0-9][0-9][0-9]$/u', $version)) { + $version = $version[0] . '.' . $version[1] . '.' . $version[2]; + } + + $this->data->browser->name = 'Qihoo 360 Browser'; + $this->data->browser->channel = ''; + $this->data->browser->version = new Version([ 'value' => $version ]); + + if (!$this->data->isOs('iOS')) { + $this->data->device->type = Constants\DeviceType::MOBILE; + $this->data->os->reset([ + 'name' => 'iOS' + ]); + } + } + + /* Mercury */ + + if (preg_match('/Mercury\/([0-9\.]+)/u', $ua, $match)) { + $version = $match[1]; + if (preg_match('/^[0-9][0-9][0-9]$/u', $version)) { + $version = $version[0] . '.' . $version[1] . '.' . $version[2]; + } + + $this->data->browser->name = 'Mercury Browser'; + $this->data->browser->channel = ''; + $this->data->browser->version = new Version([ 'value' => $version ]); + } + /* iBrowser */ if (preg_match('/(iBrowser)\/([0-9.]*)/u', $ua, $match) && !preg_match('/OviBrowser/u', $ua)) { @@ -1541,6 +1585,8 @@ private function detectSpecficBrowsers($ua) $this->data->browser->name = 'MiniBrowser'; $this->data->browser->version = new Version([ 'value' => $match[1] ]); + $this->data->device->type = Constants\DeviceType::MOBILE; + $this->data->os->name = 'Series60'; $this->data->os->version = null; } @@ -1731,7 +1777,6 @@ private function detectRemainingBrowsers($ua) [ 'name' => '2345 Browser', 'regexp' => '/Mb2345Browser\/([0-9.]*)/u' ], [ 'name' => '3G Explorer', 'regexp' => '/3G Explorer\/([0-9.]*)/u', 'details' => 3 ], [ 'name' => '4G Explorer', 'regexp' => '/4G Explorer\/([0-9.]*)/u', 'details' => 3 ], - [ 'name' => '360 Aphone Browser', 'regexp' => '/360 Aphone Browser\(([0-9.]*)\)/u' ], [ 'name' => '360 Extreme Explorer', 'regexp' => '/QIHU 360EE/u', 'type' => Constants\DeviceType::DESKTOP ], [ 'name' => '360 Safe Explorer', 'regexp' => '/QIHU 360SE/u', 'type' => Constants\DeviceType::DESKTOP ], [ 'name' => 'ABrowse', 'regexp' => '/A[Bb]rowse ([0-9.]*)/u' ], @@ -1753,7 +1798,7 @@ private function detectRemainingBrowsers($ua) [ 'name' => 'Baidu Browser', 'regexp' => '/BdMobile\/([0-9.]*)/i' ], [ 'name' => 'Baidu Browser', 'regexp' => '/FlyFlow\/([0-9.]*)/u', 'details' => 2 ], [ 'name' => 'Baidu Browser', 'regexp' => '/BIDUBrowser[ \/]([0-9.]*)/u' ], - [ 'name' => 'Baidu Browser', 'regexp' => '/BaiduHD\/([0-9.]*)/u', 'details' => 2 ], + [ 'name' => 'Baidu Browser', 'regexp' => '/BaiduHD\/([0-9.]*)/u', 'details' => 2, 'type' => Constants\DeviceType::MOBILE ], [ 'name' => 'Baidu Spark', 'regexp' => '/BDSpark\/([0-9.]*)/u', 'details' => 2 ], [ 'name' => 'Baidu Hao123', 'regexp' => '/hao123\/([0-9.]*)/u', 'details' => 2 ], [ 'name' => 'Black Wren', 'regexp' => '/BlackWren\/([0-9.]*)/u', 'details' => 2 ], @@ -1799,6 +1844,7 @@ private function detectRemainingBrowsers($ua) [ 'name' => 'Iron', 'regexp' => '/Iron\/([0-9.]*)/u', 'details' => 2 ], [ 'name' => 'Isis', 'regexp' => '/BrowserServer/u' ], [ 'name' => 'Isis', 'regexp' => '/ISIS\/([0-9.]*)/u', 'details' => 2 ], + [ 'name' => 'iSurf', 'regexp' => '/iSurf version \/v([0-9.]*)/u', 'details' => 2 ], [ 'name' => 'Jumanji', 'regexp' => '/jumanji/u' ], [ 'name' => 'Kazehakase', 'regexp' => '/Kazehakase\/([0-9.]*)/u' ], [ 'name' => 'KChrome', 'regexp' => '/KChrome\/([0-9.]*)/u', 'details' => 3 ], @@ -1819,7 +1865,7 @@ private function detectRemainingBrowsers($ua) [ 'name' => 'MaCross Mobile', 'regexp' => '/MaCross\/([0-9.]*)/u' ], [ 'name' => 'Mammoth', 'regexp' => '/Mammoth\/([0-9.]*)/u' ], // see: https://itunes.apple.com/cn/app/meng-ma-liu-lan-qi/id403760998?mt=8 [ 'name' => 'Maxthon', 'regexp' => '/MxBrowser\/([0-9.]*)/u' ], - [ 'name' => 'Mercury Browser', 'regexp' => '/Mercury\/([0-9.]*)/u' ], + [ 'name' => 'Maxthon', 'regexp' => '/MxBrowser-iPhone\/([0-9.]*)/u' ], [ 'name' => 'MixShark', 'regexp' => '/MixShark\/([0-9.]*)/u' ], [ 'name' => 'mlbrowser', 'regexp' => '/mlbrowser/u' ], [ 'name' => 'Motorola WebKit', 'regexp' => '/MotorolaWebKit(?:\/([0-9.]*))?/u', 'details' => 3 ], diff --git a/src/Analyser/Header/Useragent/Device/Ereader.php b/src/Analyser/Header/Useragent/Device/Ereader.php index 03d9702..bb94ff6 100644 --- a/src/Analyser/Header/Useragent/Device/Ereader.php +++ b/src/Analyser/Header/Useragent/Device/Ereader.php @@ -104,12 +104,14 @@ private function detectKobo($ua) private function detectSonyreader($ua) { if (preg_match('/EBRD([0-9]+)/u', $ua, $match)) { + $model = null; + switch ($match[1]) { case '1101': $model = 'PRS-T1'; break; case '1102': - $model = 'PRS-T1'; + $model = 'PRS-G1'; break; case '1201': $model = 'PRS-T2'; @@ -117,8 +119,6 @@ private function detectSonyreader($ua) case '1301': $model = 'PRS-T3'; break; - default: - $model = null; } $this->data->os->reset(); @@ -138,6 +138,8 @@ private function detectSonyreader($ua) private function detectPocketbook($ua) { if (preg_match('/PocketBook\/([0-9]+)/u', $ua, $match)) { + $model = null; + switch ($match[1]) { case '515': $model = 'Mini'; @@ -172,8 +174,6 @@ private function detectPocketbook($ua) case '840': $model = 'InkPad'; break; - default: - $model = null; } $this->data->os->reset(); diff --git a/src/Analyser/Header/Useragent/Device/Mobile.php b/src/Analyser/Header/Useragent/Device/Mobile.php index 9ac5cf4..b0db7e9 100644 --- a/src/Analyser/Header/Useragent/Device/Mobile.php +++ b/src/Analyser/Header/Useragent/Device/Mobile.php @@ -558,7 +558,7 @@ private function detectGenericMobileModels($ua) $this->data->os->name = 'Nokia Asha Platform'; $this->data->os->version = new Version([ 'value' => '1.0' ]); - if (preg_match('/java_runtime_version=Nokia_Asha_([0-9_]+);/u', $ua, $match)) { + if (preg_match('/java_runtime_version=Nokia_Asha_([0-9_]+)[;\)]/u', $ua, $match)) { $this->data->os->version = new Version([ 'value' => str_replace('_', '.', $match[1]) ]); } } @@ -756,9 +756,6 @@ private function detectGenericMobileModels($ua) case '1.0': $this->data->os->version = new Version([ 'value' => '2.0', 'alias' => '2.0 or earlier' ]); break; - case '2.0': - $this->data->os->version = new Version([ 'value' => '3.0' ]); - break; } } } elseif (preg_match('/(?:Dolfin\/([0-9.]*)|Browser\/Dolfin([0-9.]*))/u', $ua, $match)) { @@ -1064,19 +1061,6 @@ private function detectGenericMobileModels($ua) } } } - - if (! ($this->data->device->identified & Constants\Id::MATCH_UA)) { - $device = Data\DeviceModels::identify('s40', $this->data->device->model); - if ($device->identified) { - $device->identified |= $this->data->device->identified; - $this->data->device = $device; - - if (!isset($this->data->os->name) || $this->data->os->name != 'Series40') { - $this->data->os->name = 'Series40'; - $this->data->os->version = null; - } - } - } } } } diff --git a/src/Analyser/Header/Useragent/Device/Signage.php b/src/Analyser/Header/Useragent/Device/Signage.php index f2f13e9..df83377 100644 --- a/src/Analyser/Header/Useragent/Device/Signage.php +++ b/src/Analyser/Header/Useragent/Device/Signage.php @@ -28,7 +28,7 @@ private function detectSignage($ua) } $this->data->device->setIdentification([ - 'manufacturer' => 'Iadea', + 'manufacturer' => 'IAdea', 'model' => $match[1], 'type' => Constants\DeviceType::SIGNAGE ]); diff --git a/src/Analyser/Header/Useragent/Os.php b/src/Analyser/Header/Useragent/Os.php index 5794b50..21223aa 100644 --- a/src/Analyser/Header/Useragent/Os.php +++ b/src/Analyser/Header/Useragent/Os.php @@ -56,9 +56,6 @@ private function detectDarwin($ua) if (preg_match('/OS (.*) like Mac OS X/u', $ua, $match)) { $this->data->os->version = new Version([ 'value' => str_replace('_', '.', $match[1]) ]); - if ($this->data->os->version->is('<', '4')) { - $this->data->os->alias = 'iPhone OS'; - } } if (preg_match('/iPhone Simulator;/u', $ua)) { @@ -93,32 +90,47 @@ private function detectDarwin($ua) $this->data->os->version = new Version([ 'value' => $match[1], 'details' => 2 ]); } - if (!empty($this->data->os->version)) { - if ($this->data->os->version->is('<', '10.7')) { - $this->data->os->alias = 'Mac OS X'; - } - - if ($this->data->os->version->is('10.7')) { - $this->data->os->version->nickname = 'Lion'; - } elseif ($this->data->os->version->is('10.8')) { - $this->data->os->version->nickname = 'Mountain Lion'; - } elseif ($this->data->os->version->is('10.9')) { - $this->data->os->version->nickname = 'Mavericks'; - } elseif ($this->data->os->version->is('10.10')) { - $this->data->os->version->nickname = 'Yosemite'; - } elseif ($this->data->os->version->is('10.11')) { - $this->data->os->version->nickname = 'El Capitan'; - } - } - $this->data->device->type = Constants\DeviceType::DESKTOP; } /* Darwin */ - if (preg_match('/Darwin[\/ ]([0-9]+.[0-9]+)/u', $ua, $match)) { - $this->data->os->name = "Darwin"; - $this->data->os->version = new Version([ 'value' => $match[1], 'details' => 2 ]); + if (preg_match('/Darwin\/([0-9]+).[0-9]+/u', $ua, $match)) { + if (preg_match('/\((?:x86_64|i386)\)/u', $ua)) { + + /* OS X */ + $this->data->os->name = 'OS X'; + $this->data->device->type = Constants\DeviceType::DESKTOP; + + $version = Data\Darwin::getVersion('osx', $match[1]); + if ($version) { + $this->data->os->version = new Version($version); + } + + if (preg_match('/CFNetwork\/([0-9\.]+)/u', $ua, $match)) { + $version = Data\CFNetwork::getVersion('osx', $match[1]); + if ($version) { + $this->data->os->version = new Version($version); + } + } + } else { + + /* iOS */ + $this->data->os->name = 'iOS'; + $this->data->device->type = Constants\DeviceType::MOBILE; + + $version = Data\Darwin::getVersion('ios', $match[1]); + if ($version) { + $this->data->os->version = new Version($version); + } + + if (preg_match('/CFNetwork\/([0-9\.]+)/u', $ua, $match)) { + $version = Data\CFNetwork::getVersion('ios', $match[1]); + if ($version) { + $this->data->os->version = new Version($version); + } + } + } } } @@ -233,48 +245,6 @@ private function detectAndroid($ua) $this->data->device->identified |= Constants\Id::MATCH_UA; $this->data->device->generic = false; } - if (preg_match('/Pre\/1.0/u', $ua)) { - $this->data->device->manufacturer = 'Palm'; - $this->data->device->model = 'Pre'; - $this->data->device->identified |= Constants\Id::MATCH_UA; - $this->data->device->generic = false; - } - if (preg_match('/Pre\/1.1/u', $ua)) { - $this->data->device->manufacturer = 'Palm'; - $this->data->device->model = 'Pre Plus'; - $this->data->device->identified |= Constants\Id::MATCH_UA; - $this->data->device->generic = false; - } - if (preg_match('/Pre\/1.2/u', $ua)) { - $this->data->device->manufacturer = 'Palm'; - $this->data->device->model = 'Pre 2'; - $this->data->device->identified |= Constants\Id::MATCH_UA; - $this->data->device->generic = false; - } - if (preg_match('/Pre\/3.0/u', $ua)) { - $this->data->device->manufacturer = 'HP'; - $this->data->device->model = 'Pre 3'; - $this->data->device->identified |= Constants\Id::MATCH_UA; - $this->data->device->generic = false; - } - if (preg_match('/Pixi\/1.0/u', $ua)) { - $this->data->device->manufacturer = 'Palm'; - $this->data->device->model = 'Pixi'; - $this->data->device->identified |= Constants\Id::MATCH_UA; - $this->data->device->generic = false; - } - if (preg_match('/Pixi\/1.1/u', $ua)) { - $this->data->device->manufacturer = 'Palm'; - $this->data->device->model = 'Pixi Plus'; - $this->data->device->identified |= Constants\Id::MATCH_UA; - $this->data->device->generic = false; - } - if (preg_match('/P160UN?A?\/1.0/u', $ua)) { - $this->data->device->manufacturer = 'HP'; - $this->data->device->model = 'Veer'; - $this->data->device->identified |= Constants\Id::MATCH_UA; - $this->data->device->generic = false; - } } } @@ -340,7 +310,7 @@ private function detectAndroid($ua) $this->data->os->version = new Version([ 'value' => $match[1], 'details' => 3 ]); } - if (preg_match('/Android 20[0-9]+/u', $ua, $match)) { + if (preg_match('/Android 20[0-9]+\./u', $ua, $match)) { $this->data->os->name = 'Aliyun OS'; $this->data->os->family = new Family([ 'name' => 'Android' ]); $this->data->os->version = null; @@ -351,6 +321,7 @@ private function detectAndroid($ua) if (preg_match('/Baidu Yi/u', $ua)) { $this->data->os->name = 'Baidu Yi'; + $this->data->os->family = new Family([ 'name' => 'Android' ]); $this->data->os->version = null; } @@ -381,6 +352,7 @@ private function detectAndroid($ua) if (preg_match('/WoPhone/u', $ua)) { $this->data->os->name = 'WoPhone'; + $this->data->os->family = new Family([ 'name' => 'Android' ]); if (preg_match('/WoPhone\/([0-9\.]*)/u', $ua, $match)) { $this->data->os->version = new Version([ 'value' => $match[1] ]); @@ -975,16 +947,6 @@ private function detectNokia($ua) } } - $this->data->device->type = Constants\DeviceType::MOBILE; - } elseif (preg_match('/Series30/u', $ua)) { - $this->data->os->name = 'Series30'; - - if (preg_match('/Nokia([^\/]+)\//u', $ua, $match)) { - $this->data->device->manufacturer = 'Nokia'; - $this->data->device->model = Data\DeviceModels::cleanup($match[1]); - $this->data->device->identified |= Constants\Id::PATTERN; - } - $this->data->device->type = Constants\DeviceType::MOBILE; } @@ -1027,34 +989,47 @@ private function detectWebos($ua) $this->data->os->version = new Version([ 'value' => $match[1], 'details' => 2 ]); $this->data->device->type = preg_match('/Tablet/iu', $ua) ? Constants\DeviceType::TABLET : Constants\DeviceType::MOBILE; $this->data->device->generic = false; + } + + if (preg_match('/(?:Spark|elite)\/fzz/u', $ua, $match) || preg_match('/webOSBrowser/u', $ua, $match)) { + $this->data->os->name = 'webOS'; + $this->data->device->type = preg_match('/Tablet/iu', $ua) ? Constants\DeviceType::TABLET : Constants\DeviceType::MOBILE; + $this->data->device->generic = false; + } + if ($this->data->isOs('webOS')) { if (preg_match('/Pre\/1.0/u', $ua)) { + $this->data->device->manufacturer = 'Palm'; $this->data->device->model = 'Pre'; } if (preg_match('/Pre\/1.1/u', $ua)) { + $this->data->device->manufacturer = 'Palm'; $this->data->device->model = 'Pre Plus'; } if (preg_match('/Pre\/1.2/u', $ua)) { + $this->data->device->manufacturer = 'Palm'; $this->data->device->model = 'Pre 2'; } if (preg_match('/Pre\/3.0/u', $ua)) { + $this->data->device->manufacturer = 'Palm'; $this->data->device->model = 'Pre 3'; } if (preg_match('/Pixi\/1.0/u', $ua)) { + $this->data->device->manufacturer = 'Palm'; $this->data->device->model = 'Pixi'; } if (preg_match('/Pixi\/1.1/u', $ua)) { + $this->data->device->manufacturer = 'Palm'; $this->data->device->model = 'Pixi Plus'; } if (preg_match('/P160UN?A?\/1.0/u', $ua)) { + $this->data->device->manufacturer = 'HP'; $this->data->device->model = 'Veer'; } if (preg_match('/TouchPad\/1.0/u', $ua)) { + $this->data->device->manufacturer = 'HP'; $this->data->device->model = 'TouchPad'; } - if (isset($this->data->device->model)) { - $this->data->device->manufacturer = preg_match('/hpwOS/u', $ua) ? 'HP' : 'Palm'; - } if (preg_match('/Emulator\//u', $ua) || preg_match('/Desktop\//u', $ua)) { $this->data->device->type = Constants\DeviceType::EMULATOR; @@ -1064,10 +1039,6 @@ private function detectWebos($ua) $this->data->device->identified |= Constants\Id::MATCH_UA; } - - if (preg_match('/elite\/fzz/u', $ua, $match)) { - $this->data->os->name = 'webOS'; - } } @@ -1172,6 +1143,12 @@ private function detectBlackberry($ua) $this->data->device->identified |= Constants\Id::MATCH_UA; } } + + /* Internal versions of BlackBerry 10 running on the Playbook */ + + if ($this->data->isOs('BlackBerry Tablet OS', '>=', 10)) { + $this->data->os->name = 'BlackBerry'; + } } @@ -1379,7 +1356,9 @@ private function detectUnix($ua) $this->data->os->name = 'LiMo'; $this->data->device->type = Constants\DeviceType::MOBILE; } - } elseif (preg_match('/\(Ubuntu; (Mobile|Tablet)/u', $ua)) { + } + + if (preg_match('/\(Ubuntu; (Mobile|Tablet)/u', $ua)) { $this->data->os->name = 'Ubuntu Touch'; if (preg_match('/\(Ubuntu; Mobile/u', $ua)) { @@ -1388,7 +1367,9 @@ private function detectUnix($ua) if (preg_match('/\(Ubuntu; Tablet/u', $ua)) { $this->data->device->type = Constants\DeviceType::TABLET; } - } elseif (preg_match('/\(Ubuntu ([0-9.]+) like Android/u', $ua, $match)) { + } + + if (preg_match('/(?:\(|; )Ubuntu ([0-9.]+) like Android/u', $ua, $match)) { $this->data->os->name = 'Ubuntu Touch'; $this->data->os->version = new Version([ 'value' => $match[1] ]); $this->data->device->type = Constants\DeviceType::MOBILE; diff --git a/src/Data/CFNetwork.php b/src/Data/CFNetwork.php new file mode 100644 index 0000000..6f7ede7 --- /dev/null +++ b/src/Data/CFNetwork.php @@ -0,0 +1,27 @@ + Constants\DeviceType::MOBILE, - 'identified' => Constants\Id::PATTERN, - 'manufacturer' => 'RIM', - 'model' => 'BlackBerry ' . $model, + 'identified' => Constants\Id::NONE, + 'manufacturer' => null, + 'model' => $model, + 'identifier' => $original, 'generic' => false ]); - if (isset(self::$BLACKBERRY_MODELS[$model])) { - $device->model = 'BlackBerry ' . self::$BLACKBERRY_MODELS[$model] . ' ' . $model; - $device->identified |= Constants\Id::MATCH_UA; + if (is_numeric($model) && intval($model) > 999 && intval($model) < 10000) { + $device = new Device([ + 'type' => Constants\DeviceType::MOBILE, + 'identified' => Constants\Id::PATTERN, + 'manufacturer' => 'RIM', + 'model' => 'BlackBerry ' . $model, + 'generic' => false + ]); + + if (isset(self::$BLACKBERRY_MODELS[$model])) { + $device->model = 'BlackBerry ' . self::$BLACKBERRY_MODELS[$model] . ' ' . $model; + $device->identified |= Constants\Id::MATCH_UA; + } } return $device; diff --git a/templates/detect.js b/templates/detect.js new file mode 100644 index 0000000..50c8551 --- /dev/null +++ b/templates/detect.js @@ -0,0 +1,400 @@ +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + define([], factory); + } else if (typeof module === 'object' && module.exports) { + module.exports = factory(); + } else { + root.WhichBrowser = factory(); + } +}(this, function () { + + var WhichBrowser = function() { this.initialize.apply(this, arguments) }; + WhichBrowser.prototype = { + initialize: function(options) { + this.options = { + }; + + /* $detected->toJavaScript() */ + }, + + a: function(s) { + return (/^[aeiou]/i.test(s) ? 'an ' : 'a ') + s; + }, + + isX: function() { + var valid = true; + var x = arguments[0]; + + if (arguments.length >= 2) { + valid = valid && this[x].name == arguments[1]; + } + + if (arguments.length >= 4 && this[x].version && valid) { + valid = valid && this[x].version.is(arguments[2], arguments[3]); + } + + return valid; + }, + + isBrowser: function() { var a = Array.prototype.slice.call(arguments); a.unshift('browser'); return this.isX.apply(this, a); }, + isEngine: function() { var a = Array.prototype.slice.call(arguments); a.unshift('engine'); return this.isX.apply(this, a); }, + isOs: function() { var a = Array.prototype.slice.call(arguments); a.unshift('os'); return this.isX.apply(this, a); }, + + isDevice: function(d) { + return this.device.series == d || this.device.model == d; + }, + + isType: function() { + var valid = false; + for (var a = 0; a < arguments.length; a++) valid = valid || arguments[a] == this.device.type; + return valid; + }, + + toJSON: function() { + return { + browser: this.browser.toJSON(), + os: this.os.toJSON(), + engine: this.engine.toJSON(), + device: this.device.toJSON() + }; + }, + + toString: function() { + var prefix = this.camouflage ? 'an unknown browser that imitates ' : ''; + var browser = this.browser.toString(); + var os = this.os.toString(); + var engine = this.engine.toString(); + var device = this.device.toString(); + + if (!device && !os && this.device.type == 'television') device = 'television'; + if (!device && this.device.type == 'emulator') device = 'emulator'; + + if (browser && os && device) return prefix + browser + ' on ' + this.a(device) + ' running ' + os; + if (browser && !os && device) return prefix + browser + ' on ' + this.a(device); + if (browser && os && !device) return prefix + browser + ' on ' + os; + if (!browser && os && device) return prefix + this.a(device) + ' running ' + os; + if (browser && !os && !device) return prefix + browser; + if (!browser && !os && device) return prefix + this.a(device); + if (this.device.type == 'desktop' && os && engine != '' && !device) return 'an unknown browser based on ' + engine + ' running on ' + os; + if (this.browser.stock && os && !device) return os; + if (this.browser.stock && engine != '' && !device) return 'an unknown browser based on ' + engine; + + return 'an unknown browser'; + } + }; + + var Using = function() { this.initialize.apply(this, Array.prototype.slice.call(arguments)) }; + Using.prototype = { + initialize: function(v) { + this.name = v.name || null; + this.version = v.version || null; + }, + + toJSON: function() { + return { + name: this.name, + version: (this.version) ? this.version.toJSON() : null, + }; + }, + + toString: function() { + return (this.name ? this.name + (this.version && !this.version.hidden ? ' ' + this.version.toString() : '') : ''); + } + }; + + var Family = function() { this.initialize.apply(this, Array.prototype.slice.call(arguments)) }; + Family.prototype = { + initialize: function(v) { + this.name = v.name || null; + this.version = v.version || null; + }, + + toJSON: function() { + return { + name: this.name, + version: (this.version) ? this.version.toJSON() : null, + }; + }, + + toString: function() { + return (this.name ? this.name + (this.version && !this.version.hidden ? ' ' + this.version.toString() : '') : ''); + } + }; + + var Browser = function() { this.initialize.apply(this, Array.prototype.slice.call(arguments)) }; + Browser.prototype = { + initialize: function(v) { + this.name = v.name || null; + this.alias = v.alias || null; + this.version = v.version || null; + this.using = v.using || null; + this.family = v.family || null; + + this.stock = v.stock || false; + this.channel = v.channel || null; + this.mode = v.mode || null; + this.hidden = v.hidden || false; + }, + + toJSON: function() { + return { + name: this.name, + alias: this.alias, + version: (this.version) ? this.version.toJSON() : null, + stock: this.stock, + channel: this.channel, + mode: this.mode, + hidden: this.hidden + }; + }, + + toString: function() { + var name = this.alias ? this.alias : (this.name ? this.name : ''); + if (name != '') return (name ? name + (this.channel ? ' ' + this.channel : '') + (this.version && !this.version.hidden ? ' ' + this.version.toString() : '') : ''); + if (this.using) return this.using.toString(); + return ''; + } + }; + + var Engine = function() { this.initialize.apply(this, Array.prototype.slice.call(arguments)) }; + Engine.prototype = { + initialize: function(v) { + this.name = v.name || null; + this.alias = v.alias || null; + this.version = v.version || null; + }, + + toJSON: function() { + return { + name: this.name, + version: (this.version) ? this.version.toJSON() : null + }; + }, + + toString: function() { + var name = this.alias ? this.alias : (this.name ? this.name : ''); + return name; + } + }; + + var Os = function() { this.initialize.apply(this, Array.prototype.slice.call(arguments)) }; + Os.prototype = { + initialize: function(v) { + this.name = v.name || null; + this.family = v.family || null; + this.alias = v.alias || null; + this.version = v.version || null; + }, + + toJSON: function() { + return { + name: this.name, + family: this.family, + alias: this.alias, + version: (this.version) ? this.version.toJSON() : null + }; + }, + + toString: function() { + var name = this.alias ? this.alias : (this.name ? this.name : ''); + return (name ? name + (this.version && !this.version.hidden ? ' ' + this.version.toString() : '') : ''); + } + }; + + var Device = function() { this.initialize.apply(this, Array.prototype.slice.call(arguments)) }; + Device.prototype = { + initialize: function(v) { + this.type = v.type || null; + this.identified = v.identified || false; + this.manufacturer = v.manufacturer || null; + this.model = v.model || null; + this.series = v.series || null; + }, + + toJSON: function() { + return { + type: this.type, + identified: this.identified, + manufacturer: this.manufacturer, + model: this.model, + series: this.series + }; + }, + + toString: function() { + if (this.identified) { + var manufacturer = this.manufacturer || ''; + var model = ((this.model || '') + ' ' + (this.series || '')).trim(); + + if (model.indexOf(manufacturer) === 0) { + manufacturer = ''; + } + + return (manufacturer + ' ' + model).trim(); + } + + return (this.model ? 'unrecognized device (' + this.model + ')' : ''); + } + }; + + var Version = function() { this.initialize.apply(this, Array.prototype.slice.call(arguments)) }; + Version.prototype = { + initialize: function(v) { + this.original = v.value || null; + this.alias = v.alias || null; + this.nickname = v.nickname || null; + this.details = v.details || null; + this.hidden = v.hidden || null; + this.builds = typeof v.builds != 'undefined' ? v.builds : true; + + this.major = 0; + this.minor = null; + this.revision = null; + this.build = null; + this.type = ''; + + var match; + if (match = /([0-9]+)(?:\.([0-9]+))?(?:\.([0-9]+))?(?:\.([0-9]+))?(?:([ab])([0-9]+))?/.exec(this.original)) { + if (typeof match[1] != 'undefined') { + this.major = match[1]; + } + + if (typeof match[2] != 'undefined') { + this.minor = match[2]; + } + + if (typeof match[3] != 'undefined') { + this.revision = match[3]; + } + + if (typeof match[4] != 'undefined') { + this.build = match[4]; + } + + if (typeof match[5] != 'undefined') { + switch(match[5]) { + case 'a': this.type = 'alpha'; break; + case 'b': this.type = 'beta'; break; + } + + if (typeof match[6] != 'undefined') { + this.build = match[6]; + } + } + } + }, + + is: function(v) { + var valid = false; + + if (arguments.length > 0) { + var operator = '='; + var compare = null; + + if (arguments.length == 1) { + compare = new Version({ value: arguments[0] }); + } + + if (arguments.length >= 2) { + operator = arguments[0]; + compare = new Version({ value: arguments[1] }); + } + + if (compare) { + var v1 = v2 = ''; + + if (compare.major && this.major) { + v1 += this.major; + v2 += compare.major; + + if (compare.minor && this.minor) { + v1 += '.' + ('0000' + this.minor).slice(-4); + v2 += '.' + ('0000' + compare.minor).slice(-4); + + if (compare.revision && this.revision) { + v1 += ('0000' + this.revision).slice(-4); + v2 += ('0000' + compare.revision).slice(-4); + } + } + } + + v1 = parseFloat(v1); + v2 = parseFloat(v2); + + switch (operator) { + case '<': valid = v1 < v2; break; + case '<=': valid = v1 <= v2; break; + case '=': valid = v1 == v2; break; + case '>': valid = v1 > v2; break; + case '>=': valid = v1 >= v2; break; + } + } + + return valid; + } + + return false; + }, + + valueOf: function() { + return parseFloat('' + this.major + '.' + ('0000' + this.minor).slice(-4) + ('0000' + this.revision).slice(-4)); + }, + + toJSON: function() { + var o = { + value: this.toString(), + details: this.details, + hidden: this.hidden, + original: this.original, + major: this.major, + minor: this.minor, + build: this.build, + revision: this.revision + }; + + if (this.type) o.type = this.type; + if (this.alias) o.alias = this.alias; + if (this.nickname) o.nickname = this.nickname; + + return o; + }, + + toString: function() { + if (this.alias) + return this.alias; + + var version = ''; + + if (this.nickname) { + version += this.nickname + ' '; + } + + if (this.major || this.minor) { + var v = []; + v.push(this.major); + if (this.minor != '' && this.minor != null) v.push(this.minor); + if (this.revision != '' && this.revision != null) v.push(this.revision); + if (this.type == '' && this.build) v.push(this.build); + if (this.details < 0) v.splice(this.details, 0 - this.details); + if (this.details > 0) v.splice(this.details, v.length - this.details); + + if (!this.builds) { + for (var i = 0; i < v.length; i++) { + if (v[i] > 999) { + v.splice(i, 1); + i--; + } + } + } + + version += v.join('.'); + + if (this.type != '') version += this.type[0] + (this.build ? this.build : ''); + } + + return version; + } + }; + + return WhichBrowser; +}));