io.github.apkcloud.devicedetector.parser.device.AbstractDeviceParser Maven / Gradle / Ivy
Show all versions of DeviceDetector Show documentation
package io.github.apkcloud.devicedetector.parser.device;
import io.github.apkcloud.devicedetector.entity.Device;
import io.github.apkcloud.devicedetector.parser.AbstractParser;
import io.github.apkcloud.devicedetector.ClientHints;
import java.util.*;
import java.util.regex.Pattern;
/**
* 所有设备解析器的抽象类
*/
public abstract class AbstractDeviceParser extends AbstractParser {
protected Integer deviceType = null;
protected String model = "";
protected String brand = "";
public static final int DEVICE_TYPE_DESKTOP = 0;
public static final int DEVICE_TYPE_SMARTPHONE = 1;
public static final int DEVICE_TYPE_TABLET = 2;
public static final int DEVICE_TYPE_FEATURE_PHONE = 3;
public static final int DEVICE_TYPE_CONSOLE = 4;
public static final int DEVICE_TYPE_TV = 5; // 包括机顶盒、蓝光播放器、...
public static final int DEVICE_TYPE_CAR_BROWSER = 6;
public static final int DEVICE_TYPE_SMART_DISPLAY = 7;
public static final int DEVICE_TYPE_CAMERA = 8;
public static final int DEVICE_TYPE_PORTABLE_MEDIA_PAYER = 9;
public static final int DEVICE_TYPE_PHABLET = 10;
public static final int DEVICE_TYPE_SMART_SPEAKER = 11;
public static final int DEVICE_TYPE_WEARABLE = 12; // 包括套装手表、耳机
public static final int DEVICE_TYPE_PERIPHERAL = 13; // 包括便携终端、便携投影仪
/**
* 可检测的设备类型
*/
protected static final Map deviceTypes = new LinkedHashMap<>() {
{
put("desktop", DEVICE_TYPE_DESKTOP); // 台式电脑
put("smartphone", DEVICE_TYPE_SMARTPHONE); // 智能手机
put("tablet", DEVICE_TYPE_TABLET); // 平板电脑
put("feature phone", DEVICE_TYPE_FEATURE_PHONE); // 功能手机
put("console", DEVICE_TYPE_CONSOLE); // 游戏主机
put("tv", DEVICE_TYPE_TV); // 电视
put("car browser", DEVICE_TYPE_CAR_BROWSER); // 车载浏览器
put("smart display", DEVICE_TYPE_SMART_DISPLAY); // 智能显示屏
put("camera", DEVICE_TYPE_CAMERA); // 相机
put("portable media player", DEVICE_TYPE_PORTABLE_MEDIA_PAYER); // 便携式媒体播放器
put("phablet", DEVICE_TYPE_PHABLET); // 平板手机
put("smart speaker", DEVICE_TYPE_SMART_SPEAKER); // 智能音箱
put("wearable", DEVICE_TYPE_WEARABLE); // 可穿戴设备
put("peripheral", DEVICE_TYPE_PERIPHERAL); // 外围设备
}
};
/**
* 已知的设备品牌
*
* 注意:在正则表达式文件中使用新品牌之前,需要在此处添加它
*/
public static Map deviceBrands = new LinkedHashMap<>() {
{
put("5E", "2E");
put("2F", "F2 Mobile");
put("3Q", "3Q");
put("J7", "7 Mobile");
put("2Q", "3GNET");
put("4G", "4Good");
put("27", "3GO");
put("04", "4ife");
put("36", "360");
put("88", "8848");
put("10M", "10moons");
put("41", "A1");
put("00", "Accent");
put("AE", "Ace");
put("AC", "Acer");
put("3K", "Acteck");
put("ACT", "actiMirror");
put("A9", "Advan");
put("AD", "Advance");
put("ADV", "Advantage Air");
put("76", "Adronix");
put("AF", "AfriOne");
put("FY", "AFFIX");
put("A3", "AGM");
put("AEE", "AEEZO");
put("J0", "AG Mobile");
put("AZ", "Ainol");
put("AIR", "Airis");
put("AI", "Airness");
put("ARP", "Airpha");
put("AT", "Airties");
put("7U", "Airtel");
put("U0", "AIRON");
put("0A", "AIS");
put("AW", "Aiwa");
put("85", "Aiuto");
put("U7", "AIDATA");
put("AK", "Akai");
put("Q3", "AKIRA");
put("1A", "Alba");
put("AL", "Alcatel");
put("20", "Alcor");
put("XY", "Alps");
put("XYA", "XY Auto");
put("7L", "ALDI NORD");
put("6L", "ALDI SÜD");
put("3L", "Alfawise");
put("4A", "Aligator");
put("AA", "AllCall");
put("3A", "AllDocube");
put("A2", "Allview");
put("ALI", "ALLINmobile");
put("A7", "Allwinner");
put("A1", "Altech UEC");
put("66", "Altice");
put("A5", "altron");
put("KN", "Amazon");
put("AMA", "AMA");
put("AG", "AMGOO");
put("9A", "Amigoo");
put("AO", "Amoi");
put("3J", "Amino");
put("54", "AMCV");
put("60", "Andowl");
put("ANX", "ANXONIT");
put("6J", "Angelcare");
put("7A", "Anry");
put("A0", "ANS");
put("74", "Anker");
put("3N", "Aoson");
put("O8", "AOC");
put("J2", "AOYODKG");
put("55", "AOpen");
put("RW", "Aoro");
put("9Y", "Aocos");
put("AP", "Apple");
put("AR", "Archos");
put("AB", "Arian Space");
put("A6", "Ark");
put("5A", "ArmPhone");
put("AN", "Arnova");
put("AS", "ARRIS");
put("AQ", "Aspera");
put("HJ", "Aquarius");
put("40", "Artel");
put("21", "Artizlee");
put("59", "ArtLine");
put("8A", "Asano");
put("90", "Asanzo");
put("1U", "Astro");
put("A4", "Ask");
put("A8", "Assistant");
put("ASS", "ASSE");
put("AU", "Asus");
put("6A", "AT&T");
put("ATH", "Athesi");
put("5Q", "Atmaca Elektronik");
put("YH", "ATMAN");
put("2A", "Atom");
put("ATO", "ATOL");
put("Z2", "Atvio");
put("ATI", "Attila");
put("AX", "Audiovox");
put("AJ", "AURIS");
put("YZ", "Autan");
put("ZA", "Avenzo");
put("AH", "AVH");
put("AV", "Avvio");
put("AVA", "Avaya");
put("AY", "Axxion");
put("AXX", "AXXA");
put("YR", "AYYA");
put("XA", "Axioo");
put("AM", "Azumi Mobile");
put("WW", "Awow");
put("XU", "AUX");
put("BAC", "Backcell");
put("BO", "BangOlufsen");
put("BN", "Barnes & Noble");
put("BB", "BBK");
put("0B", "BB Mobile");
put("B6", "BDF");
put("QD", "BDQ");
put("8Z", "BDsharing");
put("BEF", "Beafon");
put("BE", "Becker");
put("B5", "Beeline");
put("B0", "Beelink");
put("BL", "Beetel");
put("2X", "Benco");
put("BQ", "BenQ");
put("BS", "BenQ-Siemens");
put("4Y", "Benzo");
put("XJ", "Benesse");
put("BEN", "BenWee");
put("YB", "Beista");
put("BY", "BS Mobile");
put("BZ", "Bezkam");
put("9B", "Bellphone");
put("63", "Beyond");
put("BG", "BGH");
put("6B", "Bigben");
put("B8", "BIHEE");
put("1B", "Billion");
put("BA", "BilimLand");
put("BIL", "Billow");
put("BH", "BioRugged");
put("BI", "Bird");
put("BT", "Bitel");
put("B7", "Bitmore");
put("ZB", "Bittium");
put("BK", "Bkav");
put("5B", "Black Bear");
put("BF", "Black Fox");
put("BPC", "Blackpcs");
put("B2", "Blackview");
put("2Y", "b2m");
put("BP", "Blaupunkt");
put("BU", "Blu");
put("BUS", "BluSlate");
put("BUZ", "BuzzTV");
put("B3", "Bluboo");
put("2B", "Bluedot");
put("BD", "Bluegood");
put("LB", "Bluewave");
put("J8", "Bluebird");
put("BSS", "BlueSky");
put("7B", "Blloc");
put("UB", "Bleck");
put("Q2", "Blow");
put("BLI", "BLISS");
put("BM", "Bmobile");
put("Y5", "BMAX");
put("BMX", "BMXC");
put("B9", "Bobarry");
put("B4", "bogo");
put("BOL", "Bolva");
put("BW", "Boway");
put("BOO", "Boost");
put("BOK", "Bookeen");
put("BX", "bq");
put("8B", "Brandt");
put("BRA", "BrandCode");
put("BV", "Bravis");
put("BRV", "BRAVE");
put("BRG", "Brigmton");
put("BR", "Brondi");
put("XF", "BROR");
put("BJ", "BrightSign");
put("B1", "Bush");
put("4Q", "Bundy");
put("Y8", "Bubblegum");
put("C9", "CAGI");
put("CT", "Capitel");
put("G3", "CG Mobile");
put("37", "CGV");
put("CP", "Captiva");
put("CF", "Carrefour");
put("CA1", "Carbon Mobile");
put("CS", "Casio");
put("R4", "Casper");
put("CA", "Cat");
put("BC", "Camfone");
put("CJ", "Cavion");
put("4D", "Canal Digital");
put("CEI", "Ceibal");
put("02", "Cell-C");
put("CEL", "Cellacom");
put("34", "CellAllure");
put("7C", "Celcus");
put("CE", "Celkon");
put("CG", "Cellution");
put("62", "Centric");
put("C2", "Changhong");
put("CHA", "Chainway");
put("CHG", "ChiliGreen");
put("CH", "Cherry Mobile");
put("C3", "China Mobile");
put("U9", "China Telecom");
put("CI", "Chico Mobile");
put("CIP", "CipherLab");
put("CIT", "Citycall");
put("1C", "Chuwi");
put("L8", "Clarmin");
put("25", "Claresta");
put("1J", "Cloud");
put("CD", "Cloudfone");
put("6C", "Cloudpad");
put("C0", "Clout");
put("CN", "CnM");
put("CY", "Coby Kyros");
put("XC", "Cobalt");
put("C6", "Comio");
put("CL", "Compal");
put("CQ", "Compaq");
put("C7", "ComTrade Tesla");
put("7Z", "COMPUMAX");
put("C8", "Concord");
put("CC", "ConCorde");
put("C5", "Condor");
put("C5M", "C5 Mobile");
put("4C", "Conquest");
put("3C", "Contixo");
put("8C", "Connex");
put("53", "Connectce");
put("CON", "Conceptum");
put("9C", "Colors");
put("CO", "Coolpad");
put("COO", "Coopers");
put("4R", "CORN");
put("1O", "Cosmote");
put("CW", "Cowon");
put("75", "Covia");
put("QG", "COYOTE");
put("YW", "ClearPHONE");
put("33", "Clementoni");
put("CR", "CreNova");
put("CX", "Crescent");
put("CK", "Cricket");
put("CM", "Crius Mea");
put("0C", "Crony");
put("C1", "Crosscall");
put("4W", "Crown");
put("CTR", "Ctroniq");
put("CU", "Cube");
put("CB", "CUBOT");
put("CV", "CVTE");
put("CWO", "Cwowdefu");
put("C4", "Cyrus");
put("D5", "Daewoo");
put("DA", "Danew");
put("DAN", "Dany");
put("DT", "Datang");
put("D7", "Datawind");
put("7D", "Datamini");
put("6D", "Datalogic");
put("D1", "Datsun");
put("DZ", "Dazen");
put("DAS", "DASS");
put("DB", "Dbtel");
put("DBP", "DbPhone");
put("DCO", "Dcode");
put("DL", "Dell");
put("DL0", "DL");
put("DE", "Denver");
put("DS", "Desay");
put("DSI", "DSIC");
put("DW", "DeWalt");
put("DX", "DEXP");
put("DEY", "DEYI");
put("DEN", "Denali");
put("DEA", "DEALDIG");
put("8D", "DF");
put("DGT", "DGTEC");
put("DG", "Dialog");
put("DI", "Dicam");
put("D4", "Digi");
put("D3", "Digicel");
put("DDG", "Digidragon");
put("DH", "Digihome");
put("DD", "Digiland");
put("DIJ", "DIJITSU");
put("DIG", "Digit4G");
put("DIC", "DIGICOM");
put("Q0", "DIGIFORS");
put("DQ", "DISH");
put("DIS", "Disney");
put("9D", "Ditecma");
put("D2", "Digma");
put("1D", "Diva");
put("DIV", "DiverMax");
put("D6", "Divisat");
put("X6", "DIXON");
put("DIM", "DIMO");
put("5D", "DING DING");
put("DIN", "Dinax");
put("DM", "DMM");
put("DN", "DNS");
put("DC", "DoCoMo");
put("DF", "Doffler");
put("D9", "Dolamee");
put("DO", "Doogee");
put("D0", "Doopro");
put("DV", "Doov");
put("DOM", "Dom.ru");
put("DP", "Dopod");
put("DPA", "DPA");
put("JQ", "Doppio");
put("DR", "Doro");
put("ZD", "DORLAND");
put("D8", "Droxio");
put("DJ", "Dragon Touch");
put("DRA", "DRAGON");
put("DY", "Dreamgate");
put("DRE", "DreamTab");
put("DR1", "DreamStar");
put("DTA", "Dtac");
put("DU", "Dune HD");
put("UD", "DUNNS Mobile");
put("DUU", "Duubee");
put("DTE", "D-Tech");
put("DLI", "D-Link");
put("ENO", "eNOVA");
put("IN2", "iNOVA");
put("INH", "Inhon");
put("EB", "E-Boda");
put("EJ", "Engel");
put("ENA", "ENACOM");
put("ENI", "ENIE");
put("2E", "E-Ceros");
put("E8", "E-tel");
put("EP", "Easypix");
put("EQ", "Eagle");
put("EA", "EBEST");
put("YC", "EBEN");
put("E4", "Echo Mobiles");
put("EQ1", "Equator");
put("ES", "ECS");
put("35", "ECON");
put("ECC", "ECOO");
put("ZZ", "ecom");
put("E6", "EE");
put("GW", "EGL");
put("EFT", "EFT");
put("EK", "EKO");
put("EY", "Einstein");
put("EM", "Eks Mobility");
put("UE", "Ematic");
put("EMR", "Emporia");
put("4K", "EKT");
put("EKI", "EKINOX");
put("7E", "ELARI");
put("03", "Electroneum");
put("Z8", "ELECTRONIA");
put("EL1", "Elecson");
put("L0", "Element");
put("EG", "Elenberg");
put("EL", "Elephone");
put("JE", "Elekta");
put("ELE", "Elevate");
put("4E", "Eltex");
put("ELM", "Elong Mobile");
put("ED", "Energizer");
put("E1", "Energy Sistem");
put("3E", "Enot");
put("ENT", "Entity");
put("ENV", "Envizen");
put("8E", "Epik One");
put("XP", "Epson");
put("EPH", "Ephone");
put("E7", "Ergo");
put("EC", "Ericsson");
put("05", "Erisson");
put("ER", "Ericy");
put("EE", "Essential");
put("E2", "Essentielb");
put("6E", "eSTAR");
put("EN", "Eton");
put("ET", "eTouch");
put("1E", "Etuline");
put("EU", "Eurostar");
put("4J", "Eurocase");
put("E9", "Evercoss");
put("EV", "Evertek");
put("EVE", "Everest");
put("EV1", "Everex");
put("E3", "Evolio");
put("EO", "Evolveo");
put("0Q", "Evoo");
put("5U", "EVPAD");
put("E0", "EvroMedia");
put("XE", "ExMobile");
put("4Z", "Exmart");
put("EH", "EXO");
put("EX", "Explay");
put("E5", "Extrem");
put("EF", "EXCEED");
put("QE", "EWIS");
put("EI", "Ezio");
put("EZ", "Ezze");
put("UF", "EYU");
put("UE1", "UE");
put("5F", "F150");
put("F6", "Facebook");
put("FAC", "Facetel");
put("FA1", "Facime");
put("FA", "Fairphone");
put("FM", "Famoco");
put("FAM", "Famous");
put("17", "FarEasTone");
put("9R", "FaRao Pro");
put("FAR", "Farassoo");
put("FB", "Fantec");
put("FE", "Fengxiang");
put("F7", "Fero");
put("67", "FEONAL");
put("FI", "FiGO");
put("J9", "FiGi");
put("FIG", "Figgers");
put("F9", "FiiO");
put("F1", "FinePower");
put("FX", "Finlux");
put("F3", "FireFly Mobile");
put("F8", "FISE");
put("FIL", "FILIX");
put("FL", "Fly");
put("QC", "FLYCAT");
put("FLU", "Fluo");
put("FN", "FNB");
put("FD", "Fondi");
put("0F", "Fourel");
put("44", "Four Mobile");
put("F0", "Fonos");
put("F2", "FORME");
put("F5", "Formuler");
put("FR", "Forstar");
put("RF", "Fortis");
put("FO", "Foxconn");
put("FOD", "FoxxD");
put("FJ", "FOODO");
put("FT", "Freetel");
put("FRU", "Frunsi");
put("F4", "F&U");
put("1F", "FMT");
put("FPT", "FPT");
put("FG", "Fuego");
put("FU", "Fujitsu");
put("4F", "Funai");
put("5J", "Fusion5");
put("FF", "Future Mobile Technology");
put("FFF", "FFF SmartLife");
put("FW", "FNF");
put("FXT", "Fxtec");
put("GT", "G-TiDE");
put("G9", "G-Touch");
put("GTM", "GTMEDIA");
put("0G", "GFive");
put("GM", "Garmin-Asus");
put("GA", "Gateway");
put("99", "Galaxy Innovations");
put("GA1", "Galactic");
put("GAZ", "Gazer");
put("GEA", "Geanee");
put("GEN", "Geant");
put("GD", "Gemini");
put("GN", "General Mobile");
put("2G", "Genesis");
put("G2", "GEOFOX");
put("GE", "Geotel");
put("Q4", "Geotex");
put("GEO", "GEOZON");
put("GER", "Gear Mobile");
put("GH", "Ghia");
put("2C", "Ghong");
put("GJ", "Ghost");
put("GG", "Gigabyte");
put("GS", "Gigaset");
put("GZ", "Ginzzu");
put("1G", "Gini");
put("GI", "Gionee");
put("GIR", "GIRASOLE");
put("G4", "Globex");
put("38", "GLONYX");
put("U6", "Glofiish");
put("G7", "GoGEN");
put("GC", "GOCLEVER");
put("5G", "Gocomma");
put("GB", "Gol Mobile");
put("GL", "Goly");
put("GOL", "GoldMaster");
put("GX", "GLX");
put("G5", "Gome");
put("G1", "GoMobile");
put("GO", "Google");
put("G0", "Goophone");
put("6G", "Gooweel");
put("GOO", "GOODTEL");
put("8G", "Gplus");
put("GR", "Gradiente");
put("GP", "Grape");
put("G6", "Gree");
put("GRA", "Great Asia");
put("3G", "Greentel");
put("GF", "Gretel");
put("82", "Gresso");
put("GU", "Grundig");
put("GV", "Gtel");
put("CUO", "Guophone");
put("H13", "H133");
put("9Z", "H96");
put("HF", "Hafury");
put("9F", "HAOVM");
put("HAQ", "HAOQIN");
put("HA", "Haier");
put("XH", "Haipai");
put("HAN", "Handheld");
put("HE", "HannSpree");
put("HK", "Hardkernel");
put("HAR", "Harper");
put("HA1", "Hartens");
put("HS", "Hasee");
put("8H", "Hamlet");
put("HAM", "Hammer");
put("HAT", "Hathway");
put("H6", "Helio");
put("HQ", "HERO");
put("ZH", "Hezire");
put("HEX", "HexaByte");
put("HEW", "HeadWolf");
put("HL", "Hi-Level");
put("3H", "Hi");
put("HIB", "Hiberg");
put("HIH", "HiHi");
put("HIK", "HiKing");
put("H2", "Highscreen");
put("Q1", "High Q");
put("1H", "Hipstreet");
put("HI", "Hisense");
put("HIP", "HIPER");
put("HC", "Hitachi");
put("H8", "Hitech");
put("W3", "HiMax");
put("8X", "Hi Nova");
put("HLL", "HLLO");
put("8W", "HKPro");
put("H1", "Hoffmann");
put("H0", "Hometech");
put("HM", "Homtom");
put("HZ", "Hoozo");
put("H7", "Horizon");
put("4H", "Horizont");
put("HO", "Hosin");
put("H3", "Hotel");
put("HV", "Hotwav");
put("U8", "Hot Pepper");
put("JH", "HOTREALS");
put("HW", "How");
put("WH", "Honeywell");
put("HP", "HP");
put("HDC", "HDC");
put("HT", "HTC");
put("QZ", "Huagan");
put("HD", "Huadoo");
put("HG", "Huavi");
put("HU", "Huawei");
put("HX", "Humax");
put("HR", "Hurricane");
put("H5", "Huskee");
put("HUG", "Hugerock");
put("HY", "Hyrican");
put("HN", "Hyundai");
put("7H", "Hyve");
put("HYT", "Hytera");
put("HYK", "Hykker");
put("3I", "i-Cherry");
put("IJ", "i-Joy");
put("IM", "i-mate");
put("IO", "i-mobile");
put("INN", "I-INN");
put("OF", "iOutdoor");
put("IB", "iBall");
put("IY", "iBerry");
put("7I", "iBrit");
put("I2", "IconBIT");
put("IC", "iDroid");
put("6Z", "iData");
put("IG", "iGet");
put("IH", "iHunt");
put("IA", "Ikea");
put("IYO", "iYou");
put("8I", "IKU Mobile");
put("2K", "IKI Mobile");
put("IK", "iKoMo");
put("58", "iKon");
put("I7", "iLA");
put("2I", "iLife");
put("1I", "iMars");
put("IMI", "iMI");
put("U4", "iMan");
put("ILE", "iLepo");
put("IL", "IMO Mobile");
put("IM1", "Imose");
put("I3", "Impression");
put("FC", "INCAR");
put("2H", "Inch");
put("6I", "Inco");
put("IW", "iNew");
put("IF", "Infinix");
put("INF", "Infiniton");
put("I0", "InFocus");
put("IN1", "InFone");
put("II", "Inkti");
put("81", "InfoKit");
put("I5", "InnJoo");
put("26", "Innos");
put("IN", "Innostream");
put("I4", "Inoi");
put("INO", "iNo Mobile");
put("IQ", "INQ");
put("QN", "iQ&T");
put("IS", "Insignia");
put("YI", "INSYS");
put("IT", "Intek");
put("INT", "Intel");
put("IX", "Intex");
put("IV", "Inverto");
put("32", "Invens");
put("4I", "Invin");
put("INA", "iNavi");
put("I1", "iOcean");
put("IMU", "iMuz");
put("IP", "iPro");
put("X9", "iPEGTOP");
put("8Q", "IQM");
put("Q8", "IRA");
put("I6", "Irbis");
put("5I", "Iris");
put("IRE", "iReplace");
put("IR", "iRola");
put("IU", "iRulu");
put("IRO", "iRobot");
put("9I", "iSWAG");
put("9J", "iSafe Mobile");
put("IST", "iStar");
put("86", "IT");
put("IZ", "iTel");
put("0I", "iTruck");
put("I8", "iVA");
put("IE", "iView");
put("0J", "iVooMi");
put("UI", "ivvi");
put("QW", "iWaylink");
put("I9", "iZotron");
put("IXT", "iXTech");
put("JA", "JAY-Tech");
put("KJ", "Jiake");
put("JD", "Jedi");
put("J6", "Jeka");
put("JF", "JFone");
put("JI", "Jiayu");
put("JG", "Jinga");
put("JX", "Jio");
put("VJ", "Jivi");
put("JK", "JKL");
put("JR1", "JREN");
put("JO", "Jolla");
put("JP", "Joy");
put("JOY", "JoySurf");
put("UJ", "Juniper Systems");
put("J5", "Just5");
put("7J", "Jumper");
put("JPA", "JPay");
put("JV", "JVC");
put("JXD", "JXD");
put("JS", "Jesy");
put("KT", "K-Touch");
put("KLT", "K-Lite");
put("K4", "Kaan");
put("K7", "Kaiomy");
put("KL", "Kalley");
put("K6", "Kanji");
put("KA", "Karbonn");
put("K5", "KATV1");
put("KAP", "Kapsys");
put("K0", "Kata");
put("KZ", "Kazam");
put("9K", "Kazuna");
put("KD", "KDDI");
put("KHA", "Khadas");
put("KS", "Kempler & Strauss");
put("K3", "Keneksi");
put("KX", "Kenxinda");
put("KEN", "Kenbo");
put("KZG", "KZG");
put("K1", "Kiano");
put("5W", "Kingbox");
put("KI", "Kingsun");
put("KIS", "Kinstone");
put("KF", "KINGZONE");
put("KIN", "Kingstar");
put("46", "Kiowa");
put("KV", "Kivi");
put("64", "Kvant");
put("0K", "Klipad");
put("KC", "Kocaso");
put("KK", "Kodak");
put("KG", "Kogan");
put("KM", "Komu");
put("KO", "Konka");
put("KW", "Konrow");
put("KB", "Koobee");
put("7K", "Koolnee");
put("K9", "Kooper");
put("KP", "KOPO");
put("KR", "Koridy");
put("XK", "Koslam");
put("K2", "KRONO");
put("KE", "Krüger&Matz");
put("5K", "KREZ");
put("WK", "KRIP");
put("KRA", "Kraft");
put("KH", "KT-Tech");
put("Z6", "KUBO");
put("KUG", "KuGou");
put("K8", "Kuliao");
put("8K", "Kult");
put("KU", "Kumai");
put("6K", "Kurio");
put("KY", "Kyocera");
put("KQ", "Kyowon");
put("1K", "Kzen");
put("LQ", "LAIQ");
put("L6", "Land Rover");
put("L2", "Landvo");
put("LA", "Lanix");
put("LA1", "Lanin");
put("LK", "Lark");
put("Z3", "Laurus");
put("LEC", "Lectrus");
put("LV", "Lava");
put("LC", "LCT");
put("L5", "Leagoo");
put("U3", "Leben");
put("LEB", "LeBest");
put("LD", "Ledstar");
put("LEE", "Leelbox");
put("L1", "LeEco");
put("4B", "Leff");
put("LEG", "Legend");
put("L4", "Lemhoov");
put("W9", "LEMFO");
put("LN", "Lenco");
put("LE", "Lenovo");
put("LT", "Leotec");
put("LP", "Le Pan");
put("ZJ", "Leke");
put("L7", "Lephone");
put("LZ", "Lesia");
put("L3", "Lexand");
put("LX", "Lexibook");
put("LG", "LG");
put("39", "Liberton");
put("5L", "Linsar");
put("LIN", "Linsay");
put("LF", "Lifemaxx");
put("LI", "Lingwin");
put("LJ", "L-Max");
put("LW", "Linnex");
put("JJ", "Listo");
put("LNM", "LNMBBS");
put("LO", "Loewe");
put("YL", "Loview");
put("LOV", "Lovme");
put("1L", "Logic");
put("LH", "Logic Instrument");
put("LM", "Logicom");
put("GY", "LOKMAT");
put("LPX", "LPX-G");
put("0L", "Lumigon");
put("LU", "Lumus");
put("LUM", "Lumitel");
put("L9", "Luna");
put("LR", "Luxor");
put("LY", "LYF");
put("LL", "Leader Phone");
put("QL", "LT Mobile");
put("MQ", "M.T.T.");
put("MN", "M4tel");
put("XM", "Macoox");
put("92", "MAC AUDIO");
put("MJ", "Majestic");
put("FQ", "Mafe");
put("6Y", "Magicsee");
put("23", "Magnus");
put("NH", "Manhattan");
put("MAN", "Mango");
put("5M", "Mann");
put("MA", "Manta Multimedia");
put("Z0", "Mantra");
put("J4", "Mara");
put("MAR", "Marshal");
put("8Y", "Massgo");
put("MA1", "Mascom");
put("2M", "Masstel");
put("3X", "Mastertech");
put("MAS", "Master-G");
put("50", "Matrix");
put("7M", "Maxcom");
put("7M1", "Maxfone");
put("ZM", "Maximus");
put("6X", "Maxtron");
put("0D", "MAXVI");
put("XZ", "MAXX");
put("MW", "Maxwest");
put("M0", "Maze");
put("YM", "Maze Speed");
put("87", "Malata");
put("28", "MBOX");
put("FK", "MBI");
put("3D", "MDC Store");
put("1Y", "MDTV");
put("09", "meanIT");
put("M3", "Mecer");
put("M3M", "M3 Mobile");
put("0M", "Mecool");
put("MC", "Mediacom");
put("MK", "MediaTek");
put("MD", "Medion");
put("M2", "MEEG");
put("MP", "MegaFon");
put("X0", "mPhone");
put("3M", "Meitu");
put("M1", "Meizu");
put("0E", "Melrose");
put("MU", "Memup");
put("ME", "Metz");
put("MX", "MEU");
put("MI", "MicroMax");
put("MS", "Microsoft");
put("6Q", "Microtech");
put("1X", "Minix");
put("OM", "Mintt");
put("MIN", "Mint");
put("MO", "Mio");
put("X7", "Mione");
put("M7", "Miray");
put("8M", "Mito");
put("MT", "Mitsubishi");
put("0Y", "Mitsui");
put("M5", "MIXC");
put("2D", "MIVO");
put("1Z", "MiXzo");
put("MIW", "MIWANG");
put("ML", "MLLED");
put("LS", "MLS");
put("5H", "MMI");
put("4M", "Mobicel");
put("M6", "Mobiistar");
put("MOK", "Mobile Kingdom");
put("MH", "Mobiola");
put("MB", "Mobistel");
put("ID", "MobiIoT");
put("6W", "MobiWire");
put("9M", "Mobo");
put("MOB", "Mobell");
put("M4", "Modecom");
put("MF", "Mofut");
put("MR", "Motorola");
put("MIV", "Motiv");
put("MV", "Movic");
put("MOV", "Movitel");
put("MO1", "MOVISUN");
put("MOS", "Mosimosi");
put("MOX", "Moxee");
put("MM", "Mpman");
put("MZ", "MSI");
put("3R", "MStar");
put("M9", "MTC");
put("N4", "MTN");
put("72", "M-Tech");
put("9H", "M-Horse");
put("1R", "Multilaser");
put("1M", "MYFON");
put("MY", "MyPhone");
put("51", "Myros");
put("M8", "Myria");
put("6M", "Mystery");
put("3T", "MyTab");
put("MG", "MyWigo");
put("J3", "Mymaga");
put("MYM", "MyMobile");
put("07", "MyGica");
put("MYG", "MygPad");
put("MWA", "MwalimuPlus");
put("NEO", "neoCore");
put("08", "Nabi");
put("N7", "National");
put("NC", "Navcity");
put("6N", "Navitech");
put("7V", "Navitel");
put("N3", "Navon");
put("7R", "NavRoad");
put("NAS", "NASCO");
put("NP", "Naomi Phone");
put("NE", "NEC");
put("NDP", "Nedaphone");
put("8N", "Necnot");
put("NF", "Neffos");
put("9X", "Neo");
put("NEK", "NEKO");
put("1N", "Neomi");
put("7Q", "Neon IQ");
put("8F", "Neolix");
put("NA", "Netgear");
put("NEM", "Netmak");
put("NU", "NeuImage");
put("NEU", "NeuTab");
put("NW", "Newgen");
put("N9", "Newland");
put("0N", "Newman");
put("NS", "NewsMy");
put("ND", "Newsday");
put("HB", "New Balance");
put("BRI", "New Bridge");
put("XB", "NEXBOX");
put("NX", "Nexian");
put("7X", "Nexa");
put("N8", "NEXON");
put("N2", "Nextbit");
put("NT", "NextBook");
put("NTT", "NTT West");
put("4N", "NextTab");
put("NEX", "NEXT");
put("NJO", "nJoy");
put("NG", "NGM");
put("NZ", "NG Optics");
put("NZP", "NGpon");
put("NN", "Nikon");
put("NI", "Nintendo");
put("NIN", "NINETEC");
put("N5", "NOA");
put("N1", "Noain");
put("N6", "Nobby");
put("NOV", "Novey");
put("NO1", "NOVO");
put("57", "Nubia");
put("JN", "NOBUX");
put("NB", "Noblex");
put("OG", "NOGA");
put("NK", "Nokia");
put("NM", "Nomi");
put("2N", "Nomu");
put("6H", "Noontec");
put("NR", "Nordmende");
put("7N", "NorthTech");
put("NOT", "Nothing Phone");
put("5N", "Nos");
put("NO", "Nous");
put("NQ", "Novex");
put("NJ", "NuAns");
put("NL", "NUU Mobile");
put("N0", "Nuvo");
put("NUV", "NuVision");
put("NV", "Nvidia");
put("NY", "NYX Mobile");
put("O3", "O+");
put("OT", "O2");
put("O7", "Oale");
put("OC", "OASYS");
put("OB", "Obi");
put("OBR", "Ober");
put("OQ", "Meta");
put("O1", "Odys");
put("ODP", "Odotpad");
put("O9", "Ok");
put("OA", "Okapia");
put("OKI", "Oking");
put("OLA", "Olax");
put("OLK", "Olkya");
put("OLY", "Olympia");
put("OLT", "OLTO");
put("OJ", "Ookee");
put("OD", "Onda");
put("ON", "OnePlus");
put("ONC", "OneClick");
put("ONL", "OneLern");
put("OAN", "Oangcc");
put("OX", "Onix");
put("3O", "ONYX BOOX");
put("O4", "ONN");
put("9Q", "Onkyo");
put("2O", "OpelMobile");
put("OH", "Openbox");
put("7Y", "Obabox");
put("OP", "OPPO");
put("OO", "Opsson");
put("OPT", "Optoma");
put("OPH", "Ophone");
put("OR", "Orange");
put("O5", "Orbic");
put("Y6", "Orbita");
put("ORB", "Orbsmart");
put("OS", "Ordissimo");
put("8O", "Orion");
put("OTT", "OTTO");
put("OK", "Ouki");
put("0O", "OINOM");
put("QK", "OKWU");
put("QQ", "OMIX");
put("56", "OKSI");
put("OE", "Oukitel");
put("OU", "OUYA");
put("JB", "OUJIA");
put("OV", "Overmax");
put("30", "Ovvi");
put("O2", "Owwo");
put("OSC", "OSCAL");
put("OY", "Oysters");
put("QF", "OYSIN");
put("O6", "Oyyu");
put("OZ", "OzoneHD");
put("OLL", "Ollee");
put("7P", "P-UP");
put("YP", "Paladin");
put("PM", "Palm");
put("PN", "Panacom");
put("PA", "Panasonic");
put("PT", "Pantech");
put("PAN", "Pano");
put("94", "Packard Bell");
put("H9", "Parrot Mobile");
put("PAR", "Partner Mobile");
put("PAP", "PAPYRE");
put("PB", "PCBOX");
put("PCS", "PC Smart");
put("PC", "PCD");
put("PD", "PCD Argentina");
put("PE", "PEAQ");
put("PG", "Pentagram");
put("PQ", "Pendoo");
put("93", "Perfeo");
put("8J", "Pelitt");
put("1P", "Phicomm");
put("4P", "Philco");
put("PH", "Philips");
put("5P", "Phonemax");
put("PO", "phoneOne");
put("PI", "Pioneer");
put("PIC", "Pioneer Computers");
put("PJ", "PiPO");
put("8P", "Pixelphone");
put("9O", "Pixela");
put("PX", "Pixus");
put("QP", "Pico");
put("PIR", "PIRANHA");
put("PIN", "PINE");
put("9P", "Planet Computers");
put("PY", "Ployer");
put("P4", "Plum");
put("PLU", "PlusStyle");
put("22", "Pluzz");
put("P8", "PocketBook");
put("0P", "POCO");
put("FH", "Point Mobile");
put("PV", "Point of View");
put("PL", "Polaroid");
put("Q6", "Polar");
put("97", "PolarLine");
put("PP", "PolyPad");
put("P5", "Polytron");
put("P2", "Pomp");
put("P0", "Poppox");
put("0X", "POPTEL");
put("PS", "Positivo");
put("3P", "Positivo BGH");
put("3F", "Porsche");
put("P3", "PPTV");
put("FP", "Premio");
put("PR", "Prestigio");
put("P9", "Primepad");
put("PRM", "PRIME");
put("6P", "Primux");
put("2P", "Prixton");
put("PRI", "Pritom");
put("PF", "PROFiLO");
put("P6", "Proline");
put("5O", "Prology");
put("P1", "ProScan");
put("P7", "Protruly");
put("R0", "ProVision");
put("7O", "Polestar");
put("PU", "PULID");
put("UP", "Purism");
put("PUN", "Punos");
put("QFX", "QFX");
put("Q7", "Q-Box");
put("QH", "Q-Touch");
put("QB", "Q.Bell");
put("QI", "Qilive");
put("QM", "QMobile");
put("QT", "Qtek");
put("Q9", "QTECH");
put("QA", "Quantum");
put("QUE", "Quest");
put("QUA", "Quatro");
put("QU", "Quechua");
put("QUI", "Quipus");
put("QO", "Qumo");
put("UQ", "Qubo");
put("YQ", "QLink");
put("QY", "Qnet Mobile");
put("WJ", "Qware");
put("R2", "R-TV");
put("RA", "Ramos");
put("0R", "Raspberry");
put("R9", "Ravoz");
put("RZ", "Razer");
put("95", "Rakuten");
put("RAY", "Raylandz");
put("RC", "RCA Tablets");
put("2R", "Reach");
put("REL", "RelNAT");
put("RB", "Readboy");
put("RE", "Realme");
put("RE1", "Redbean");
put("R8", "RED");
put("REW", "Redway");
put("6F", "Redfox");
put("RE2", "RedLine");
put("RD", "Reeder");
put("Z9", "REGAL");
put("RH", "Remdun");
put("RP", "Revo");
put("REV", "Revomovil");
put("8R", "Retroid Pocket");
put("RIC", "Ricoh");
put("RI", "Rikomagic");
put("RM", "RIM");
put("RN", "Rinno");
put("RX", "Ritmix");
put("R7", "Ritzviva");
put("RV", "Riviera");
put("6R", "Rivo");
put("RIZ", "Rizzen");
put("RR", "Roadrover");
put("QR", "ROADMAX");
put("ROC", "Roam Cat");
put("R1", "Rokit");
put("ROI", "ROiK");
put("RK", "Roku");
put("R3", "Rombica");
put("R5", "Ross&Moor");
put("RO", "Rover");
put("R6", "RoverPad");
put("RQ", "RoyQueen");
put("RJ", "Royole");
put("RT", "RT Project");
put("RG", "RugGear");
put("RUG", "Ruggex");
put("RUT", "RuggeTech");
put("RU", "Runbo");
put("RUP", "Rupa");
put("RL", "Ruio");
put("RY", "Ryte");
put("X5", "Saba");
put("8L", "S-TELL");
put("4O", "S2Tel");
put("89", "Seatel");
put("SEW", "Sewoo");
put("SE1", "SEEWO");
put("Y7", "Saiet");
put("X1", "Safaricom");
put("SG", "Sagem");
put("4L", "Salora");
put("SA", "Samsung");
put("SAT", "Samtech");
put("SAM", "Samtron");
put("SNA", "SNAMI");
put("S0", "Sanei");
put("12", "Sansui");
put("SAK", "Sankey");
put("SQ", "Santin");
put("SY", "Sanyo");
put("SAN", "SANY");
put("S9", "Savio");
put("Y4", "SCBC");
put("CZ", "Schneider");
put("SCO", "Scosmos");
put("ZG", "Schok");
put("G8", "SEG");
put("SD", "Sega");
put("0U", "Selecline");
put("9G", "Selenga");
put("SV", "Selevision");
put("SL", "Selfix");
put("0S", "SEMP TCL");
put("S1", "Sencor");
put("SN", "Sendo");
put("01", "Senkatel");
put("S6", "Senseit");
put("EW", "Senwa");
put("24", "Seeken");
put("SEB", "SEBBE");
put("61", "Seuic");
put("SX", "SFR");
put("SGI", "SGIN");
put("SH", "Sharp");
put("JU", "Shanling");
put("7S", "Shift Phones");
put("78", "Shivaki");
put("RS", "Shtrikh-M");
put("3S", "Shuttle");
put("13", "Sico");
put("SI", "Siemens");
put("1S", "Sigma");
put("70", "Silelis");
put("SJ", "Silent Circle");
put("10", "Simbans");
put("98", "Simply");
put("52", "Singtech");
put("31", "Siragon");
put("83", "Sirin Labs");
put("5Z", "SK Broadband");
put("GK", "SKG");
put("SW", "Sky");
put("SK", "Skyworth");
put("SKY", "Skyline");
put("SK1", "SkyStream");
put("SKK", "SKK Mobile");
put("14", "Smadl");
put("19", "Smailo");
put("SR", "Smart Electronic");
put("SMA", "Smart Kassel");
put("49", "Smart");
put("47", "SmartBook");
put("3B", "Smartab");
put("80", "SMARTEC");
put("SM1", "Smartex");
put("SC", "Smartfren");
put("S7", "Smartisan");
put("JR", "Sylvania");
put("SYH", "SYH");
put("3Y", "Smarty");
put("HH", "Smooth Mobile");
put("1Q", "Smotreshka");
put("SF", "Softbank");
put("9L", "SOLE");
put("JL", "SOLO");
put("SOS", "SOSH");
put("SOD", "Soda");
put("16", "Solone");
put("OI", "Sonim");
put("SO", "Sony");
put("SE", "Sony Ericsson");
put("X2", "Soundmax");
put("8S", "Soyes");
put("77", "SONOS");
put("68", "Soho Style");
put("PK", "Spark");
put("FS", "SPC");
put("6S", "Spectrum");
put("43", "Spectralink");
put("SP", "Spice");
put("84", "Sprint");
put("QS", "SQOOL");
put("S4", "Star");
put("OL", "Starlight");
put("18", "Starmobile");
put("2S", "Starway");
put("45", "Starwind");
put("SB", "STF Mobile");
put("S8", "STK");
put("GQ", "STG Telecom");
put("S2", "Stonex");
put("ST", "Storex");
put("STR", "Stream");
put("71", "StrawBerry");
put("96", "STRONG");
put("69", "Stylo");
put("9S", "Sugar");
put("SUR", "Surge");
put("06", "Subor");
put("SZ", "Sumvision");
put("0H", "Sunstech");
put("S3", "SunVan");
put("5S", "Sunvell");
put("5Y", "Sunny");
put("W8", "SUNWIND");
put("SBX", "SuperBOX");
put("SU", "SuperSonic");
put("79", "SuperTab");
put("S5", "Supra");
put("SUP", "Supraim");
put("ZS", "Suzuki");
put("2J", "Sunmi");
put("SUN", "Sunmax");
put("0W", "Swipe");
put("SWI", "Switel");
put("SS", "SWISSMOBILITY");
put("1W", "Swisstone");
put("W7", "SWTV");
put("SSK", "SSKY");
put("SYC", "Syco");
put("SM", "Symphony");
put("4S", "Syrox");
put("TM", "T-Mobile");
put("T96", "T96");
put("TK", "Takara");
put("73", "Tambo");
put("9N", "Tanix");
put("U5", "Taiga System");
put("TAL", "Talius");
put("7G", "TAG Tech");
put("T5", "TB Touch");
put("TC", "TCL");
put("T0", "TD Systems");
put("YY", "TD Tech");
put("H4", "Technicolor");
put("TEA", "TeachTouch");
put("Z5", "Technika");
put("TX", "TechniSat");
put("TT", "TechnoTrend");
put("TP", "TechPad");
put("TPS", "TPS");
put("9E", "Techwood");
put("7F", "Technopc");
put("T7", "Teclast");
put("TB", "Tecno Mobile");
put("TEC", "TecToy");
put("91", "TEENO");
put("2L", "Tele2");
put("TL", "Telefunken");
put("TG", "Telego");
put("T2", "Telenor");
put("TE", "Telit");
put("65", "Telia");
put("TEL", "Telma");
put("PW", "Telpo");
put("TLS", "TeloSystems");
put("TER", "Teracube");
put("TD", "Tesco");
put("TA", "Tesla");
put("9T", "Tetratab");
put("TET", "TETC");
put("TZ", "teXet");
put("29", "Teknosa");
put("JZ", "TJC");
put("JC", "TENPLUS");
put("T4", "ThL");
put("TN", "Thomson");
put("O0", "Thuraya");
put("TI", "TIANYU");
put("JY", "Tigers");
put("8T", "Time2");
put("TQ", "Timovi");
put("TIM", "TIMvision");
put("2T", "Tinai");
put("TF", "Tinmo");
put("TH", "TiPhone");
put("YV", "TiVo");
put("TIB", "Tibuta");
put("Y3", "TOKYO");
put("TOX", "TOX");
put("T1", "Tolino");
put("0T", "Tone");
put("TY", "Tooky");
put("T9", "Top House");
put("DK", "Topelotek");
put("42", "Topway");
put("TO", "Toplux");
put("TOD", "TOPDON");
put("TOP", "TopDevice");
put("TO2", "TOPSHOWS");
put("7T", "Torex");
put("TOR", "Torque");
put("6O", "TOSCIDO");
put("TO1", "Topsion");
put("TS", "Toshiba");
put("T8", "Touchmate");
put("TOU", "Touch Plus");
put("5R", "Transpeed");
put("T6", "TrekStor");
put("T3", "Trevi");
put("TJ", "Trifone");
put("Q5", "Trident");
put("4T", "Tronsmart");
put("11", "True");
put("JT", "True Slim");
put("J1", "Trio");
put("5C", "TTEC");
put("TTK", "TTK-TV");
put("TU", "Tunisie Telecom");
put("1T", "Turbo");
put("TR", "Turbo-X");
put("5X", "TurboPad");
put("5T", "TurboKids");
put("UR", "Turkcell");
put("4U", "TuCEL");
put("2U", "Türk Telekom");
put("TV", "TVC");
put("TW", "TWM");
put("Z1", "TWZ");
put("6T", "Twoe");
put("15", "Tymes");
put("UC", "U.S. Cellular");
put("UG", "Ugoos");
put("U1", "Uhans");
put("UH", "Uhappy");
put("UL", "Ulefone");
put("UA", "Umax");
put("UM", "UMIDIGI");
put("UNT", "Unitech");
put("UZ", "Unihertz");
put("3Z", "UZ Mobile");
put("UX", "Unimax");
put("UNQ", "Uniqcell");
put("US", "Uniscope");
put("UNI", "Unistrong");
put("U2", "UNIWA");
put("UND", "Uniden");
put("UO", "Unnecto");
put("UNN", "Unnion Technologies");
put("UU", "Unonu");
put("UN", "Unowhy");
put("UY", "UNNO");
put("UNB", "Unblock Tech");
put("UK", "UTOK");
put("3U", "IUNI");
put("UT", "UTStarcom");
put("6U", "UTime");
put("9U", "Urovo");
put("UW", "U-Magic");
put("5V", "VAIO");
put("WV", "VAVA");
put("VA", "Vastking");
put("VP", "Vargo");
put("VC", "Vankyo");
put("VAL", "VALEM");
put("VAT", "VALTECH");
put("VB", "VC");
put("VN", "Venso");
put("VEN", "Venstar");
put("UV", "Venturer");
put("VQ", "Vega");
put("WC", "VEON");
put("4V", "Verico");
put("V4", "Verizon");
put("VR", "Vernee");
put("VX", "Vertex");
put("VE", "Vertu");
put("VL", "Verykool");
put("QV", "Verssed");
put("VER", "Versus");
put("V8", "Vesta");
put("VT", "Vestel");
put("48", "Vexia");
put("V6", "VGO TEL");
put("QJ", "VDVD");
put("VIC", "Victurio");
put("VD", "Videocon");
put("VW", "Videoweb");
put("VS", "ViewSonic");
put("V7", "Vinga");
put("V3", "Vinsoc");
put("XD", "Vinabox");
put("FV", "Vios");
put("0V", "Vipro");
put("ZV", "Virzo");
put("VIP", "Viper");
put("VI", "Vitelcom");
put("VIB", "ViBox");
put("8V", "Viumee");
put("V5", "Vivax");
put("VIV", "VIVIMAGE");
put("VV", "Vivo");
put("6V", "VIWA");
put("VII", "VIIPOO");
put("VID", "VIDA");
put("VZ", "Vizio");
put("VIZ", "Vizmo");
put("VIT", "Vityaz");
put("9V", "Vision Touch");
put("VK", "VK Mobile");
put("JM", "v-mobile");
put("VHO", "V-HOPE");
put("VHM", "V-HOME");
put("VGE", "V-Gen");
put("V0", "VKworld");
put("VM", "Vodacom");
put("VF", "Vodafone");
put("7W", "VOGA");
put("V2", "Vonino");
put("1V", "Vontar");
put("VG", "Vorago");
put("2V", "Vorke");
put("8U", "Vorcom");
put("JW", "Vortex");
put("VOR", "Vormor");
put("V1", "Voto");
put("Z7", "VOX");
put("VO", "Voxtel");
put("VY", "Voyo");
put("VOL", "Völfen");
put("VO1", "Volt");
put("VH", "Vsmart");
put("V9", "Vsun");
put("VU", "Vulcan");
put("3V", "VVETIME");
put("ZC", "VUCATIMES");
put("VUE", "Vue Micro");
put("WA", "Walton");
put("WAF", "WAF");
put("WAL", "Waltter");
put("WHI", "White Mobile");
put("WM", "Weimei");
put("WE", "WellcoM");
put("W6", "WELLINGTON");
put("WD", "Western Digital");
put("WT", "Westpoint");
put("WAN", "Wanmukang");
put("WA1", "WANSA");
put("WY", "Wexler");
put("3W", "WE");
put("WEC", "Wecool");
put("WEE", "Weelikeit");
put("WP", "Wieppo");
put("W2", "Wigor");
put("WI", "Wiko");
put("WF", "Wileyfox");
put("WS", "Winds");
put("WN", "Wink");
put("9W", "Winmax");
put("W5", "Winnovo");
put("WU", "Wintouch");
put("WIS", "Winstar");
put("W0", "Wiseasy");
put("2W", "Wizz");
put("W4", "WIWA");
put("WIZ", "WizarPos");
put("WL", "Wolder");
put("WG", "Wolfgang");
put("WQ", "Wolki");
put("WO", "Wonu");
put("W1", "Woo");
put("WR", "Wortmann");
put("WX", "Woxter");
put("XQ", "X-AGE");
put("XEL", "XElectron");
put("X3", "X-BO");
put("XMO", "X-Mobile");
put("XT", "X-TIGI");
put("XV", "X-View");
put("X4", "X.Vision");
put("X88", "X88");
put("X96", "X96");
put("96Q", "X96Q");
put("XG", "Xgody");
put("QX", "XGIMI");
put("XL", "Xiaolajiao");
put("XI", "Xiaomi");
put("XW", "Xiaodu");
put("XN", "Xion");
put("XO", "Xolo");
put("XR", "Xoro");
put("XS", "Xshitou");
put("4X", "Xtouch");
put("X8", "Xtratech");
put("XCR", "Xcruiser");
put("XCO", "XCOM");
put("XWA", "Xwave");
put("YD", "Yandex");
put("YA", "Yarvik");
put("Y2", "Yes");
put("YES", "Yestel");
put("YE", "Yezz");
put("YG", "YEPEN");
put("YEL", "YELLYOUTH");
put("YK", "Yoka TV");
put("YO", "Yota");
put("YOU", "Youin");
put("YO1", "Youwei");
put("YOO", "Yooz");
put("YT", "Ytone");
put("Y9", "YOTOPT");
put("Y1", "Yu");
put("YF", "YU Fly");
put("Y0", "YUHO");
put("YN", "Yuno");
put("YUN", "YUNDOO");
put("YUS", "YunSong");
put("YUM", "YUMKEM");
put("YU", "Yuandao");
put("YS", "Yusun");
put("YJ", "YASIN");
put("YX", "Yxtel");
put("0Z", "Zatec");
put("2Z", "Zaith");
put("ZAM", "Zamolxe");
put("ZEA", "Zealot");
put("PZ", "Zebra");
put("ZE", "Zeemi");
put("WZ", "Zeeker");
put("ZN", "Zen");
put("ZK", "Zenek");
put("ZL", "Zentality");
put("ZF", "Zfiner");
put("ZI", "Zidoo");
put("FZ", "ZIFRO");
put("ZX", "Ziox");
put("ZIK", "ZIK");
put("ZIG", "Zigo");
put("ZIN", "Zinox");
put("ZO", "Zonda");
put("ZW", "Zonko");
put("ZP", "Zopo");
put("ZOO", "ZoomSmart");
put("ZO1", "Zoom");
put("ZT", "ZTE");
put("ZU", "Zuum");
put("ZY", "Zync");
put("ZR", "Zyrex");
put("ZQ", "ZYQ");
put("Z4", "ZH&K");
put("OW", "öwn");
put("WBF", "Webfleet");
// 旧品牌,可能会在未来版本中删除
put("WB", "Web TV");
put("XX", "Unknown");
}
};
public AbstractDeviceParser() {
super();
}
public AbstractDeviceParser(String ua) {
super(ua);
}
public AbstractDeviceParser(String ua, ClientHints clientHints) {
super(ua, clientHints);
}
/**
* 返回由 DEVICE_TYPE_* 常量之一表示的设备类型
*
* @return int | null
*/
public int getDeviceType() {
return deviceType;
}
/**
* 返回可用的设备类型
*
* @return {@code Map}
* @see #deviceTypes
*/
public static Map getAvailableDeviceTypes() {
return deviceTypes;
}
/**
* 返回所有可用的设备类型名称。
*
* @return 返回 {@link #deviceTypes} 的所有键名
*/
public static Set getAvailableDeviceTypeNames() {
return deviceTypes.keySet();
}
/**
* 返回指定设备类型的名称。
*
* @param deviceType DEVICE_TYPE_* 常量中的一个
* @return 如果 {@link #deviceTypes} 包含指定的值(形参:deviceType),返回首个相应的键名,否则返回空。
*/
public static String getDeviceTypeName(int deviceType) {
for (Map.Entry entry : deviceTypes.entrySet()) {
if (entry.getValue().equals(deviceType)) {
return entry.getKey();
}
}
return "";
}
/**
* 返回检测到的设备型号。
*
* @return String
*/
public String getModel() {
return model;
}
/**
* 返回检测到的设备品牌。
*
* @return String
*/
public String getBrand() {
return brand;
}
/**
* 返回指定品牌ID的完整品牌名称。
*
* @param brandId 品牌ID
* @return 如果 {@link #deviceBrands} 包含指定的键名(形参:brandId),返回首个相应的值,否则返回空。
*/
public static String getFullName(String brandId) {
if (deviceBrands.containsKey(brandId)) {
return deviceBrands.get(brandId);
}
return "";
}
/**
* 返回指定名称的品牌短代码
*
* @param brand 品牌名称
* @return 如果 {@link #deviceBrands} 包含指定的值(形参:brand),返回首个相应的键名,否则返回空。
* @deprecated since 4.0 - 短代码可能会在下一个主要版本中被删除
*/
public static String getShortCode(String brand) {
for (Map.Entry entry : deviceBrands.entrySet()) {
if (entry.getValue().equals(brand)) {
return entry.getKey();
}
}
return "";
}
/**
* 设置要解析的UserAgent
*/
public void setUserAgent(String userAgent) {
reset();
super.setUserAgent(userAgent);
}
/**
* 解析当前设置的 UserAgent 并返回可能的结果
*/
public abstract Map parse() throws Exception;
/**
* {@inheritDoc}
*
* @return {@code Map | null}
*/
public Map parse(String fixtureFile) throws Exception {
Map resultClientHint = parseClientHints();
String deviceModel = "";
if (resultClientHint != null) {
deviceModel = resultClientHint.getOrDefault("model", "");
}
if ("".equals(deviceModel) && hasDesktopFragment()) {
return getResult();
}
String brand = "";
Map regexes = getRegexes(fixtureFile, String.class, Device.class);
List matches = null;
Device regex = null;
for (Map.Entry entry : regexes.entrySet()) {
brand = entry.getKey();
regex = entry.getValue();
matches = matchUserAgent(regex.getRegex());
if (!isNullOrEmpty(matches)) {
break;
}
}
if (isNullOrEmpty(matches)) {
return resultClientHint;
}
if (!"Unknown".equals(brand)) {
if (!deviceBrands.containsValue(brand)) {
// 这个异常应该永远不会被抛出。如果发生,表示在 deviceBrands 数组中缺少定义的品牌名称
throw new Exception(String.format(
"名为 '%s' 的品牌应该被列入在 deviceBrands 集合中。尝试解析 UserAgent: %s",
brand,
userAgent
)); // @codeCoverageIgnore
}
this.brand = brand;
}
if (regex.getDevice() != null && deviceTypes.containsKey(regex.getDevice())) {
deviceType = deviceTypes.get(regex.getDevice());
}
model = "";
if (regex.getModel() != null) {
model = buildModel(regex.getModel(), matches);
}
if (regex.getModels() != null) {
Map modelRegex = null;
List modelMatches = null;
for (Map $modelRegex : regex.getModels()) {
modelRegex = $modelRegex;
modelMatches = matchUserAgent($modelRegex.get("regex"));
if (!isNullOrEmpty(modelMatches)) {
break;
}
}
if (isNullOrEmpty(modelMatches)) {
return getResult();
}
model = buildModel(modelRegex.get("model"), modelMatches);
if (modelRegex.get("brand") != null && deviceBrands.containsValue(modelRegex.get("brand"))) {
this.brand = modelRegex.get("brand");
}
if (modelRegex.get("device") != null && deviceTypes.containsKey(modelRegex.get("device"))) {
deviceType = deviceTypes.get(modelRegex.get("device"));
}
}
return getResult();
}
/**
* @param model
* @param matches
* @return String
*/
private String buildModel(String model, List matches) {
model = buildByMatch(model, matches);
model = model.replace("_", " ");
model = Pattern.compile(" TD$", Pattern.CASE_INSENSITIVE).matcher(model).replaceAll("");
if ("Build".equals(model) || isNullOrEmpty(model)) {
return "";
}
return model.trim();
}
/**
* @return 如果条件 {@code clientHints != null && !isNullOrEmpty(clientHints.getModel())} 不成立,则返回 null
*/
private Map parseClientHints() {
if (clientHints != null && !isNullOrEmpty(clientHints.getModel())) {
Map result = new HashMap<>();
result.put("deviceType", null);
result.put("model", clientHints.getModel());
result.put("brand", "");
return result;
}
return null;
}
/**
* 如果解析的 UA 包含 'Windows NT;' 或 'X11; Linux x86_64' 片段,则返回 true
*/
protected boolean hasDesktopFragment() throws Exception {
return !isNullOrEmpty(matchUserAgent("(?:Windows (?:NT|IoT)|X11; Linux x86_64)")) &&
isNullOrEmpty(matchUserAgent(" Mozilla/|Andr[o0]id|Tablet|Mobile|iPhone|Windows Phone|ricoh|OculusBrowser")) &&
isNullOrEmpty(matchUserAgent("Lenovo|compatible; MSIE|Trident/|Tesla/|XBOX|FBMD/|ARM; ?([^)]+)"));
}
/**
* 重置存储值
*/
protected void reset() {
deviceType = null;
model = "";
brand = "";
}
/**
* @return {@code Map}
*/
protected Map getResult() {
Map result = new HashMap<>();
result.put("deviceType", deviceType == null ? null : String.valueOf(deviceType));
result.put("model", model);
result.put("brand", brand);
return result;
}
/**
* {@inheritDoc}
*/
protected List preMatchOverall(String fixtureFile) throws Exception {
Map> regexes = getRegexes(fixtureFile, String.class, Map.class);
List reversedList = new ArrayList<>();
for (Map.Entry> entry : regexes.entrySet()) {
Map item = entry.getValue();
reversedList.add(item.get("regex"));
}
Collections.reverse(reversedList);
overAllMatch = String.join("|", reversedList);
return matchUserAgent(overAllMatch);
}
}