diff --git a/devices.json b/devices.json index afdbf98..7f0a648 100644 --- a/devices.json +++ b/devices.json @@ -1 +1 @@ -{"version": 1, "devices": [{"show-by-default": false, "modes": [], "title": "Amazon Kindle Fire First Generation", "screen": {"horizontal": {"width": 600, "height": 1024}, "device-pixel-ratio": 1, "vertical": {"width": 1024, "height": 600}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-us; Silk/1.0.141.16-Gen4_11004310) AppleWebkit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16 Silk-Accelerated=true", "type": "tablet"}, {"show-by-default": false, "modes": [], "title": "Amazon Kindle Fire HDX 7", "screen": {"horizontal": {"width": 1200, "height": 1920}, "device-pixel-ratio": 2, "vertical": {"width": 1920, "height": 1200}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; en-us; KFTHWI Build/JDQ39) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.13 Safari/535.19 Silk-Accelerated=true", "type": "tablet"}, {"show-by-default": false, "modes": [], "title": "Amazon Kindle Fire HDX 8.9", "screen": {"horizontal": {"width": 1600, "height": 2560}, "device-pixel-ratio": 2, "vertical": {"width": 2560, "height": 1600}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; en-us; KFAPWI Build/JDQ39) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.13 Safari/535.19 Silk-Accelerated=true", "type": "tablet"}, {"//": "iPad (1st generation), iPad 2, iPad Mini (1st generation), have same device characteristics", "show-by-default": false, "modes": [], "title": "Apple iPad Mini", "screen": {"horizontal": {"width": 768, "height": 1024}, "device-pixel-ratio": 1, "vertical": {"width": 1024, "height": 768}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (iPad; CPU OS 4_3_5 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8L1 Safari/6533.18.5", "type": "tablet"}, {"//": "iPad (3rd generation), iPad (4th generation), iPad Air, iPad Air 2 have same display", "show-by-default": false, "modes": [], "title": "Apple iPad", "screen": {"horizontal": {"width": 768, "height": 1024}, "device-pixel-ratio": 2, "vertical": {"width": 1024, "height": 768}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (iPad; CPU OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53", "type": "tablet"}, {"//": "iPad Mini (1st generation), iPad (1st generation), iPad 2 have same device characteristics", "show-by-default": false, "modes": [], "title": "Apple iPad Mini 2 / 3", "screen": {"horizontal": {"width": 768, "height": 1024}, "device-pixel-ratio": 2, "vertical": {"width": 1024, "height": 768}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (iPad; CPU OS 7_0_4 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11B554a Safari/9537.53", "type": "tablet"}, {"show-by-default": false, "modes": [], "title": "Apple iPhone 3GS", "screen": {"horizontal": {"width": 480, "height": 320}, "device-pixel-ratio": 1, "vertical": {"width": 320, "height": 480}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_2_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "Apple iPhone 4", "screen": {"horizontal": {"width": 480, "height": 320}, "device-pixel-ratio": 2, "vertical": {"width": 320, "height": 480}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_2_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5", "type": "phone"}, {"//": "iPhone 5, iPhone 5S, iPhone 5c have identical display & screen characteristics", "show-by-default": true, "modes": [], "title": "Apple iPhone 5", "screen": {"horizontal": {"width": 568, "height": 320}, "device-pixel-ratio": 2, "vertical": {"width": 320, "height": 568}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X; en-us) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53", "type": "phone"}, {"show-by-default": true, "modes": [], "title": "Apple iPhone 6", "screen": {"horizontal": {"width": 667, "height": 375}, "device-pixel-ratio": 2, "vertical": {"width": 375, "height": 667}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/600.1.3 (KHTML, like Gecko) Version/8.0 Mobile/12A4345d Safari/600.1.4", "type": "phone"}, {"show-by-default": true, "modes": [], "title": "Apple iPhone 6 Plus", "screen": {"horizontal": {"width": 736, "height": 414}, "device-pixel-ratio": 3, "vertical": {"width": 414, "height": 736}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/600.1.3 (KHTML, like Gecko) Version/8.0 Mobile/12A4345d Safari/600.1.4", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "BlackBerry Classic", "screen": {"horizontal": {"width": 374, "height": 390}, "device-pixel-ratio": 1.84375, "vertical": {"width": 390, "height": 374}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (BB10; Kbd) AppleWebKit/537.35+ (KHTML, like Gecko) Version/10.3.1.1418 Mobile Safari/537.35+", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "BlackBerry Passport", "screen": {"horizontal": {"width": 462, "height": 504}, "device-pixel-ratio": 2.856250047683716, "vertical": {"width": 504, "height": 462}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (BB10; Kbd) AppleWebKit/537.35+ (KHTML, like Gecko) Version/10.3.0.1418 Mobile Safari/537.35+", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "BlackBerry PlayBook", "screen": {"horizontal": {"width": 600, "height": 1024}, "device-pixel-ratio": 1, "vertical": {"width": 1024, "height": 600}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/7.2.1.0 Safari/536.2+", "type": "tablet"}, {"show-by-default": false, "modes": [], "title": "BlackBerry Z10", "screen": {"horizontal": {"width": 640, "height": 384}, "device-pixel-ratio": 2, "vertical": {"width": 384, "height": 640}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.0.9.2372 Mobile Safari/537.10+", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "BlackBerry Z30", "screen": {"horizontal": {"width": 640, "height": 360}, "device-pixel-ratio": 2, "vertical": {"width": 360, "height": 640}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.0.9.2372 Mobile Safari/537.10+", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "Generic notebook", "screen": {"horizontal": {"width": 800, "height": 1280}, "device-pixel-ratio": 1, "vertical": {"width": 1280, "height": 800}}, "capabilities": [], "user-agent": "", "type": "notebook"}, {"show-by-default": false, "modes": [], "title": "Google Nexus 10", "screen": {"horizontal": {"width": 800, "height": 1280}, "device-pixel-ratio": 2, "vertical": {"width": 1280, "height": 800}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; Android 4.3; Nexus 10 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.72 Safari/537.36", "type": "tablet"}, {"show-by-default": false, "modes": [], "title": "Google Nexus 4", "screen": {"horizontal": {"width": 640, "height": 384}, "device-pixel-ratio": 2, "vertical": {"width": 384, "height": 640}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.122 Mobile Safari/537.36", "type": "phone"}, {"show-by-default": true, "modes": [{"images": [{"src": "google-nexus-5/navigation-v-1x.png", "scale": 1}, {"src": "google-nexus-5/navigation-v-2x.png", "scale": 2}], "page-rect": {"width": 360, "top": 80, "height": 512, "left": 0}, "orientation": "vertical", "title": "With navigation bar"}, {"images": [{"src": "google-nexus-5/clear-v-1x.png", "scale": 1}, {"src": "google-nexus-5/clear-v-2x.png", "scale": 2}], "page-rect": {"width": 360, "top": 25, "height": 567, "left": 0}, "orientation": "vertical", "title": "Without navigation bar"}, {"images": [{"src": "google-nexus-5/keyboard-v-1x.png", "scale": 1}, {"src": "google-nexus-5/keyboard-v-2x.png", "scale": 2}], "page-rect": {"width": 360, "top": 80, "height": 248, "left": 0}, "orientation": "vertical", "title": "With keyboard"}, {"images": [{"src": "google-nexus-5/navigation-h-1x.png", "scale": 1}, {"src": "google-nexus-5/navigation-h-2x.png", "scale": 2}], "page-rect": {"width": 598, "top": 80, "height": 280, "left": 0}, "orientation": "horizontal", "title": "With navigation bar"}, {"images": [{"src": "google-nexus-5/clear-h-1x.png", "scale": 1}, {"src": "google-nexus-5/clear-h-2x.png", "scale": 2}], "page-rect": {"width": 598, "top": 25, "height": 335, "left": 0}, "orientation": "horizontal", "title": "Without navigation bar"}, {"images": [{"src": "google-nexus-5/keyboard-h-1x.png", "scale": 1}, {"src": "google-nexus-5/keyboard-h-2x.png", "scale": 2}], "page-rect": {"width": 598, "top": 80, "height": 78, "left": 0}, "orientation": "horizontal", "title": "With keyboard"}], "title": "Google Nexus 5", "screen": {"horizontal": {"width": 640, "outline": {"images": [{"src": "google-nexus-5/outline-h-1x.png", "scale": 1}, {"src": "google-nexus-5/outline-h-2x.png", "scale": 2}], "insets": {"top": 20, "left": 86}}, "height": 360}, "device-pixel-ratio": 3, "vertical": {"width": 360, "outline": {"images": [{"src": "google-nexus-5/outline-v-1x.png", "scale": 1}, {"src": "google-nexus-5/outline-v-2x.png", "scale": 2}], "insets": {"top": 86, "left": 20}}, "height": 640}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; Android 4.4.4; Nexus 5 Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.114 Mobile Safari/537.36", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "Google Nexus 7 (1st gen)", "screen": {"horizontal": {"width": 604, "height": 966}, "device-pixel-ratio": 1.325, "vertical": {"width": 966, "height": 604}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; Android 4.3; Nexus 7 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.72 Safari/537.36", "type": "tablet"}, {"show-by-default": true, "modes": [], "title": "Google Nexus 7", "screen": {"horizontal": {"width": 600, "height": 960}, "device-pixel-ratio": 2, "vertical": {"width": 960, "height": 600}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; Android 4.3; Nexus 7 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.72 Safari/537.36", "type": "tablet"}, {"show-by-default": false, "modes": [], "title": "Google Nexus S", "screen": {"horizontal": {"width": 533, "height": 320}, "device-pixel-ratio": 1.5, "vertical": {"width": 320, "height": 533}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; Nexus S Build/GRJ22) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "HTC Evo, Touch HD, Desire HD, Desire", "screen": {"horizontal": {"width": 533, "height": 320}, "device-pixel-ratio": 1.5, "vertical": {"width": 320, "height": 533}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 2.2; en-us; Sprint APA9292KT Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "HTC One M7", "screen": {"horizontal": {"width": 615, "height": 360}, "device-pixel-ratio": 3, "vertical": {"width": 360, "height": 615}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 4.4.3; en-us; HTC_One/6.14.111.2 Build/KTU84L) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "HTC One X, EVO LTE", "screen": {"horizontal": {"width": 640, "height": 360}, "device-pixel-ratio": 2, "vertical": {"width": 360, "height": 640}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; Android 4.0.3; HTC One X Build/IML74K) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "HTC Sensation, Evo 3D", "screen": {"horizontal": {"width": 640, "height": 360}, "device-pixel-ratio": 1.5, "vertical": {"width": 360, "height": 640}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 4.0.3; en-us; HTC Sensation Build/IML74K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "LG Optimus 2X, Optimus 3D, Optimus Black", "screen": {"horizontal": {"width": 533, "height": 320}, "device-pixel-ratio": 1.5, "vertical": {"width": 320, "height": 533}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 2.2; en-us; LG-P990/V08c Build/FRG83) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1 MMS/LG-Android-MMS-V1.0/1.2", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "LG Optimus G", "screen": {"horizontal": {"width": 640, "height": 384}, "device-pixel-ratio": 2, "vertical": {"width": 384, "height": 640}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; Android 4.0; LG-E975 Build/IMM76L) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "LG Optimus LTE, Optimus 4X HD", "screen": {"horizontal": {"width": 753, "height": 424}, "device-pixel-ratio": 1.7, "vertical": {"width": 424, "height": 753}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 2.3; en-us; LG-P930 Build/GRJ90) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "LG Optimus One", "screen": {"horizontal": {"width": 320, "height": 213}, "device-pixel-ratio": 1.5, "vertical": {"width": 213, "height": 320}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 2.2.1; en-us; LG-MS690 Build/FRG83) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "Motorola Defy, Droid, Droid X, Milestone", "screen": {"horizontal": {"width": 569, "height": 320}, "device-pixel-ratio": 1.5, "vertical": {"width": 320, "height": 569}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 2.0; en-us; Milestone Build/ SHOLS_U2_01.03.1) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "Motorola Droid 3, Droid 4, Droid Razr, Atrix 4G, Atrix 2", "screen": {"horizontal": {"width": 960, "height": 540}, "device-pixel-ratio": 1, "vertical": {"width": 540, "height": 960}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 2.2; en-us; Droid Build/FRG22D) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "Motorola Droid Razr HD", "screen": {"horizontal": {"width": 1280, "height": 720}, "device-pixel-ratio": 1, "vertical": {"width": 720, "height": 1280}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 2.3; en-us; DROID RAZR 4G Build/6.5.1-73_DHD-11_M1-29) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "Motorola Xoom, Xyboard", "screen": {"horizontal": {"width": 800, "height": 1280}, "device-pixel-ratio": 1, "vertical": {"width": 1280, "height": 800}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/525.10 (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2", "type": "tablet"}, {"show-by-default": false, "modes": [], "title": "Nokia C5, C6, C7, N97, N8, X7", "screen": {"horizontal": {"width": 640, "height": 360}, "device-pixel-ratio": 1, "vertical": {"width": 360, "height": 640}}, "capabilities": ["touch", "mobile"], "user-agent": "NokiaN97/21.1.107 (SymbianOS/9.4; Series60/5.0 Mozilla/5.0; Profile/MIDP-2.1 Configuration/CLDC-1.1) AppleWebkit/525 (KHTML, like Gecko) BrowserNG/7.1.4", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "Nokia Lumia 7X0, Lumia 8XX, Lumia 900, N800, N810, N900", "screen": {"horizontal": {"width": 533, "height": 320}, "device-pixel-ratio": 1.5, "vertical": {"width": 320, "height": 533}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 820)", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "Notebook with HiDPI screen", "screen": {"horizontal": {"width": 900, "height": 1440}, "device-pixel-ratio": 2, "vertical": {"width": 1440, "height": 900}}, "capabilities": [], "user-agent": "", "type": "notebook"}, {"show-by-default": true, "modes": [], "title": "Notebook with touch", "screen": {"horizontal": {"width": 950, "height": 1280}, "device-pixel-ratio": 1, "vertical": {"width": 1280, "height": 950}}, "capabilities": ["touch"], "user-agent": "", "type": "notebook"}, {"show-by-default": false, "modes": [], "title": "Samsung Galaxy Note", "screen": {"horizontal": {"width": 640, "height": 400}, "device-pixel-ratio": 2, "vertical": {"width": 400, "height": 640}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 2.3; en-us; SAMSUNG-SGH-I717 Build/GINGERBREAD) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "Samsung Galaxy Note II", "screen": {"horizontal": {"width": 640, "height": 360}, "device-pixel-ratio": 2, "vertical": {"width": 360, "height": 640}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 4.1; en-us; GT-N7100 Build/JRO03C) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", "type": "phone"}, {"show-by-default": true, "modes": [], "title": "Samsung Galaxy Note 3", "screen": {"horizontal": {"width": 640, "height": 360}, "device-pixel-ratio": 3, "vertical": {"width": 360, "height": 640}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 4.3; en-us; SM-N900T Build/JSS15J) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "Samsung Galaxy S III, Galaxy Nexus", "screen": {"horizontal": {"width": 640, "height": 360}, "device-pixel-ratio": 2, "vertical": {"width": 360, "height": 640}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 4.0; en-us; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "Samsung Galaxy S, S II, W", "screen": {"horizontal": {"width": 533, "height": 320}, "device-pixel-ratio": 1.5, "vertical": {"width": 320, "height": 533}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 2.1; en-us; GT-I9000 Build/ECLAIR) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2", "type": "phone"}, {"show-by-default": true, "modes": [], "title": "Samsung Galaxy S4", "screen": {"horizontal": {"width": 640, "height": 360}, "device-pixel-ratio": 3, "vertical": {"width": 360, "height": 640}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; Android 4.2.2; GT-I9505 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.59 Mobile Safari/537.36", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "Samsung Galaxy Tab", "screen": {"horizontal": {"width": 600, "height": 1024}, "device-pixel-ratio": 1, "vertical": {"width": 1024, "height": 600}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 2.2; en-us; SCH-I800 Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", "type": "tablet"}, {"show-by-default": false, "modes": [], "title": "Samsung Galaxy Tab 7.7, 8.9, 10.1", "screen": {"horizontal": {"width": 800, "height": 1280}, "device-pixel-ratio": 1, "vertical": {"width": 1280, "height": 800}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 2.2; en-us; SCH-I800 Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", "type": "tablet"}, {"show-by-default": false, "modes": [], "title": "Sony Xperia S, Ion", "screen": {"horizontal": {"width": 640, "height": 360}, "device-pixel-ratio": 2, "vertical": {"width": 360, "height": 640}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 4.0; en-us; LT28at Build/6.1.C.1.111) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "Sony Xperia Sola, U", "screen": {"horizontal": {"width": 854, "height": 480}, "device-pixel-ratio": 1, "vertical": {"width": 480, "height": 854}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 2.3; en-us; SonyEricssonST25i Build/6.0.B.1.564) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "Sony Xperia Z, Z1", "screen": {"horizontal": {"width": 640, "height": 360}, "device-pixel-ratio": 3, "vertical": {"width": 360, "height": 640}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 4.2; en-us; SonyC6903 Build/14.1.G.1.518) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", "type": "phone"}]} \ No newline at end of file +{"version": 1, "devices": [{"show-by-default": false, "modes": [], "title": "Sony Xperia Sola, U", "screen": {"horizontal": {"width": 854, "height": 480}, "device-pixel-ratio": 1, "vertical": {"width": 480, "height": 854}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 2.3; en-us; SonyEricssonST25i Build/6.0.B.1.564) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "LG Optimus G", "screen": {"horizontal": {"width": 640, "height": 384}, "device-pixel-ratio": 2, "vertical": {"width": 384, "height": 640}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; Android 4.0; LG-E975 Build/IMM76L) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "LG Optimus LTE, Optimus 4X HD", "screen": {"horizontal": {"width": 753, "height": 424}, "device-pixel-ratio": 1.7, "vertical": {"width": 424, "height": 753}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 2.3; en-us; LG-P930 Build/GRJ90) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "Amazon Kindle Fire HDX 7", "screen": {"horizontal": {"width": 1200, "height": 1920}, "device-pixel-ratio": 2, "vertical": {"width": 1920, "height": 1200}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; en-us; KFTHWI Build/JDQ39) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.13 Safari/535.19 Silk-Accelerated=true", "type": "tablet"}, {"show-by-default": false, "modes": [], "title": "Samsung Galaxy Note II", "screen": {"horizontal": {"width": 640, "height": 360}, "device-pixel-ratio": 2, "vertical": {"width": 360, "height": 640}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 4.1; en-us; GT-N7100 Build/JRO03C) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "HTC One X, EVO LTE", "screen": {"horizontal": {"width": 640, "height": 360}, "device-pixel-ratio": 2, "vertical": {"width": 360, "height": 640}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; Android 4.0.3; HTC One X Build/IML74K) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19", "type": "phone"}, {"//": "iPhone 5, iPhone 5S, iPhone 5c have identical display & screen characteristics", "show-by-default": true, "modes": [], "title": "Apple iPhone 5", "screen": {"horizontal": {"width": 568, "height": 320}, "device-pixel-ratio": 2, "vertical": {"width": 320, "height": 568}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X; en-us) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "Amazon Kindle Fire HDX 8.9", "screen": {"horizontal": {"width": 1600, "height": 2560}, "device-pixel-ratio": 2, "vertical": {"width": 2560, "height": 1600}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; en-us; KFAPWI Build/JDQ39) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.13 Safari/535.19 Silk-Accelerated=true", "type": "tablet"}, {"show-by-default": true, "modes": [], "title": "Google Nexus 7", "screen": {"horizontal": {"width": 600, "height": 960}, "device-pixel-ratio": 2, "vertical": {"width": 960, "height": 600}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; Android 4.3; Nexus 7 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.72 Safari/537.36", "type": "tablet"}, {"show-by-default": false, "modes": [], "title": "Apple iPhone 4", "screen": {"horizontal": {"width": 480, "height": 320}, "device-pixel-ratio": 2, "vertical": {"width": 320, "height": 480}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_2_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "Generic notebook", "screen": {"horizontal": {"width": 800, "height": 1280}, "device-pixel-ratio": 1, "vertical": {"width": 1280, "height": 800}}, "capabilities": [], "user-agent": "", "type": "notebook"}, {"show-by-default": true, "modes": [{"images": [{"src": "google-nexus-5/navigation-v-1x.png", "scale": 1}, {"src": "google-nexus-5/navigation-v-2x.png", "scale": 2}], "page-rect": {"width": 360, "top": 80, "height": 512, "left": 0}, "orientation": "vertical", "title": "With navigation bar"}, {"images": [{"src": "google-nexus-5/clear-v-1x.png", "scale": 1}, {"src": "google-nexus-5/clear-v-2x.png", "scale": 2}], "page-rect": {"width": 360, "top": 25, "height": 567, "left": 0}, "orientation": "vertical", "title": "Without navigation bar"}, {"images": [{"src": "google-nexus-5/keyboard-v-1x.png", "scale": 1}, {"src": "google-nexus-5/keyboard-v-2x.png", "scale": 2}], "page-rect": {"width": 360, "top": 80, "height": 248, "left": 0}, "orientation": "vertical", "title": "With keyboard"}, {"images": [{"src": "google-nexus-5/navigation-h-1x.png", "scale": 1}, {"src": "google-nexus-5/navigation-h-2x.png", "scale": 2}], "page-rect": {"width": 598, "top": 80, "height": 280, "left": 0}, "orientation": "horizontal", "title": "With navigation bar"}, {"images": [{"src": "google-nexus-5/clear-h-1x.png", "scale": 1}, {"src": "google-nexus-5/clear-h-2x.png", "scale": 2}], "page-rect": {"width": 598, "top": 25, "height": 335, "left": 0}, "orientation": "horizontal", "title": "Without navigation bar"}, {"images": [{"src": "google-nexus-5/keyboard-h-1x.png", "scale": 1}, {"src": "google-nexus-5/keyboard-h-2x.png", "scale": 2}], "page-rect": {"width": 598, "top": 80, "height": 78, "left": 0}, "orientation": "horizontal", "title": "With keyboard"}], "title": "Google Nexus 5", "screen": {"horizontal": {"width": 640, "outline": {"images": [{"src": "google-nexus-5/outline-h-1x.png", "scale": 1}, {"src": "google-nexus-5/outline-h-2x.png", "scale": 2}], "insets": {"top": 20, "left": 86}}, "height": 360}, "device-pixel-ratio": 3, "vertical": {"width": 360, "outline": {"images": [{"src": "google-nexus-5/outline-v-1x.png", "scale": 1}, {"src": "google-nexus-5/outline-v-2x.png", "scale": 2}], "insets": {"top": 86, "left": 20}}, "height": 640}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; Android 4.4.4; Nexus 5 Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.114 Mobile Safari/537.36", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "Motorola Xoom, Xyboard", "screen": {"horizontal": {"width": 800, "height": 1280}, "device-pixel-ratio": 1, "vertical": {"width": 1280, "height": 800}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/525.10 (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2", "type": "tablet"}, {"show-by-default": false, "modes": [], "title": "HTC One M7", "screen": {"horizontal": {"width": 615, "height": 360}, "device-pixel-ratio": 3, "vertical": {"width": 360, "height": 615}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 4.4.3; en-us; HTC_One/6.14.111.2 Build/KTU84L) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "Notebook with HiDPI screen", "screen": {"horizontal": {"width": 900, "height": 1440}, "device-pixel-ratio": 2, "vertical": {"width": 1440, "height": 900}}, "capabilities": [], "user-agent": "", "type": "notebook"}, {"show-by-default": false, "modes": [], "title": "Nokia C5, C6, C7, N97, N8, X7", "screen": {"horizontal": {"width": 640, "height": 360}, "device-pixel-ratio": 1, "vertical": {"width": 360, "height": 640}}, "capabilities": ["touch", "mobile"], "user-agent": "NokiaN97/21.1.107 (SymbianOS/9.4; Series60/5.0 Mozilla/5.0; Profile/MIDP-2.1 Configuration/CLDC-1.1) AppleWebkit/525 (KHTML, like Gecko) BrowserNG/7.1.4", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "BlackBerry Passport", "screen": {"horizontal": {"width": 462, "height": 504}, "device-pixel-ratio": 2.856250047683716, "vertical": {"width": 504, "height": 462}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (BB10; Kbd) AppleWebKit/537.35+ (KHTML, like Gecko) Version/10.3.0.1418 Mobile Safari/537.35+", "type": "phone"}, {"//": "iPad (3rd generation), iPad (4th generation), iPad Air, iPad Air 2 have same display", "show-by-default": false, "modes": [], "title": "Apple iPad", "screen": {"horizontal": {"width": 768, "height": 1024}, "device-pixel-ratio": 2, "vertical": {"width": 1024, "height": 768}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (iPad; CPU OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53", "type": "tablet"}, {"show-by-default": true, "modes": [], "title": "Notebook with touch", "screen": {"horizontal": {"width": 950, "height": 1280}, "device-pixel-ratio": 1, "vertical": {"width": 1280, "height": 950}}, "capabilities": ["touch"], "user-agent": "", "type": "notebook"}, {"show-by-default": false, "modes": [], "title": "Sony Xperia Z, Z1", "screen": {"horizontal": {"width": 640, "height": 360}, "device-pixel-ratio": 3, "vertical": {"width": 360, "height": 640}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 4.2; en-us; SonyC6903 Build/14.1.G.1.518) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "Sony Xperia S, Ion", "screen": {"horizontal": {"width": 640, "height": 360}, "device-pixel-ratio": 2, "vertical": {"width": 360, "height": 640}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 4.0; en-us; LT28at Build/6.1.C.1.111) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "Samsung Galaxy Tab", "screen": {"horizontal": {"width": 600, "height": 1024}, "device-pixel-ratio": 1, "vertical": {"width": 1024, "height": 600}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 2.2; en-us; SCH-I800 Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", "type": "tablet"}, {"//": "iPad Mini (1st generation), iPad (1st generation), iPad 2 have same device characteristics", "show-by-default": false, "modes": [], "title": "Apple iPad Mini 2 / 3", "screen": {"horizontal": {"width": 768, "height": 1024}, "device-pixel-ratio": 2, "vertical": {"width": 1024, "height": 768}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (iPad; CPU OS 7_0_4 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11B554a Safari/9537.53", "type": "tablet"}, {"show-by-default": false, "modes": [], "title": "Motorola Droid Razr HD", "screen": {"horizontal": {"width": 1280, "height": 720}, "device-pixel-ratio": 1, "vertical": {"width": 720, "height": 1280}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 2.3; en-us; DROID RAZR 4G Build/6.5.1-73_DHD-11_M1-29) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", "type": "phone"}, {"show-by-default": true, "modes": [], "title": "Apple iPhone 6 Plus", "screen": {"horizontal": {"width": 736, "height": 414}, "device-pixel-ratio": 3, "vertical": {"width": 414, "height": 736}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/600.1.3 (KHTML, like Gecko) Version/8.0 Mobile/12A4345d Safari/600.1.4", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "HTC Sensation, Evo 3D", "screen": {"horizontal": {"width": 640, "height": 360}, "device-pixel-ratio": 1.5, "vertical": {"width": 360, "height": 640}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 4.0.3; en-us; HTC Sensation Build/IML74K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "Motorola Defy, Droid, Droid X, Milestone", "screen": {"horizontal": {"width": 569, "height": 320}, "device-pixel-ratio": 1.5, "vertical": {"width": 320, "height": 569}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 2.0; en-us; Milestone Build/ SHOLS_U2_01.03.1) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17", "type": "phone"}, {"show-by-default": true, "modes": [], "title": "Samsung Galaxy Note 3", "screen": {"horizontal": {"width": 640, "height": 360}, "device-pixel-ratio": 3, "vertical": {"width": 360, "height": 640}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 4.3; en-us; SM-N900T Build/JSS15J) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "BlackBerry PlayBook", "screen": {"horizontal": {"width": 600, "height": 1024}, "device-pixel-ratio": 1, "vertical": {"width": 1024, "height": 600}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/7.2.1.0 Safari/536.2+", "type": "tablet"}, {"show-by-default": false, "modes": [], "title": "Google Nexus 7 (1st gen)", "screen": {"horizontal": {"width": 604, "height": 966}, "device-pixel-ratio": 1.325, "vertical": {"width": 966, "height": 604}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; Android 4.3; Nexus 7 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.72 Safari/537.36", "type": "tablet"}, {"show-by-default": false, "modes": [], "title": "Samsung Galaxy Tab 7.7, 8.9, 10.1", "screen": {"horizontal": {"width": 800, "height": 1280}, "device-pixel-ratio": 1, "vertical": {"width": 1280, "height": 800}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 2.2; en-us; SCH-I800 Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", "type": "tablet"}, {"show-by-default": false, "modes": [], "title": "Google Nexus 4", "screen": {"horizontal": {"width": 640, "height": 384}, "device-pixel-ratio": 2, "vertical": {"width": 384, "height": 640}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.122 Mobile Safari/537.36", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "BlackBerry Classic", "screen": {"horizontal": {"width": 374, "height": 390}, "device-pixel-ratio": 1.84375, "vertical": {"width": 390, "height": 374}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (BB10; Kbd) AppleWebKit/537.35+ (KHTML, like Gecko) Version/10.3.1.1418 Mobile Safari/537.35+", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "Apple iPhone 3GS", "screen": {"horizontal": {"width": 480, "height": 320}, "device-pixel-ratio": 1, "vertical": {"width": 320, "height": 480}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_2_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "BlackBerry Z10", "screen": {"horizontal": {"width": 640, "height": 384}, "device-pixel-ratio": 2, "vertical": {"width": 384, "height": 640}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.0.9.2372 Mobile Safari/537.10+", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "LG Optimus 2X, Optimus 3D, Optimus Black", "screen": {"horizontal": {"width": 533, "height": 320}, "device-pixel-ratio": 1.5, "vertical": {"width": 320, "height": 533}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 2.2; en-us; LG-P990/V08c Build/FRG83) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1 MMS/LG-Android-MMS-V1.0/1.2", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "Nokia Lumia 7X0, Lumia 8XX, Lumia 900, N800, N810, N900", "screen": {"horizontal": {"width": 533, "height": 320}, "device-pixel-ratio": 1.5, "vertical": {"width": 320, "height": 533}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 820)", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "Samsung Galaxy S, S II, W", "screen": {"horizontal": {"width": 533, "height": 320}, "device-pixel-ratio": 1.5, "vertical": {"width": 320, "height": 533}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 2.1; en-us; GT-I9000 Build/ECLAIR) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "BlackBerry Z30", "screen": {"horizontal": {"width": 640, "height": 360}, "device-pixel-ratio": 2, "vertical": {"width": 360, "height": 640}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.0.9.2372 Mobile Safari/537.10+", "type": "phone"}, {"//": "iPad (1st generation), iPad 2, iPad Mini (1st generation), have same device characteristics", "show-by-default": false, "modes": [], "title": "Apple iPad Mini", "screen": {"horizontal": {"width": 768, "height": 1024}, "device-pixel-ratio": 1, "vertical": {"width": 1024, "height": 768}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (iPad; CPU OS 4_3_5 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8L1 Safari/6533.18.5", "type": "tablet"}, {"show-by-default": false, "modes": [], "title": "Motorola Droid 3, Droid 4, Droid Razr, Atrix 4G, Atrix 2", "screen": {"horizontal": {"width": 960, "height": 540}, "device-pixel-ratio": 1, "vertical": {"width": 540, "height": 960}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 2.2; en-us; Droid Build/FRG22D) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "Amazon Kindle Fire First Generation", "screen": {"horizontal": {"width": 600, "height": 1024}, "device-pixel-ratio": 1, "vertical": {"width": 1024, "height": 600}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_3; en-us; Silk/1.0.141.16-Gen4_11004310) AppleWebkit/533.16 (KHTML, like Gecko) Version/5.0 Safari/533.16 Silk-Accelerated=true", "type": "tablet"}, {"show-by-default": false, "modes": [], "title": "Samsung Galaxy S III, Galaxy Nexus", "screen": {"horizontal": {"width": 640, "height": 360}, "device-pixel-ratio": 2, "vertical": {"width": 360, "height": 640}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 4.0; en-us; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "LG Optimus One", "screen": {"horizontal": {"width": 320, "height": 213}, "device-pixel-ratio": 1.5, "vertical": {"width": 213, "height": 320}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 2.2.1; en-us; LG-MS690 Build/FRG83) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "Google Nexus 10", "screen": {"horizontal": {"width": 800, "height": 1280}, "device-pixel-ratio": 2, "vertical": {"width": 1280, "height": 800}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; Android 4.3; Nexus 10 Build/JSS15Q) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.72 Safari/537.36", "type": "tablet"}, {"show-by-default": false, "modes": [], "title": "Samsung Galaxy Note", "screen": {"horizontal": {"width": 640, "height": 400}, "device-pixel-ratio": 2, "vertical": {"width": 400, "height": 640}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 2.3; en-us; SAMSUNG-SGH-I717 Build/GINGERBREAD) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", "type": "phone"}, {"show-by-default": true, "modes": [], "title": "Samsung Galaxy S4", "screen": {"horizontal": {"width": 640, "height": 360}, "device-pixel-ratio": 3, "vertical": {"width": 360, "height": 640}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; Android 4.2.2; GT-I9505 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.59 Mobile Safari/537.36", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "HTC Evo, Touch HD, Desire HD, Desire", "screen": {"horizontal": {"width": 533, "height": 320}, "device-pixel-ratio": 1.5, "vertical": {"width": 320, "height": 533}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 2.2; en-us; Sprint APA9292KT Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", "type": "phone"}, {"show-by-default": false, "modes": [], "title": "Google Nexus S", "screen": {"horizontal": {"width": 533, "height": 320}, "device-pixel-ratio": 1.5, "vertical": {"width": 320, "height": 533}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; Nexus S Build/GRJ22) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1", "type": "phone"}, {"show-by-default": true, "modes": [], "title": "Apple iPhone 6", "screen": {"horizontal": {"width": 667, "height": 375}, "device-pixel-ratio": 2, "vertical": {"width": 375, "height": 667}}, "capabilities": ["touch", "mobile"], "user-agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/600.1.3 (KHTML, like Gecko) Version/8.0 Mobile/12A4345d Safari/600.1.4", "type": "phone"}]} \ No newline at end of file diff --git a/generate_devices_list.py b/generate_devices_list.py index 69ae2c6..ce14c9b 100755 --- a/generate_devices_list.py +++ b/generate_devices_list.py @@ -1,5 +1,6 @@ #!/usr/bin/env python +import numbers import os import os.path import sys @@ -9,6 +10,8 @@ try: except ImportError: import simplejson as json +POSSIBLE_TYPES = ["phone", "tablet", "notebook", "desktop", "unknown"] + def load_and_parse_json(file_name): try: with open(file_name, "r") as file: @@ -17,28 +20,107 @@ def load_and_parse_json(file_name): print 'ERROR: Failed to parse %s' % file_name raise -def rebase_images(json, rebase_path): - for entry in json: - if "src" in entry: - entry["src"] = os.path.join(rebase_path, entry["src"]) +def raise_type_error(file_name, key, expected_type): + raise Exception('ERROR: "' + key + '" must be of type "' + expected_type + '" (' + file_name + ')') -def read_device_json(file_name, rebase_path): +def parse_and_rebase_images(images, file_name, prefix, rebase_path): + for (index, entry) in enumerate(images): + i = str(index) + if not isinstance(entry, dict): + raise_type_error(file_name, prefix + "[" + i + "]", "object") + if not ("src" in entry) or not isinstance(entry["src"], basestring): + raise_type_error(file_name, prefix + "[" + i + "]/src", "string") + if not ("scale" in entry) or not isinstance(entry["scale"], numbers.Number): + raise_type_error(file_name, prefix + "[" + i + "]/scale", "number") + entry["src"] = os.path.join(rebase_path, entry["src"]) + +def parse_orientation(d, file_name, prefix, rebase_path): + if not ("width" in d) or not isinstance(d["width"], numbers.Number) or d["width"] < 0 or d["width"] > 10000 or abs(d["width"]) != d["width"]: + raise_type_error(file_name, prefix + "/width", "number") + if not ("height" in d) or not isinstance(d["height"], numbers.Number) or d["height"] < 0 or d["height"] > 10000 or abs(d["height"]) != d["height"]: + raise_type_error(file_name, prefix + "/height", "number") + + if not ("outline" in d): + return + outline = d["outline"] + if not isinstance(outline, dict): + raise_type_error(file_name, prefix + "/outline", "object") + if not ("images" in outline) or not isinstance(outline["images"], (list, tuple)): + raise_type_error(file_name, prefix + "/outline/images", "array") + parse_and_rebase_images(outline["images"], file_name, prefix + "/outline/images", rebase_path) + if not ("insets" in outline) or not isinstance(outline["insets"], dict): + raise_type_error(file_name, prefix + "/outline/insets", "object") + if not ("left" in outline["insets"]) or not isinstance(outline["insets"]["left"], numbers.Number) or outline["insets"]["left"] < 0: + raise_type_error(file_name, prefix + "/outline/insets/left", "number") + if not ("top" in outline["insets"]) or not isinstance(outline["insets"]["top"], numbers.Number) or outline["insets"]["top"] < 0: + raise_type_error(file_name, prefix + "/outline/insets/top", "number") + +def parse_modes(modes, file_name, prefix, rebase_path): + for (index, mode) in enumerate(modes): + i = str(index) + if not isinstance(mode, dict): + raise_type_error(file_name, prefix + "[" + i + "]", "object") + if not ("title" in mode) or not isinstance(mode["title"], basestring): + raise_type_error(file_name, prefix + "[" + i + "]/title", "string") + if not ("orientation" in mode) or not isinstance(mode["orientation"], basestring): + raise_type_error(file_name, prefix + "[" + i + "]/orientation", "string") + if mode["orientation"] != "vertical" and mode["orientation"] != "horizontal": + raise Exception('ERROR: "' + prefix + '[' + i + ']/orientation" must be one of the following: [horizontal, vertical] (' + file_name + ')') + + if not ("images" in mode) or not isinstance(mode["images"], (list, tuple)): + raise_type_error(file_name, prefix + "[" + i + "]/images", "array") + parse_and_rebase_images(mode["images"], file_name, prefix + "[" + i + "]/images", rebase_path) + + if not ("page-rect" in mode) or not isinstance(mode["page-rect"], dict): + raise_type_error(file_name, prefix + "[" + i + "]/page-rect", "object") + if not ("left" in mode["page-rect"]) or not isinstance(mode["page-rect"]["left"], numbers.Number) or mode["page-rect"]["left"] < 0: + raise_type_error(file_name, prefix + "[" + i + "]/page-rect/left", "object") + if not ("top" in mode["page-rect"]) or not isinstance(mode["page-rect"]["top"], numbers.Number) or mode["page-rect"]["top"] < 0: + raise_type_error(file_name, prefix + "[" + i + "]/page-rect/top", "object") + if not ("width" in mode["page-rect"]) or not isinstance(mode["page-rect"]["width"], numbers.Number) or mode["page-rect"]["width"] < 0: + raise_type_error(file_name, prefix + "[" + i + "]/page-rect/width", "object") + if not ("height" in mode["page-rect"]) or not isinstance(mode["page-rect"]["height"], numbers.Number) or mode["page-rect"]["height"] < 0: + raise_type_error(file_name, prefix + "[" + i + "]/page-rect/height", "object") + +def parse_device_json(file_name, rebase_path): json = load_and_parse_json(file_name) - if "screen" in json: + + if not ("title" in json) or not isinstance(json["title"], basestring): + raise_type_error(file_name, "title", "string") + + if not ("type" in json) or not isinstance(json["type"], basestring): + raise_type_error(file_name, "type", "string") + if not (json["type"] in POSSIBLE_TYPES): + raise Exception('ERROR: "type" must be one of the following: [' + ", ".join(POSSIBLE_TYPES) + '] (' + file_name + ')') + + if not ("user-agent" in json) or not isinstance(json["user-agent"], basestring): + raise_type_error(file_name, "user-agent", "string") + + if not ("show-by-default" in json) or not isinstance(json["show-by-default"], bool): + raise_type_error(file_name, "show-by-default", "boolean") + + if not ("capabilities" in json) or not isinstance(json["capabilities"], (list, tuple)): + raise_type_error(file_name, "capabilities", "array") + for cap in json["capabilities"]: + if not isinstance(cap, basestring): + raise_type_error(file_name, "capability", "string") + + if ("screen" in json) and isinstance(json["screen"], dict): screen = json["screen"] - if ("vertical" in screen) and ("outline" in screen["vertical"]): - v_outline = screen["vertical"]["outline"] - if "images" in v_outline: - rebase_images(v_outline["images"], rebase_path) - if ("horizontal" in screen) and ("outline" in screen["horizontal"]): - h_outline = screen["horizontal"]["outline"] - if "images" in h_outline: - rebase_images(h_outline["images"], rebase_path) + if not ("device-pixel-ratio" in screen) or not isinstance(screen["device-pixel-ratio"], numbers.Number) or screen["device-pixel-ratio"] < 0 or screen["device-pixel-ratio"] > 100: + raise_type_error(file_name, "screen/device-pixel-ratio", "number") + + for orientation in ["vertical", "horizontal"]: + if not (orientation in screen) or not isinstance(screen[orientation], dict): + raise_type_error(file_name, "screen/" + orientation, "object") + parse_orientation(screen[orientation], file_name, "screen/" + orientation, rebase_path) + else: + raise_type_error(file_name, "screen", "object") if "modes" in json: - for mode_json in json["modes"]: - if "images" in mode_json: - rebase_images(mode_json["images"], rebase_path) + if not isinstance(json["modes"], (list, tuple)): + raise_type_error(file_name, "modes", "array") + parse_modes(json["modes"], file_name, "modes", rebase_path) return json @@ -50,7 +132,7 @@ def main(argv): dir_name = os.path.join(root_path, file_name) device_file_name = os.path.join(dir_name, "device.json") if os.path.isdir(dir_name) and os.path.isfile(device_file_name): - devices_json.append(read_device_json(device_file_name, file_name)) + devices_json.append(parse_device_json(device_file_name, file_name)) result_json = {} result_json["version"] = 1