########################################################
# NOTICE: this file is autogenerated from regexes.yaml #
########################################################
__all__ = [
    "USER_AGENT_PARSERS",
    "DEVICE_PARSERS",
    "OS_PARSERS",
]

from ua_parser.user_agent_parser import UserAgentParser, DeviceParser, OSParser

USER_AGENT_PARSERS = [
    UserAgentParser('(GeoEvent Server) (\\d+)(?:\\.(\\d+)(?:\\.(\\d+)|)|)'),
    UserAgentParser('(ArcGIS Pro)(?: (\\d+)\\.(\\d+)\\.([^ ]+)|)'),
    UserAgentParser('ArcGIS Client Using WinInet', 'ArcMap'),
    UserAgentParser('(OperationsDashboard)-(?:Windows)-(\\d+)\\.(\\d+)\\.(\\d+)', 'Operations Dashboard for ArcGIS'),
    UserAgentParser('(arcgisearth)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)', 'ArcGIS Earth'),
    UserAgentParser('com.esri.(earth).phone/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)', 'ArcGIS Earth'),
    UserAgentParser('(arcgis-explorer)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Explorer for ArcGIS'),
    UserAgentParser('arcgis-(collector|aurora)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Collector for ArcGIS'),
    UserAgentParser('(arcgis-workforce)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Workforce for ArcGIS'),
    UserAgentParser('(Collector|Explorer|Workforce)-(?:Android|iOS)-(\\d+)\\.(\\d+)(?:\\.(\\d+)|)', '$1 for ArcGIS'),
    UserAgentParser('(Explorer|Collector)/(\\d+) CFNetwork', '$1 for ArcGIS'),
    UserAgentParser('ArcGISRuntime-(Android|iOS|NET|Qt)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)', 'ArcGIS Runtime SDK for $1'),
    UserAgentParser('ArcGIS\\.?(iOS|Android|NET|Qt)(?:-|\\.)(\\d+)\\.(\\d+)(?:\\.(\\d+)|)', 'ArcGIS Runtime SDK for $1'),
    UserAgentParser('ArcGIS\\.Runtime\\.(Qt)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+)|)', 'ArcGIS Runtime SDK for $1'),
    UserAgentParser('^(Luminary)[Stage]+/(\\d+) CFNetwork'),
    UserAgentParser('(ESPN)[%20| ]+Radio/(\\d+)\\.(\\d+)\\.(\\d+) CFNetwork'),
    UserAgentParser('(Antenna)/(\\d+) CFNetwork', 'AntennaPod'),
    UserAgentParser('(TopPodcasts)Pro/(\\d+) CFNetwork'),
    UserAgentParser('(MusicDownloader)Lite/(\\d+)\\.(\\d+)\\.(\\d+) CFNetwork'),
    UserAgentParser('^(.{0,200})-iPad\\/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)(?:\\.(\\d+)|) CFNetwork'),
    UserAgentParser('^(.{0,200})-iPhone/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)(?:\\.(\\d+)|) CFNetwork'),
    UserAgentParser('^(.{0,200})/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)(?:\\.(\\d+)|) CFNetwork'),
    UserAgentParser('^(Luminary)/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)'),
    UserAgentParser('(espn\\.go)', 'ESPN'),
    UserAgentParser('(espnradio\\.com)', 'ESPN'),
    UserAgentParser('ESPN APP$', 'ESPN'),
    UserAgentParser('(audioboom\\.com)', 'AudioBoom'),
    UserAgentParser(' (Rivo) RHYTHM'),
    UserAgentParser('(CFNetwork)(?:/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)|)', 'CFNetwork'),
    UserAgentParser('(Pingdom\\.com_bot_version_)(\\d+)\\.(\\d+)', 'PingdomBot'),
    UserAgentParser('(PingdomTMS)/(\\d+)\\.(\\d+)\\.(\\d+)', 'PingdomBot'),
    UserAgentParser('(PingdomPageSpeed)/(\\d+)\\.(\\d+)', 'PingdomBot'),
    UserAgentParser(' (PTST)/(\\d+)(?:\\.(\\d+)|)$', 'WebPageTest.org bot'),
    UserAgentParser('X11; (Datanyze); Linux'),
    UserAgentParser('(NewRelicPinger)/(\\d+)\\.(\\d+)', 'NewRelicPingerBot'),
    UserAgentParser('(RuxitSynthetic)/(\\d+)\\.(\\d+)', 'Ruxit Synthetic'),
    UserAgentParser('(Tableau)/(\\d+)\\.(\\d+)', 'Tableau'),
    UserAgentParser('AppleWebKit/\\d{1,10}\\.\\d{1,10}.{0,200} Safari.{0,200} (CreativeCloud)/(\\d+)\\.(\\d+).(\\d+)', 'Adobe CreativeCloud'),
    UserAgentParser('(Salesforce)(?:.)\\/(\\d+)\\.(\\d?)'),
    UserAgentParser('(\\(StatusCake\\))', 'StatusCakeBot'),
    UserAgentParser('(facebookexternalhit)/(\\d+)\\.(\\d+)', 'FacebookBot'),
    UserAgentParser('Google.{0,50}/\\+/web/snippet', 'GooglePlusBot'),
    UserAgentParser('via ggpht\\.com GoogleImageProxy', 'GmailImageProxy'),
    UserAgentParser('YahooMailProxy; https://help\\.yahoo\\.com/kb/yahoo-mail-proxy-SLN28749\\.html', 'YahooMailProxy'),
    UserAgentParser('(Twitterbot)/(\\d+)\\.(\\d+)', 'Twitterbot'),
    UserAgentParser('/((?:Ant-|)Nutch|[A-z]+[Bb]ot|[A-z]+[Ss]pider|Axtaris|fetchurl|Isara|ShopSalad|Tailsweep)[ \\-](\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)'),
    UserAgentParser('\\b(008|Altresium|Argus|BaiduMobaider|BoardReader|DNSGroup|DataparkSearch|EDI|Goodzer|Grub|INGRID|Infohelfer|LinkedInBot|LOOQ|Nutch|OgScrper|Pandora|PathDefender|Peew|PostPost|Steeler|Twitterbot|VSE|WebCrunch|WebZIP|Y!J-BR[A-Z]|YahooSeeker|envolk|sproose|wminer)/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)'),
    UserAgentParser('(MSIE) (\\d+)\\.(\\d+)([a-z]\\d|[a-z]|);.{0,200} MSIECrawler', 'MSIECrawler'),
    UserAgentParser('(DAVdroid)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)'),
    UserAgentParser('(Google-HTTP-Java-Client|Apache-HttpClient|PostmanRuntime|Go-http-client|scalaj-http|http%20client|Python-urllib|HttpMonitor|TLSProber|WinHTTP|JNLP|okhttp|aihttp|reqwest|axios|unirest-(?:java|python|ruby|nodejs|php|net))(?:[ /](\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)|)'),
    UserAgentParser('(Pinterest(?:bot|))/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)[;\\s(]+\\+https://www.pinterest.com/bot.html', 'Pinterestbot'),
    UserAgentParser('(CSimpleSpider|Cityreview Robot|CrawlDaddy|CrawlFire|Finderbots|Index crawler|Job Roboter|KiwiStatus Spider|Lijit Crawler|QuerySeekerSpider|ScollSpider|Trends Crawler|USyd-NLP-Spider|SiteCat Webbot|BotName\\/\\$BotVersion|123metaspider-Bot|1470\\.net crawler|50\\.nu|8bo Crawler Bot|Aboundex|Accoona-[A-z]{1,30}-Agent|AdsBot-Google(?:-[a-z]{1,30}|)|altavista|AppEngine-Google|archive.{0,30}\\.org_bot|archiver|Ask Jeeves|[Bb]ai[Dd]u[Ss]pider(?:-[A-Za-z]{1,30})(?:-[A-Za-z]{1,30}|)|bingbot|BingPreview|blitzbot|BlogBridge|Bloglovin|BoardReader Blog Indexer|BoardReader Favicon Fetcher|boitho.com-dc|BotSeer|BUbiNG|\\b\\w{0,30}favicon\\w{0,30}\\b|\\bYeti(?:-[a-z]{1,30}|)|Catchpoint(?: bot|)|[Cc]harlotte|Checklinks|clumboot|Comodo HTTP\\(S\\) Crawler|Comodo-Webinspector-Crawler|ConveraCrawler|CRAWL-E|CrawlConvera|Daumoa(?:-feedfetcher|)|Feed Seeker Bot|Feedbin|findlinks|Flamingo_SearchEngine|FollowSite Bot|furlbot|Genieo|gigabot|GomezAgent|gonzo1|(?:[a-zA-Z]{1,30}-|)Googlebot(?:-[a-zA-Z]{1,30}|)|GoogleOther|Google SketchUp|grub-client|gsa-crawler|heritrix|HiddenMarket|holmes|HooWWWer|htdig|ia_archiver|ICC-Crawler|Icarus6j|ichiro(?:/mobile|)|IconSurf|IlTrovatore(?:-Setaccio|)|InfuzApp|Innovazion Crawler|InternetArchive|IP2[a-z]{1,30}Bot|jbot\\b|KaloogaBot|Kraken|Kurzor|larbin|LEIA|LesnikBot|Linguee Bot|LinkAider|LinkedInBot|Lite Bot|Llaut|lycos|Mail\\.RU_Bot|masscan|masidani_bot|Mediapartners-Google|Microsoft .{0,30} Bot|mogimogi|mozDex|MJ12bot|msnbot(?:-media {0,2}|)|msrbot|Mtps Feed Aggregation System|netresearch|Netvibes|NewsGator[^/]{0,30}|^NING|Nutch[^/]{0,30}|Nymesis|ObjectsSearch|OgScrper|Orbiter|OOZBOT|PagePeeker|PagesInventory|PaxleFramework|Peeplo Screenshot Bot|PHPCrawl|PlantyNet_WebRobot|Pompos|Qwantify|Read%20Later|Reaper|RedCarpet|Retreiver|Riddler|Rival IQ|scooter|Scrapy|Scrubby|searchsight|seekbot|semanticdiscovery|SemrushBot|Simpy|SimplePie|SEOstats|SimpleRSS|SiteCon|Slackbot-LinkExpanding|Slack-ImgProxy|Slurp|snappy|Speedy Spider|Squrl Java|Stringer|TheUsefulbot|ThumbShotsBot|Thumbshots\\.ru|Tiny Tiny RSS|Twitterbot|WhatsApp|URL2PNG|Vagabondo|VoilaBot|^vortex|Votay bot|^voyager|WASALive.Bot|Web-sniffer|WebThumb|WeSEE:[A-z]{1,30}|WhatWeb|WIRE|WordPress|Wotbox|www\\.almaden\\.ibm\\.com|Xenu(?:.s|) Link Sleuth|Xerka [A-z]{1,30}Bot|yacy(?:bot|)|YahooSeeker|Yahoo! Slurp|Yandex\\w{1,30}|YodaoBot(?:-[A-z]{1,30}|)|YottaaMonitor|Yowedo|^Zao|^Zao-Crawler|ZeBot_www\\.ze\\.bz|ZooShot|ZyBorg|ArcGIS Hub Indexer|GPTBot|Google-InspectionTool)(?:[ /]v?(\\d+)(?:\\.(\\d+)(?:\\.(\\d+)|)|)|)'),
    UserAgentParser('\\b(Boto3?|JetS3t|aws-(?:cli|sdk-(?:cpp|go|go-v\\d|java|nodejs|ruby2?|dotnet-(?:\\d{1,2}|core)))|s3fs)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)'),
    UserAgentParser('(FME)\\/(\\d+\\.\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('(QGIS)\\/(\\d)\\.?0?(\\d{1,2})\\.?0?(\\d{1,2})'),
    UserAgentParser('(JOSM)/(\\d+)\\.(\\d+)'),
    UserAgentParser('(Tygron Platform) \\((\\d+)\\.(\\d+)\\.(\\d+(?:\\.\\d+| RC \\d+\\.\\d+))'),
    UserAgentParser('\\[(FBAN/MessengerForiOS|FB_IAB/MESSENGER);FBAV/(\\d+)(?:\\.(\\d+)(?:\\.(\\d+)(?:\\.(\\d+)|)|)|)', 'Facebook Messenger'),
    UserAgentParser('\\[FB.{0,300};(FBAV)/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)', 'Facebook'),
    UserAgentParser('\\[FB.{0,300};', 'Facebook'),
    UserAgentParser('(RecipeRadar)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)'),
    UserAgentParser('^.{0,200}?(?:\\/[A-Za-z0-9\\.]{0,50}|) {0,2}([A-Za-z0-9 \\-_\\!\\[\\]:]{0,50}(?:[Aa]rchiver|[Ii]ndexer|[Ss]craper|[Bb]ot|[Ss]pider|[Cc]rawl[a-z]{0,50}))[/ ](\\d+)(?:\\.(\\d+)(?:\\.(\\d+)|)|)'),
    UserAgentParser('^.{0,200}?((?:[A-Za-z][A-Za-z0-9 -]{0,50}|)[^C][^Uu][Bb]ot)\\b(?:(?:[ /]| v)(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)|)'),
    UserAgentParser('^.{0,200}?((?:[A-z0-9]{1,50}|[A-z\\-]{1,50} ?|)(?: the |)(?:[Ss][Pp][Ii][Dd][Ee][Rr]|[Ss]crape|[Cc][Rr][Aa][Ww][Ll])[A-z0-9]{0,50})(?:(?:[ /]| v)(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)|)'),
    UserAgentParser('(HbbTV)/(\\d+)\\.(\\d+)\\.(\\d+) \\('),
    UserAgentParser('(Chimera|SeaMonkey|Camino|Waterfox)/(\\d+)\\.(\\d+)\\.?([ab]?\\d+[a-z]*|)'),
    UserAgentParser('(SailfishBrowser)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)', 'Sailfish Browser'),
    UserAgentParser('\\[(Pinterest)/[^\\]]{1,50}\\]'),
    UserAgentParser('(Pinterest)(?: for Android(?: Tablet|)|)/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)'),
    UserAgentParser('Mozilla.{1,200}Mobile.{1,100}(Instagram).(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('(Instagram) (\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('Mozilla.{1,200}Mobile.{1,100}(Flipboard).(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('Mozilla.{1,200}Mobile.{1,100}(Flipboard-Briefing).(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('Mozilla.{1,200}Mobile.{1,100}(Onefootball)\\/Android.(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('(Snapchat)\\/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('(Twitter for (?:iPhone|iPad)|TwitterAndroid)(?:\\/(\\d+)\\.(\\d+)|)', 'Twitter'),
    UserAgentParser('(musical_ly) app_version\\/(\\d+)\\.(\\d+)\\.(\\d+)', 'TikTok'),
    UserAgentParser('(musical_ly_)(\\d+)\\.(\\d+)\\.(\\d+)', 'TikTok'),
    UserAgentParser('(BytedanceWebview)\\/[a-z0-9]+', 'TikTok'),
    UserAgentParser('Mozilla.{1,200}Mobile.{1,100}(KAKAOTALK)/(\\d+)\\.(\\d+)\\.(\\d+)', 'KakaoTalk'),
    UserAgentParser('(Telegram-Android)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Telegram'),
    UserAgentParser('Mozilla.{1,200}Mobile.{1,100}(Phantom\\/ios|Phantom\\/android).(\\d+)\\.(\\d+)\\.(\\d+)', 'Phantom'),
    UserAgentParser('Mozilla.{1,100}Mobile.{1,100}(AspiegelBot|PetalBot)', 'Spider'),
    UserAgentParser('AspiegelBot|PetalBot', 'Spider'),
    UserAgentParser('(Firefox)/(\\d+)\\.(\\d+) Basilisk/(\\d+)', 'Basilisk'),
    UserAgentParser('(PaleMoon)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)', 'Pale Moon'),
    UserAgentParser('(Camoufox) Camoufox (\\d+)\\.(\\d+)'),
    UserAgentParser('(Fennec)/(\\d+)\\.(\\d+)\\.?([ab]?\\d+[a-z]*)', 'Firefox Mobile'),
    UserAgentParser('(Fennec)/(\\d+)\\.(\\d+)(pre)', 'Firefox Mobile'),
    UserAgentParser('(Fennec)/(\\d+)\\.(\\d+)', 'Firefox Mobile'),
    UserAgentParser('(?:Mobile|Tablet);.{0,200}(Firefox)/(\\d+)\\.(\\d+)', 'Firefox Mobile'),
    UserAgentParser('(Namoroka|Shiretoko|Minefield)/(\\d+)\\.(\\d+)\\.(\\d+(?:pre|))', 'Firefox ($1)'),
    UserAgentParser('(Firefox)/(\\d+)\\.(\\d+)(a\\d+[a-z]*)', 'Firefox Alpha'),
    UserAgentParser('(Firefox)/(\\d+)\\.(\\d+)(b\\d+[a-z]*)', 'Firefox Beta'),
    UserAgentParser('(Firefox)-(?:\\d+\\.\\d+|)/(\\d+)\\.(\\d+)(a\\d+[a-z]*)', 'Firefox Alpha'),
    UserAgentParser('(Firefox)-(?:\\d+\\.\\d+|)/(\\d+)\\.(\\d+)(b\\d+[a-z]*)', 'Firefox Beta'),
    UserAgentParser('(Namoroka|Shiretoko|Minefield)/(\\d+)\\.(\\d+)([ab]\\d+[a-z]*|)', 'Firefox ($1)'),
    UserAgentParser('(Firefox).{0,200}Tablet browser (\\d+)\\.(\\d+)\\.(\\d+)', 'MicroB'),
    UserAgentParser('(MozillaDeveloperPreview)/(\\d+)\\.(\\d+)([ab]\\d+[a-z]*|)'),
    UserAgentParser('(FxiOS)/(\\d+)\\.(\\d+)(\\.(\\d+)|)(\\.(\\d+)|)', 'Firefox iOS'),
    UserAgentParser('(Flock)/(\\d+)\\.(\\d+)(b\\d+?)'),
    UserAgentParser('(RockMelt)/(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('(Navigator)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Netscape'),
    UserAgentParser('(Navigator)/(\\d+)\\.(\\d+)([ab]\\d+)', 'Netscape'),
    UserAgentParser('(Netscape6)/(\\d+)\\.(\\d+)\\.?([ab]?\\d+|)', 'Netscape'),
    UserAgentParser('(MyIBrow)/(\\d+)\\.(\\d+)', 'My Internet Browser'),
    UserAgentParser('(UC? ?Browser|UCWEB|UCMobile|U3)[ /]?(\\d+)\\.(\\d+)\\.(\\d+)', 'UC Browser'),
    UserAgentParser('(Opera Tablet).{0,200}Version/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)'),
    UserAgentParser('(Opera Mini)(?:/att|)/?(\\d+|)(?:\\.(\\d+)|)(?:\\.(\\d+)|)'),
    UserAgentParser('(Opera)/.{1,100}Opera Mobi.{1,100}Version/(\\d+)\\.(\\d+)', 'Opera Mobile'),
    UserAgentParser('(Opera)/(\\d+)\\.(\\d+).{1,100}Opera Mobi', 'Opera Mobile'),
    UserAgentParser('Opera Mobi.{1,100}(Opera)(?:/|\\s+)(\\d+)\\.(\\d+)', 'Opera Mobile'),
    UserAgentParser('Opera Mobi', 'Opera Mobile'),
    UserAgentParser('(Opera)/9.80.{0,200}Version/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)'),
    UserAgentParser('(?:Mobile Safari).{1,300}(OPR)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Opera Mobile'),
    UserAgentParser('(?:Chrome).{1,300}(OPR)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Opera'),
    UserAgentParser('(OPX)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)', 'Opera GX'),
    UserAgentParser('(OPT)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)', 'Opera Touch'),
    UserAgentParser('(Coast)/(\\d+).(\\d+).(\\d+)', 'Opera Coast'),
    UserAgentParser('(OPiOS)/(\\d+).(\\d+).(\\d+)', 'Opera Mini'),
    UserAgentParser('Chrome/.{1,200}( MMS)/(\\d+).(\\d+).(\\d+)', 'Opera Neon'),
    UserAgentParser('(hpw|web)OS/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)', 'webOS Browser'),
    UserAgentParser('(luakit)', 'LuaKit'),
    UserAgentParser('(Snowshoe)/(\\d+)\\.(\\d+).(\\d+)'),
    UserAgentParser('Gecko/\\d+ (Lightning)/(\\d+)\\.(\\d+)\\.?((?:[ab]?\\d+[a-z]*)|(?:\\d*))'),
    UserAgentParser('(Firefox)/(\\d+)\\.(\\d+)\\.(\\d+(?:pre|)) \\(Swiftfox\\)', 'Swiftfox'),
    UserAgentParser('(Firefox)/(\\d+)\\.(\\d+)([ab]\\d+[a-z]*|) \\(Swiftfox\\)', 'Swiftfox'),
    UserAgentParser('(rekonq)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|) Safari', 'Rekonq'),
    UserAgentParser('rekonq', 'Rekonq'),
    UserAgentParser('(conkeror|Conkeror)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)', 'Conkeror'),
    UserAgentParser('(konqueror)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Konqueror'),
    UserAgentParser('(WeTab)-Browser'),
    UserAgentParser('(Comodo_Dragon)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Comodo Dragon'),
    UserAgentParser('(Symphony) (\\d+).(\\d+)'),
    UserAgentParser('PLAYSTATION 3.{1,200}WebKit', 'NetFront NX'),
    UserAgentParser('PLAYSTATION 3', 'NetFront'),
    UserAgentParser('(PlayStation Portable)', 'NetFront'),
    UserAgentParser('(PlayStation Vita)', 'NetFront NX'),
    UserAgentParser('AppleWebKit.{1,200} (NX)/(\\d+)\\.(\\d+)\\.(\\d+)', 'NetFront NX'),
    UserAgentParser('(Nintendo 3DS)', 'NetFront NX'),
    UserAgentParser('(HuaweiBrowser)/(\\d+)\\.(\\d+)\\.(\\d+)\\.\\d+', 'Huawei Browser'),
    UserAgentParser('(AVG)/(\\d+)\\.(\\d+)\\.(\\d+)\\.\\d+', 'AVG'),
    UserAgentParser('(AvastSecureBrowser|Avast)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Avast Secure Browser'),
    UserAgentParser('(Instabridge)/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)'),
    UserAgentParser('(AlohaBrowser|ABB)/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+)|)', 'Aloha Browser'),
    UserAgentParser('((?:B|b)rave(?:\\sChrome)?)/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)(?:\\.(\\d+)|)', 'Brave'),
    UserAgentParser('(?:\\()?Brave(?:\\))?\\s*$', 'Brave'),
    UserAgentParser('(Silk)/(\\d+)\\.(\\d+)(?:\\.([0-9\\-]+)|)', 'Amazon Silk'),
    UserAgentParser('(Puffin)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)'),
    UserAgentParser('Windows Phone .{0,200}(Edge)/(\\d+)\\.(\\d+)', 'Edge Mobile'),
    UserAgentParser('(EdgiOS|EdgA)/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)(?:\\.(\\d+)|)', 'Edge Mobile'),
    UserAgentParser('(OculusBrowser)/(\\d+)\\.(\\d+)(?:\\.([0-9\\-]+)|)', 'Oculus Browser'),
    UserAgentParser('(SamsungBrowser)/(\\d+)\\.(\\d+)', 'Samsung Internet'),
    UserAgentParser('(SznProhlizec)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)', 'Seznam prohlížeč'),
    UserAgentParser('(coc_coc_browser)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)', 'Coc Coc'),
    UserAgentParser('(MxBrowser)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)', 'Maxthon'),
    UserAgentParser('(Crosswalk)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('(Line)/(\\d+)\\.(\\d+)\\.(\\d+)', 'LINE'),
    UserAgentParser('(MiuiBrowser)/(\\d+)\\.(\\d+)\\.(\\d+)', 'MiuiBrowser'),
    UserAgentParser('(Mint Browser)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Mint Browser'),
    UserAgentParser('(TopBuzz)/(\\d+).(\\d+).(\\d+)', 'TopBuzz'),
    UserAgentParser('Mozilla.{1,200}Android.{1,200}(GSA)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Google'),
    UserAgentParser('(baidubrowser)[/\\s](\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)', 'Baidu Browser'),
    UserAgentParser('(FlyFlow|flyflow|baiduboxapp)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)', 'Baidu Explorer'),
    UserAgentParser('(MQQBrowser/Mini)(?:(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)|)', 'QQ Browser Mini'),
    UserAgentParser('(MQQBrowser)(?:/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)|)', 'QQ Browser Mobile'),
    UserAgentParser('(QQBrowser)(?:/(\\d+)(?:\\.(\\d+)\\.(\\d+)(?:\\.(\\d+)|)|)|)', 'QQ Browser'),
    UserAgentParser('Mozilla.{1,200}Mobile.{1,100}(DuckDuckGo)/(\\d+)', 'DuckDuckGo Mobile'),
    UserAgentParser('Mozilla.{1,200}(DuckDuckGo)/(\\d+)', 'DuckDuckGo'),
    UserAgentParser('Mozilla.{1,200}Mobile.{1,100}(Ddg)/(\\d+)(?:\\.(\\d+)|)', 'DuckDuckGo Mobile'),
    UserAgentParser('Mozilla.{1,200}(Ddg)/(\\d+)(?:\\.(\\d+)|)', 'DuckDuckGo'),
    UserAgentParser('(Tenta/)(\\d+)\\.(\\d+)\\.(\\d+)', 'Tenta Browser'),
    UserAgentParser('(Ecosia) ios@(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)(?:\\.(\\d+)|)', 'Ecosia iOS'),
    UserAgentParser('(Ecosia) android@(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)(?:\\.(\\d+)|)', 'Ecosia Android'),
    UserAgentParser('(VivoBrowser)\\/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+)|)'),
    UserAgentParser('(H[Ii]Browser)\\/v(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)', 'HiBrowser'),
    UserAgentParser('(HonorBrowser)/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+)|)', 'Honor Browser'),
    UserAgentParser('(bdhonorbrowser)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)', 'Honor Browser'),
    UserAgentParser('(HeyTapBrowser)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)', 'HeyTap Browser'),
    UserAgentParser('(weibo)__(\\d+)\\.(\\d+)\\.(\\d+)', 'Weibo'),
    UserAgentParser('(WeiboliteiOS|WeiboIntliOS)', 'Weibo'),
    UserAgentParser('(PHX)/(\\d+)\\.(\\d+)', 'Phoenix Browser'),
    UserAgentParser('Version/.{1,300}(Chrome)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)', 'Chrome Mobile WebView'),
    UserAgentParser('; wv\\).{1,300}(Chrome)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)', 'Chrome Mobile WebView'),
    UserAgentParser('(CrMo)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)', 'Chrome Mobile'),
    UserAgentParser('(CriOS)/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)(?:\\.(\\d+)|)', 'Chrome Mobile iOS'),
    UserAgentParser('(Chrome)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+) Mobile(?:[ /]|$)', 'Chrome Mobile'),
    UserAgentParser(' Mobile .{1,300}(Chrome)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)', 'Chrome Mobile'),
    UserAgentParser('(chromeframe)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Chrome Frame'),
    UserAgentParser('(SLP Browser)/(\\d+)\\.(\\d+)', 'Tizen Browser'),
    UserAgentParser('(SE 2\\.X) MetaSr (\\d+)\\.(\\d+)', 'Sogou Explorer'),
    UserAgentParser('(Rackspace Monitoring)/(\\d+)\\.(\\d+)', 'RackspaceBot'),
    UserAgentParser('(PRTG Network Monitor)'),
    UserAgentParser('(PyAMF)/(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('(YaBrowser)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Yandex Browser'),
    UserAgentParser('(YaSearchBrowser)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Yandex Browser'),
    UserAgentParser('(Chrome)/(\\d+)\\.(\\d+)\\.(\\d+).{0,100} MRCHROME', 'Mail.ru Chromium Browser'),
    UserAgentParser('(AOL) (\\d+)\\.(\\d+); AOLBuild (\\d+)'),
    UserAgentParser('(PodCruncher|Downcast)[ /]?(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)(?:\\.(\\d+)|)'),
    UserAgentParser(' (BoxNotes)/(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('(Whale)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+) Mobile(?:[ /]|$)', 'Whale'),
    UserAgentParser('(Whale)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Whale'),
    UserAgentParser('(1Password)/(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('(Ghost)/(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('PAN (GlobalProtect)/(\\d+)\\.(\\d+)\\.(\\d+) .{1,100} \\(X11; Linux x86_64\\)'),
    UserAgentParser('^(surveyon)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Surveyon'),
    UserAgentParser('(115Browser)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)', '115 Browser'),
    UserAgentParser('(Avira)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)', 'Avira'),
    UserAgentParser('(CCleaner)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)', 'CCleaner'),
    UserAgentParser('(Norton)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)', 'Norton'),
    UserAgentParser('(Quark)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Quark'),
    UserAgentParser('(QuarkPC)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Quark PC'),
    UserAgentParser('(SLBrowser)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Smart Lenovo Browser'),
    UserAgentParser('(Atom)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)', 'Atom Browser'),
    UserAgentParser('(Chrome)/\\d+\\.\\d+\\.\\d+\\.\\d+ .* QIHU 360(?:SEi18n|ENT)', '360 Secure Browser'),
    UserAgentParser('(Decentr)', 'Decentr Web3 Browser'),
    UserAgentParser('(Sparrow)', 'Sparrow Browser'),
    UserAgentParser('(Chromium GOST)', 'Chromium GOST Browser'),
    UserAgentParser('(AOLShield)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)', 'AOL Shield Browser'),
    UserAgentParser('(Hola)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Hola Browser'),
    UserAgentParser('(CravingExplorer)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Craving Explorer Browser'),
    UserAgentParser('(Talon)', 'Talon Cyber Security Browser'),
    UserAgentParser('(Qaxbrowser)', 'QAX Browser'),
    UserAgentParser('(ADG)/(\\d+)\\.(\\d+)\\.(\\d+)', 'AOL Desktop Gold Browser'),
    UserAgentParser('(SberBrowser)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)', 'Sber Browser'),
    UserAgentParser('(JiSu)/(\\d+)\\.(\\d+)\\.(\\d+)', 'JiSu Browser'),
    UserAgentParser('(Wolvic)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Wolvic Browser'),
    UserAgentParser('(Thano)/(\\d+)\\.(\\d+)', 'SmartTV WebBrowser'),
    UserAgentParser('(MicroMessenger)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)', 'WeChat Browser'),
    UserAgentParser('(Odin)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)', 'Odin'),
    UserAgentParser('(Colt)/(\\d+)\\.(\\d+)', 'NetCast Smart TV'),
    UserAgentParser('(Lite Browser)/(\\d+)\\.(\\d+)', 'Lite Browser'),
    UserAgentParser('(OMI)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Vewd Browser'),
    UserAgentParser('(Mypal)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Mypal Browser'),
    UserAgentParser('(Chesscom-Android)/(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('(RobloxApp)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Roblox App'),
    UserAgentParser('(Roadrunner)/IOS/\\d+/(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('(AncestryAndroid)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)'),
    UserAgentParser('(Slack_SSB)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Slack Desktop Client'),
    UserAgentParser('(HipChat)/?(\\d+|)', 'HipChat Desktop Client'),
    UserAgentParser('\\b(MobileIron|FireWeb|Jasmine|ANTGalio|Midori|Fresco|Lobo|PaleMoon|Maxthon|Lynx|OmniWeb|Dillo|Camino|Demeter|Fluid|Fennec|Epiphany|Shiira|Sunrise|Spotify|Flock|Netscape|Lunascape|WebPilot|NetFront|Netfront|Konqueror|SeaMonkey|Kazehakase|Vienna|Iceape|Iceweasel|IceWeasel|Iron|K-Meleon|Sleipnir|Galeon|GranParadiso|Opera Mini|iCab|NetNewsWire|ThunderBrowse|Iris|UP\\.Browser|Bunjalloo|Google Earth|Raven for Mac|Openwave|MacOutlook|Electron|OktaMobile)/(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('Microsoft Office Outlook 12\\.\\d+\\.\\d+|MSOffice 12', 'Outlook', '2007'),
    UserAgentParser('Microsoft Outlook 14\\.\\d+\\.\\d+|MSOffice 14', 'Outlook', '2010'),
    UserAgentParser('Microsoft Outlook 15\\.\\d+\\.\\d+', 'Outlook', '2013'),
    UserAgentParser('Microsoft Outlook (?:Mail )?16\\.\\d+\\.\\d+|MSOffice 16', 'Outlook', '2016'),
    UserAgentParser('Microsoft Office (Word) 2014'),
    UserAgentParser('Outlook-Express\\/7\\.0', 'Windows Live Mail'),
    UserAgentParser('(Airmail) (\\d+)\\.(\\d+)(?:\\.(\\d+)|)'),
    UserAgentParser('(Thunderbird)/(\\d+)\\.(\\d+)(?:\\.(\\d+(?:pre|))|)', 'Thunderbird'),
    UserAgentParser('(Postbox)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Postbox'),
    UserAgentParser('(Barca(?:Pro)?)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)', 'Barca'),
    UserAgentParser('(Lotus-Notes)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)', 'Lotus Notes'),
    UserAgentParser('Superhuman', 'Superhuman'),
    UserAgentParser('(Vivaldi)/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)'),
    UserAgentParser('.{0,200}(Teams)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Microsoft Teams'),
    UserAgentParser('(Edge?)/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)(?:\\.(\\d+)|)', 'Edge'),
    UserAgentParser('(Chrome)/(\\d+)\\.(\\d+)\\.(\\d+)[\\d.]{0,100} Iron[^/]', 'Iron'),
    UserAgentParser('\\b(Dolphin)(?: |HDCN/|/INT\\-)(\\d+)\\.(\\d+)(?:\\.(\\d+)|)'),
    UserAgentParser('(HeadlessChrome)(?:/(\\d+)\\.(\\d+)\\.(\\d+)|)'),
    UserAgentParser('(Evolution)/(\\d+)\\.(\\d+)\\.(\\d+\\.\\d+)'),
    UserAgentParser('(RCM CardDAV plugin)/(\\d+)\\.(\\d+)\\.(\\d+(?:-dev|))'),
    UserAgentParser('(bingbot|Bolt|AdobeAIR|Jasmine|IceCat|Skyfire|Midori|Maxthon|Lynx|Arora|IBrowse|Dillo|Camino|Shiira|Fennec|Phoenix|Flock|Netscape|Lunascape|Epiphany|WebPilot|Opera Mini|Opera|NetFront|Netfront|Konqueror|Googlebot|SeaMonkey|Kazehakase|Vienna|Iceape|Iceweasel|IceWeasel|Iron|K-Meleon|Sleipnir|Galeon|GranParadiso|iCab|iTunes|MacAppStore|NetNewsWire|Space Bison|Stainless|Orca|Dolfin|BOLT|Minimo|Tizen Browser|Polaris|Abrowser|Planetweb|ICE Browser|mDolphin|qutebrowser|Otter|QupZilla|MailBar|kmail2|YahooMobileMail|ExchangeWebServices|ExchangeServicesClient|Dragon|Outlook-iOS-Android)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)'),
    UserAgentParser('(QtWebEngine)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Qt Web Engine'),
    UserAgentParser('(OpenWave)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Open Wave'),
    UserAgentParser('(AtContent)/(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('(Trailer)/(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('(Agency)/(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('(Herring)/(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('(Config)/(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('(Viewer)/(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('(LikeWise)/(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('(Unique)/(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('(CitizenFX)/(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('(R2Client)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)'),
    UserAgentParser('(OBS)/(\\d+)\\.(\\d+)\\.(\\d+)', 'OBS Studio'),
    UserAgentParser('(AdobeCEP)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Adobe CEP'),
    UserAgentParser('Valve Steam (GameOverlay).{1,200}Chrome/(\\d+)\\.(\\d+)\\.(\\d+)', 'Steam GameOverlay'),
    UserAgentParser('Valve Steam (Gamepad)/Steam Deck.{1,200}Chrome/(\\d+)\\.(\\d+)\\.(\\d+)', 'Steam Deck'),
    UserAgentParser('(Valve(?: Steam|) Client).{1,200}Chrome/(\\d+)\\.(\\d+)\\.(\\d+)', 'Steam Client'),
    UserAgentParser('(Ladybird)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)'),
    UserAgentParser('(Chromium|Chrome)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)'),
    UserAgentParser('(IEMobile)[ /](\\d+)\\.(\\d+)', 'IE Mobile'),
    UserAgentParser('(BacaBerita App)\\/(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('^(bPod|Pocket Casts|Player FM)$'),
    UserAgentParser('^(AlexaMediaPlayer|VLC)/(\\d+)\\.(\\d+)\\.([^.\\s]+)'),
    UserAgentParser('^(AntennaPod|WMPlayer|Zune|Podkicker|Radio|ExoPlayerDemo|Overcast|PocketTunes|NSPlayer|okhttp|DoggCatcher|QuickNews|QuickTime|Peapod|Podcasts|GoldenPod|VLC|Spotify|Miro|MediaGo|Juice|iPodder|gPodder|Banshee)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)'),
    UserAgentParser('^(Peapod|Liferea)/([^.\\s]+)\\.([^.\\s]+|)\\.?([^.\\s]+|)'),
    UserAgentParser('^(bPod|Player FM) BMID/(\\S+)'),
    UserAgentParser('^(Podcast ?Addict)/v(\\d+) '),
    UserAgentParser('^(Podcast ?Addict) ', 'PodcastAddict'),
    UserAgentParser('(Replay) AV'),
    UserAgentParser('(VOX) Music Player'),
    UserAgentParser('(CITA) RSS Aggregator/(\\d+)\\.(\\d+)'),
    UserAgentParser('(Pocket Casts)$'),
    UserAgentParser('(Player FM)$'),
    UserAgentParser('(LG Player|Doppler|FancyMusic|MediaMonkey|Clementine) (\\d+)\\.(\\d+)\\.?([^.\\s]+|)\\.?([^.\\s]+|)'),
    UserAgentParser('(philpodder)/(\\d+)\\.(\\d+)\\.?([^.\\s]+|)\\.?([^.\\s]+|)'),
    UserAgentParser('(Player FM|Pocket Casts|DoggCatcher|Spotify|MediaMonkey|MediaGo|BashPodder)'),
    UserAgentParser('(QuickTime)\\.(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('(Kinoma)(\\d+)'),
    UserAgentParser('(Fancy) Cloud Music (\\d+)\\.(\\d+)', 'FancyMusic'),
    UserAgentParser('EspnDownloadManager', 'ESPN'),
    UserAgentParser('(ESPN) Radio (\\d+)\\.(\\d+)(?:\\.(\\d+)|) ?(?:rv:(\\d+)|) '),
    UserAgentParser('(podracer|jPodder) v ?(\\d+)\\.(\\d+)(?:\\.(\\d+)|)'),
    UserAgentParser('(ZDM)/(\\d+)\\.(\\d+)[; ]?'),
    UserAgentParser('(Zune|BeyondPod) (\\d+)(?:\\.(\\d+)|)[\\);]'),
    UserAgentParser('(WMPlayer)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('^(Lavf)', 'WMPlayer'),
    UserAgentParser('^(RSSRadio)[ /]?(\\d+|)'),
    UserAgentParser('(RSS_Radio) (\\d+)\\.(\\d+)', 'RSSRadio'),
    UserAgentParser('(Podkicker) \\S+/(\\d+)\\.(\\d+)\\.(\\d+)', 'Podkicker'),
    UserAgentParser('^(HTC) Streaming Player \\S+ / \\S+ / \\S+ / (\\d+)\\.(\\d+)(?:\\.(\\d+)|)'),
    UserAgentParser('^(Stitcher)/iOS'),
    UserAgentParser('^(Stitcher)/Android'),
    UserAgentParser('^(VLC) .{0,200}version (\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser(' (VLC) for'),
    UserAgentParser('(vlc)/(\\d+)\\.(\\d+)\\.(\\d+)', 'VLC'),
    UserAgentParser('^(foobar)\\S{1,10}/(\\d+)\\.(\\d+|)\\.?([\\da-z]+|)'),
    UserAgentParser('^(Clementine)\\S{1,10} (\\d+)\\.(\\d+|)\\.?(\\d+|)'),
    UserAgentParser('(amarok)/(\\d+)\\.(\\d+|)\\.?(\\d+|)', 'Amarok'),
    UserAgentParser('(Custom)-Feed Reader'),
    UserAgentParser('(iRider|Crazy Browser|SkipStone|iCab|Lunascape|Sleipnir|Maemo Browser) (\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('(iCab|Lunascape|Opera|Android|Jasmine|Polaris|Microsoft SkyDriveSync|The Bat!) (\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)'),
    UserAgentParser('(Kindle)/(\\d+)\\.(\\d+)'),
    UserAgentParser('(Android) Donut', None, '1', '2'),
    UserAgentParser('(Android) Eclair', None, '2', '1'),
    UserAgentParser('(Android) Froyo', None, '2', '2'),
    UserAgentParser('(Android) Gingerbread', None, '2', '3'),
    UserAgentParser('(Android) Honeycomb', None, '3'),
    UserAgentParser('(MSIE) (\\d+)\\.(\\d+).{0,100}XBLWP7', 'IE Large Screen'),
    UserAgentParser('(Nextcloud)'),
    UserAgentParser('(mirall)/(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('(ownCloud-android)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Owncloud'),
    UserAgentParser('(OC)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+) \\(Skype for Business\\)', 'Skype'),
    UserAgentParser('(OpenVAS)(?:-VT)?(?:[ \\/](\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)|)', 'OpenVAS Scanner'),
    UserAgentParser('(AnyConnect)\\/(\\d+)(?:\\.(\\d+)(?:\\.(\\d+)|)|)'),
    UserAgentParser('compatible; monitis', 'Monitis'),
    UserAgentParser('(Obigo)InternetBrowser'),
    UserAgentParser('(Obigo)\\-Browser'),
    UserAgentParser('(Obigo|OBIGO)[^\\d]*(\\d+)(?:.(\\d+)|)', 'Obigo'),
    UserAgentParser('(MAXTHON|Maxthon) (\\d+)\\.(\\d+)', 'Maxthon'),
    UserAgentParser('(Maxthon|MyIE2|Uzbl|Shiira)', None, '0'),
    UserAgentParser('(BrowseX) \\((\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('(NCSA_Mosaic)/(\\d+)\\.(\\d+)', 'NCSA Mosaic'),
    UserAgentParser('(POLARIS)/(\\d+)\\.(\\d+)', 'Polaris'),
    UserAgentParser('(Embider)/(\\d+)\\.(\\d+)', 'Polaris'),
    UserAgentParser('(BonEcho)/(\\d+)\\.(\\d+)\\.?([ab]?\\d+|)', 'Bon Echo'),
    UserAgentParser('(TopBuzz) com.alex.NewsMaster/(\\d+).(\\d+).(\\d+)', 'TopBuzz'),
    UserAgentParser('(TopBuzz) com.mobilesrepublic.newsrepublic/(\\d+).(\\d+).(\\d+)', 'TopBuzz'),
    UserAgentParser('(TopBuzz) com.topbuzz.videoen/(\\d+).(\\d+).(\\d+)', 'TopBuzz'),
    UserAgentParser('(iPod|iPhone|iPad).{1,200}GSA/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+)|) Mobile', 'Google'),
    UserAgentParser('(iPod|iPhone|iPad).{1,200}Version/(\\d+)\\.(\\d+)(?:\\.(\\d+)|).{1,200}[ +]Safari', 'Mobile Safari'),
    UserAgentParser('(iPod|iPod touch|iPhone|iPad);.{0,30}CPU.{0,30}OS[ +](\\d+)_(\\d+)(?:_(\\d+)|).{0,30} AppleNews\\/\\d+\\.\\d+(?:\\.\\d+|)', 'Mobile Safari UI/WKWebView'),
    UserAgentParser('(iPod|iPhone|iPad).{1,200}Version/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)', 'Mobile Safari UI/WKWebView'),
    UserAgentParser('(iPod|iPod touch|iPhone|iPad).{0,200} Safari', 'Mobile Safari'),
    UserAgentParser('(iPod|iPod touch|iPhone|iPad)', 'Mobile Safari UI/WKWebView'),
    UserAgentParser('(Watch)(\\d+),(\\d+)', 'Apple $1 App'),
    UserAgentParser('(Outlook-iOS)/\\d+\\.\\d+\\.prod\\.iphone \\((\\d+)\\.(\\d+)\\.(\\d+)\\)'),
    UserAgentParser('(AvantGo) (\\d+).(\\d+)'),
    UserAgentParser('(OneBrowser)/(\\d+).(\\d+)', 'ONE Browser'),
    UserAgentParser('(Avant)', None, '1'),
    UserAgentParser('(QtCarBrowser)', None, '1'),
    UserAgentParser('^(iBrowser/Mini)(\\d+).(\\d+)', 'iBrowser Mini'),
    UserAgentParser('^(iBrowser|iRAPP)/(\\d+).(\\d+)'),
    UserAgentParser('^(Nokia)', 'Nokia Services (WAP) Browser'),
    UserAgentParser('(NokiaBrowser)/(\\d+)\\.(\\d+).(\\d+)\\.(\\d+)', 'Nokia Browser'),
    UserAgentParser('(NokiaBrowser)/(\\d+)\\.(\\d+).(\\d+)', 'Nokia Browser'),
    UserAgentParser('(NokiaBrowser)/(\\d+)\\.(\\d+)', 'Nokia Browser'),
    UserAgentParser('(BrowserNG)/(\\d+)\\.(\\d+).(\\d+)', 'Nokia Browser'),
    UserAgentParser('(Series60)/5\\.0', 'Nokia Browser', '7', '0'),
    UserAgentParser('(Series60)/(\\d+)\\.(\\d+)', 'Nokia OSS Browser'),
    UserAgentParser('(S40OviBrowser)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)', 'Ovi Browser'),
    UserAgentParser('(Nokia)[EN]?(\\d+)'),
    UserAgentParser('(PlayBook).{1,200}RIM Tablet OS (\\d+)\\.(\\d+)\\.(\\d+)', 'BlackBerry WebKit'),
    UserAgentParser('(Black[bB]erry|BB10).{1,200}Version/(\\d+)\\.(\\d+)\\.(\\d+)', 'BlackBerry WebKit'),
    UserAgentParser('(Black[bB]erry)\\s?(\\d+)', 'BlackBerry'),
    UserAgentParser('(OmniWeb)/v(\\d+)\\.(\\d+)'),
    UserAgentParser('(Blazer)/(\\d+)\\.(\\d+)', 'Palm Blazer'),
    UserAgentParser('(Pre)/(\\d+)\\.(\\d+)', 'Palm Pre'),
    UserAgentParser('(ELinks)/(\\d+)\\.(\\d+)'),
    UserAgentParser('(ELinks) \\((\\d+)\\.(\\d+)'),
    UserAgentParser('(Links) \\((\\d+)\\.(\\d+)'),
    UserAgentParser('(QtWeb) Internet Browser/(\\d+)\\.(\\d+)'),
    UserAgentParser('(PhantomJS)/(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('(AppleWebKit)/(\\d+)(?:\\.(\\d+)|)\\+ .{0,200} Safari', 'WebKit Nightly'),
    UserAgentParser('(Version)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|).{0,100}Safari/', 'Safari'),
    UserAgentParser('(Safari)/\\d+'),
    UserAgentParser('(OLPC)/Update(\\d+)\\.(\\d+)'),
    UserAgentParser('(OLPC)/Update()\\.(\\d+)', None, '0'),
    UserAgentParser('(SEMC\\-Browser)/(\\d+)\\.(\\d+)'),
    UserAgentParser('(Teleca)', 'Teleca Browser'),
    UserAgentParser('(Phantom)/V(\\d+)\\.(\\d+)', 'Phantom Browser'),
    UserAgentParser('(Trident)/(7|8)\\.(0)', 'IE', '11'),
    UserAgentParser('(Trident)/(6)\\.(0)', 'IE', '10'),
    UserAgentParser('(Trident)/(5)\\.(0)', 'IE', '9'),
    UserAgentParser('(Trident)/(4)\\.(0)', 'IE', '8'),
    UserAgentParser('(Espial)/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)'),
    UserAgentParser('(AppleWebKit)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Apple Mail'),
    UserAgentParser('(Firefox)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|$)'),
    UserAgentParser('(Firefox)/(\\d+)\\.(\\d+)(pre|[ab]\\d+[a-z]*|)'),
    UserAgentParser('([MS]?IE) (\\d+)\\.(\\d+)', 'IE'),
    UserAgentParser('(python-requests)/(\\d+)\\.(\\d+)', 'Python Requests'),
    UserAgentParser('\\b(Windows-Update-Agent|WindowsPowerShell|Microsoft-CryptoAPI|SophosUpdateManager|SophosAgent|Debian APT-HTTP|Ubuntu APT-HTTP|libcurl-agent|libwww-perl|urlgrabber|curl|PycURL|Wget|wget2|aria2|Axel|OpenBSD ftp|lftp|jupdate|insomnia|fetch libfetch|akka-http|got|CloudCockpitBackend|ReactorNetty|axios|Jersey|Vert.x-WebClient|Apache-CXF|Go-CF-client|go-resty|AHC|HTTPie)(?:[ /](\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)|)'),
    UserAgentParser('^(cf)\\/(\\d+)\\.(\\d+)\\.(\\S+)', 'CloudFoundry'),
    UserAgentParser('^(sap-leonardo-iot-sdk-nodejs) \\/ (\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('^(SAP NetWeaver Application Server) \\(1.0;(\\d{1})(\\d{2})\\)'),
    UserAgentParser('^(\\w+-HTTPClient)\\/(\\d+)\\.(\\d+)-(\\S+)', 'HTTPClient'),
    UserAgentParser('^(go-cli)\\s(\\d+)\\.(\\d+).(\\S+)'),
    UserAgentParser('^(Java-EurekaClient|Java-EurekaClient-Replication|HTTPClient|lua-resty-http)\\/v?(\\d+)\\.(\\d+)\\.?(\\d*)'),
    UserAgentParser('^(ping-service|sap xsuaa|Node-oauth|Site24x7|SAP CPI|JAEGER_SECURITY)'),
    UserAgentParser('(Python/3\\.\\d{1,3} aiohttp)/(\\d+)\\.(\\d+)\\.(\\d+)', 'Python aiohttp'),
    UserAgentParser('(Java)[/ ]?\\d{1}\\.(\\d+)\\.(\\d+)[_-]*([a-zA-Z0-9]+|)'),
    UserAgentParser('(Java)[/ ]?(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('(minio-go)/v(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('^(ureq)[/ ](\\d+)\\.(\\d+).(\\d+)'),
    UserAgentParser('^(http\\.rb)/(\\d+)\\.(\\d+).(\\d+)'),
    UserAgentParser('^(GuzzleHttp)/(\\d+)\\.(\\d+).(\\d+)'),
    UserAgentParser('^(grab)\\b'),
    UserAgentParser('^(Cyberduck)/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.\\d+|)'),
    UserAgentParser('^(S3 Browser) (\\d+)[.-](\\d+)[.-](\\d+)(?:\\s*https?://s3browser\\.com|)'),
    UserAgentParser('(S3Gof3r)'),
    UserAgentParser('\\b(ibm-cos-sdk-(?:core|java|js|python))/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)'),
    UserAgentParser('^(rusoto)/(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('^(rclone)/v(\\d+)\\.(\\d+)'),
    UserAgentParser('^(Roku)/DVP-(\\d+)\\.(\\d+)'),
    UserAgentParser('(Kurio)\\/(\\d+)\\.(\\d+)\\.(\\d+)', 'Kurio App'),
    UserAgentParser('^(Box(?: Sync)?)/(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('^(ViaFree|Viafree)-(?:tvOS-)?[A-Z]{2}/(\\d+)\\.(\\d+)\\.(\\d+)', 'ViaFree'),
    UserAgentParser('(Transmit)/(\\d+)\\.(\\d+)\\.(\\d+)'),
    UserAgentParser('(Download Master)'),
    UserAgentParser('\\b(HTTrack) (\\d+)\\.(\\d+)(?:[\\.\\-](\\d+)|)'),
    UserAgentParser('(Ladybird)\\/(\\d+)\\.(\\d+)'),
    UserAgentParser('(MullvadBrowser)/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)'),
]

OS_PARSERS = [
    OSParser('HbbTV/\\d+\\.\\d+\\.\\d+ \\( ;(LG)E ;NetCast 4.0', None, '2013'),
    OSParser('HbbTV/\\d+\\.\\d+\\.\\d+ \\( ;(LG)E ;NetCast 3.0', None, '2012'),
    OSParser('HbbTV/1.1.1 \\(;;;;;\\) Maple_2011', 'Samsung', '2011'),
    OSParser('HbbTV/\\d+\\.\\d+\\.\\d+ \\(;(Samsung);SmartTV([0-9]{4});.{0,200}FXPDEUC', None, None, 'UE40F7000'),
    OSParser('HbbTV/\\d+\\.\\d+\\.\\d+ \\(;(Samsung);SmartTV([0-9]{4});.{0,200}MST12DEUC', None, None, 'UE32F4500'),
    OSParser('HbbTV/1\\.1\\.1 \\(; (Philips);.{0,200}NETTV/4', None, '2013'),
    OSParser('HbbTV/1\\.1\\.1 \\(; (Philips);.{0,200}NETTV/3', None, '2012'),
    OSParser('HbbTV/1\\.1\\.1 \\(; (Philips);.{0,200}NETTV/2', None, '2011'),
    OSParser('HbbTV/\\d+\\.\\d+\\.\\d+.{0,100}(firetv)-firefox-plugin (\\d+).(\\d+).(\\d+)', 'FireHbbTV'),
    OSParser('HbbTV/\\d+\\.\\d+\\.\\d+ \\(.{0,30}; ?([a-zA-Z]+) ?;.{0,30}(201[1-9]).{0,30}\\)'),
    OSParser('AspiegelBot|PetalBot', 'Other'),
    OSParser('(Windows Phone) (?:OS[ /])?(\\d+)\\.(\\d+)'),
    OSParser('(CPU[ +]OS|iPhone[ +]OS|CPU[ +]iPhone)[ +]+(\\d+)[_\\.](\\d+)(?:[_\\.](\\d+)|).{0,100}Outlook-iOS-Android', 'iOS'),
    OSParser('ArcGIS\\.?(iOS|Android)-\\d+\\.\\d+(?:\\.\\d+|)(?:[^\\/]{1,50}|)\\/(\\d+)(?:\\.(\\d+)(?:\\.(\\d+)|)|)'),
    OSParser('ArcGISRuntime-(?:Android|iOS)\\/\\d+\\.\\d+(?:\\.\\d+|) \\((Android|iOS) (\\d+)(?:\\.(\\d+)(?:\\.(\\d+)|)|);'),
    OSParser('(Android) (\\d+)(?:\\.(\\d+)).*CrKey', 'Chromecast Android'),
    OSParser('Fuchsia.*(CrKey)(?:[/](\\d+)\\.(\\d+)(?:\\.(\\d+)|)|)', 'Chromecast Fuchsia'),
    OSParser('Linux.*(CrKey)(?:[/](\\d+)\\.(\\d+)(?:\\.(\\d+)|)|).*DeviceType/SmartSpeaker', 'Chromecast SmartSpeaker'),
    OSParser('Linux.*(CrKey)(?:[/](\\d+)\\.(\\d+)(?:\\.(\\d+)|)|)', 'Chromecast Linux'),
    OSParser('(Android)[ \\-/](\\d+)(?:\\.(\\d+)|)(?:[.\\-]([a-z0-9]+)|)'),
    OSParser('(Android) Donut', None, '1', '2'),
    OSParser('(Android) Eclair', None, '2', '1'),
    OSParser('(Android) Froyo', None, '2', '2'),
    OSParser('(Android) Gingerbread', None, '2', '3'),
    OSParser('(Android) Honeycomb', None, '3'),
    OSParser('(Android) (\\d+);'),
    OSParser('(Android): (\\d+)(?:\\.(\\d+)(?:\\.(\\d+)|)|);'),
    OSParser('^UCWEB.{0,200}; (Adr) (\\d+)\\.(\\d+)(?:[.\\-]([a-z0-9]{1,100})|);', 'Android'),
    OSParser('^UCWEB.{0,200}; (iPad|iPh|iPd) OS (\\d+)_(\\d+)(?:_(\\d+)|);', 'iOS'),
    OSParser('^UCWEB.{0,200}; (wds) (\\d+)\\.(\\d+)(?:\\.(\\d+)|);', 'Windows Phone'),
    OSParser('^(JUC).{0,200}; ?U; ?(?:Android|)(\\d+)\\.(\\d+)(?:[\\.\\-]([a-z0-9]{1,100})|)', 'Android'),
    OSParser('(android)\\s(?:mobile\\/)(\\d+)(?:\\.(\\d+)(?:\\.(\\d+)|)|)', 'Android'),
    OSParser('Quest', 'Android'),
    OSParser('(Silk-Accelerated=[a-z]{4,5})', 'Android'),
    OSParser('(x86_64|aarch64)\\ (\\d+)\\.(\\d+)\\.(\\d+).{0,100}Chrome.{0,100}(?:CitrixChromeApp)$', 'Chrome OS'),
    OSParser('(XBLWP7)', 'Windows Phone'),
    OSParser('(Windows ?Mobile)', 'Windows Mobile'),
    OSParser('(Windows 10)', 'Windows', '10'),
    OSParser('(Windows (?:NT 5\\.2|NT 5\\.1))', 'Windows', 'XP'),
    OSParser('(Win(?:dows NT |32NT\\/)6\\.1)', 'Windows', '7'),
    OSParser('(Win(?:dows NT |32NT\\/)6\\.0)', 'Windows', 'Vista'),
    OSParser('(Win 9x 4\\.90)', 'Windows', 'ME'),
    OSParser('(Windows NT 6\\.2; ARM;)', 'Windows', 'RT'),
    OSParser('(Win(?:dows NT |32NT\\/)6\\.2)', 'Windows', '8'),
    OSParser('(Windows NT 6\\.3; ARM;)', 'Windows', 'RT 8', '1'),
    OSParser('(Win(?:dows NT |32NT\\/)6\\.3)', 'Windows', '8', '1'),
    OSParser('(Win(?:dows NT |32NT\\/)6\\.4)', 'Windows', '10'),
    OSParser('(Windows NT 10\\.0)', 'Windows', '10'),
    OSParser('(Windows NT 5\\.0)', 'Windows', '2000'),
    OSParser('(WinNT4.0)', 'Windows', 'NT 4.0'),
    OSParser('(Windows ?CE)', 'Windows', 'CE'),
    OSParser('Win(?:dows)? ?(95|98|3.1|NT|ME|2000|XP|Vista|7|CE)', 'Windows', '$1'),
    OSParser('Win16', 'Windows', '3.1'),
    OSParser('Win32', 'Windows', '95'),
    OSParser('^Box.{0,200}Windows/([\\d.]+);', 'Windows', '$1'),
    OSParser('(Tizen)[/ ](\\d+)\\.(\\d+)'),
    OSParser('Intel Mac OS X.+(CriOS|EdgiOS)/\\d+', 'iOS'),
    OSParser('((?:Mac[ +]?|; )OS[ +]X)[\\s+/](?:(\\d+)[_.](\\d+)(?:[_.](\\d+)|)|Mach-O)', 'Mac OS X'),
    OSParser('Mac OS X\\s.{1,50}\\s(\\d+).(\\d+).(\\d+)', 'Mac OS X', '$1', '$2', '$3'),
    OSParser(' (Dar)(win)/(9).(\\d+).{0,100}\\((?:i386|x86_64|Power Macintosh)\\)', 'Mac OS X', '10', '5'),
    OSParser(' (Dar)(win)/(10).(\\d+).{0,100}\\((?:i386|x86_64)\\)', 'Mac OS X', '10', '6'),
    OSParser(' (Dar)(win)/(11).(\\d+).{0,100}\\((?:i386|x86_64)\\)', 'Mac OS X', '10', '7'),
    OSParser(' (Dar)(win)/(12).(\\d+).{0,100}\\((?:i386|x86_64)\\)', 'Mac OS X', '10', '8'),
    OSParser(' (Dar)(win)/(13).(\\d+).{0,100}\\((?:i386|x86_64)\\)', 'Mac OS X', '10', '9'),
    OSParser('Mac_PowerPC', 'Mac OS'),
    OSParser('(?:PPC|Intel) (Mac OS X)'),
    OSParser('^Box.{0,200};(Darwin)/(10)\\.(1\\d)(?:\\.(\\d+)|)', 'Mac OS X'),
    OSParser('darwin; arm64', 'Mac OS X'),
    OSParser('(Apple\\s?TV)(?:/(\\d+)\\.(\\d+)|)', 'ATV OS X'),
    OSParser('(CPU[ +]OS|iPhone[ +]OS|CPU[ +]iPhone|CPU IPhone OS|CPU iPad OS)[ +]+(\\d+)[_\\.](\\d+)(?:[_\\.](\\d+)|)', 'iOS'),
    OSParser('(iPhone|iPad|iPod); Opera', 'iOS'),
    OSParser('(iPhone|iPad|iPod).{0,100}Mac OS X.{0,100}Version/(\\d+)\\.(\\d+)', 'iOS'),
    OSParser('(CFNetwork)/(5)48\\.0\\.3.{0,100} Darwin/11\\.0\\.0', 'iOS'),
    OSParser('(CFNetwork)/(5)48\\.(0)\\.4.{0,100} Darwin/(1)1\\.0\\.0', 'iOS'),
    OSParser('(CFNetwork)/(5)48\\.(1)\\.4', 'iOS'),
    OSParser('(CFNetwork)/(4)85\\.1(3)\\.9', 'iOS'),
    OSParser('(CFNetwork)/(6)09\\.(1)\\.4', 'iOS'),
    OSParser('(CFNetwork)/(6)(0)9', 'iOS'),
    OSParser('(CFNetwork)/6(7)2\\.(1)\\.13', 'iOS'),
    OSParser('(CFNetwork)/6(7)2\\.(1)\\.(1)4', 'iOS'),
    OSParser('(CF)(Network)/6(7)(2)\\.1\\.15', 'iOS', '7', '1'),
    OSParser('(CFNetwork)/6(7)2\\.(0)\\.(?:2|8)', 'iOS'),
    OSParser('(CFNetwork)/709\\.1', 'iOS', '8', '0.b5'),
    OSParser('(CF)(Network)/711\\.(\\d)', 'iOS', '8'),
    OSParser('(CF)(Network)/(720)\\.(\\d)', 'Mac OS X', '10', '10'),
    OSParser('(CF)(Network)/(760)\\.(\\d)', 'Mac OS X', '10', '11'),
    OSParser('CFNetwork/7.{0,100} Darwin/15\\.4\\.\\d+', 'iOS', '9', '3', '1'),
    OSParser('CFNetwork/7.{0,100} Darwin/15\\.5\\.\\d+', 'iOS', '9', '3', '2'),
    OSParser('CFNetwork/7.{0,100} Darwin/15\\.6\\.\\d+', 'iOS', '9', '3', '5'),
    OSParser('(CF)(Network)/758\\.(\\d)', 'iOS', '9'),
    OSParser('CFNetwork/808\\.3 Darwin/16\\.3\\.\\d+', 'iOS', '10', '2', '1'),
    OSParser('(CF)(Network)/808\\.(\\d)', 'iOS', '10'),
    OSParser('CFNetwork/.{0,100} Darwin/17\\.\\d+.{0,100}\\(x86_64\\)', 'Mac OS X', '10', '13'),
    OSParser('CFNetwork/.{0,100} Darwin/16\\.\\d+.{0,100}\\(x86_64\\)', 'Mac OS X', '10', '12'),
    OSParser('CFNetwork/8.{0,100} Darwin/15\\.\\d+.{0,100}\\(x86_64\\)', 'Mac OS X', '10', '11'),
    OSParser('CFNetwork/.{0,100} Darwin/(9)\\.\\d+', 'iOS', '1'),
    OSParser('CFNetwork/.{0,100} Darwin/(10)\\.\\d+', 'iOS', '4'),
    OSParser('CFNetwork/.{0,100} Darwin/(11)\\.\\d+', 'iOS', '5'),
    OSParser('CFNetwork/.{0,100} Darwin/(13)\\.\\d+', 'iOS', '6'),
    OSParser('CFNetwork/6.{0,100} Darwin/(14)\\.\\d+', 'iOS', '7'),
    OSParser('CFNetwork/7.{0,100} Darwin/(14)\\.\\d+', 'iOS', '8', '0'),
    OSParser('CFNetwork/7.{0,100} Darwin/(15)\\.\\d+', 'iOS', '9', '0'),
    OSParser('CFNetwork/8.{0,100} Darwin/16\\.5\\.\\d+', 'iOS', '10', '3'),
    OSParser('CFNetwork/8.{0,100} Darwin/16\\.6\\.\\d+', 'iOS', '10', '3', '2'),
    OSParser('CFNetwork/8.{0,100} Darwin/16\\.7\\.\\d+', 'iOS', '10', '3', '3'),
    OSParser('CFNetwork/8.{0,100} Darwin/(16)\\.\\d+', 'iOS', '10'),
    OSParser('CFNetwork/8.{0,100} Darwin/17\\.0\\.\\d+', 'iOS', '11', '0'),
    OSParser('CFNetwork/8.{0,100} Darwin/17\\.2\\.\\d+', 'iOS', '11', '1'),
    OSParser('CFNetwork/8.{0,100} Darwin/17\\.3\\.\\d+', 'iOS', '11', '2'),
    OSParser('CFNetwork/8.{0,100} Darwin/17\\.4\\.\\d+', 'iOS', '11', '2', '6'),
    OSParser('CFNetwork/8.{0,100} Darwin/17\\.5\\.\\d+', 'iOS', '11', '3'),
    OSParser('CFNetwork/9.{0,100} Darwin/17\\.6\\.\\d+', 'iOS', '11', '4'),
    OSParser('CFNetwork/9.{0,100} Darwin/17\\.7\\.\\d+', 'iOS', '11', '4', '1'),
    OSParser('CFNetwork/8.{0,100} Darwin/(17)\\.\\d+', 'iOS', '11'),
    OSParser('CFNetwork/9.{0,100} Darwin/18\\.0\\.\\d+', 'iOS', '12', '0'),
    OSParser('CFNetwork/9.{0,100} Darwin/18\\.2\\.\\d+', 'iOS', '12', '1'),
    OSParser('CFNetwork/9.{0,100} Darwin/18\\.5\\.\\d+', 'iOS', '12', '2'),
    OSParser('CFNetwork/9.{0,100} Darwin/18\\.6\\.\\d+', 'iOS', '12', '3'),
    OSParser('CFNetwork/9.{0,100} Darwin/18\\.7\\.\\d+', 'iOS', '12', '4'),
    OSParser('CFNetwork/9.{0,100} Darwin/(18)\\.\\d+', 'iOS', '12'),
    OSParser('CFNetwork/11.{0,100} Darwin/19\\.2\\.\\d+', 'iOS', '13', '3'),
    OSParser('CFNetwork/11.{0,100} Darwin/19\\.3\\.\\d+', 'iOS', '13', '3', '1'),
    OSParser('CFNetwork/11.{0,100} Darwin/19\\.4\\.\\d+', 'iOS', '13', '4'),
    OSParser('CFNetwork/11.{0,100} Darwin/19\\.5\\.\\d+', 'iOS', '13', '5'),
    OSParser('CFNetwork/11.{0,100} Darwin/19\\.6\\.\\d+', 'iOS', '13', '6'),
    OSParser('CFNetwork/1[01].{0,100} Darwin/19\\.\\d+', 'iOS', '13'),
    OSParser('CFNetwork/12.{0,100} Darwin/20\\.1\\.\\d+', 'iOS', '14', '2'),
    OSParser('CFNetwork/12.{0,100} Darwin/20\\.2\\.\\d+', 'iOS', '14', '3'),
    OSParser('CFNetwork/12.{0,100} Darwin/20\\.3\\.\\d+', 'iOS', '14', '4'),
    OSParser('CFNetwork/12.{0,100} Darwin/20\\.4\\.\\d+', 'iOS', '14', '5'),
    OSParser('CFNetwork/12.{0,100} Darwin/20\\.5\\.\\d+', 'iOS', '14', '6'),
    OSParser('CFNetwork/12.{0,100} Darwin/20\\.6\\.\\d+', 'iOS', '14', '8'),
    OSParser('CFNetwork/.{0,100} Darwin/(20)\\.\\d+', 'iOS', '14'),
    OSParser('CFNetwork/13.{0,100} Darwin/21\\.0\\.\\d+', 'iOS', '15', '0'),
    OSParser('CFNetwork/13.{0,100} Darwin/21\\.1\\.\\d+', 'iOS', '15', '1'),
    OSParser('CFNetwork/13.{0,100} Darwin/21\\.2\\.\\d+', 'iOS', '15', '2'),
    OSParser('CFNetwork/13.{0,100} Darwin/21\\.3\\.\\d+', 'iOS', '15', '3'),
    OSParser('CFNetwork/13.{0,100} Darwin/21\\.4\\.\\d+', 'iOS', '15', '4'),
    OSParser('CFNetwork/13.{0,100} Darwin/21\\.5\\.\\d+', 'iOS', '15', '5'),
    OSParser('CFNetwork/13.{0,100} Darwin/21\\.6\\.\\d+', 'iOS', '15', '6'),
    OSParser('CFNetwork/.{0,100} Darwin/(21)\\.\\d+', 'iOS', '15'),
    OSParser('CFNetwork/.{0,100} Darwin/22\\.([0-5])\\.\\d+', 'iOS', '16', '$1'),
    OSParser('CFNetwork/.{0,100} Darwin/(22)\\.\\d+', 'iOS', '16'),
    OSParser('CFNetwork/.{0,100} Darwin/23\\.([0-5])\\.\\d+', 'iOS', '17', '$1'),
    OSParser('CFNetwork/.{0,100} Darwin/(23)\\.\\d+', 'iOS', '17'),
    OSParser('CFNetwork/.{0,100} Darwin/24\\.([0-5])\\.\\d+', 'iOS', '18', '$1'),
    OSParser('CFNetwork/.{0,100} Darwin/(24)\\.\\d+', 'iOS', '18'),
    OSParser('CFNetwork/.{0,100} Darwin/', 'iOS'),
    OSParser('\\b(iOS[ /]|iOS; |iPhone(?:/| v|[ _]OS[/,]|; | OS : |\\d,\\d/|\\d,\\d; )|iPad/)(\\d{1,2})[_\\.](\\d{1,2})(?:[_\\.](\\d+)|)', 'iOS'),
    OSParser('\\((iOS);'),
    OSParser('(watchOS)[/ ](\\d+)\\.(\\d+)(?:\\.(\\d+)|)', 'WatchOS'),
    OSParser('Outlook-(iOS)/\\d+\\.\\d+\\.prod\\.iphone'),
    OSParser('(iPod|iPhone|iPad)', 'iOS'),
    OSParser('(tvOS)[/ ](\\d+)\\.(\\d+)(?:\\.(\\d+)|)', 'tvOS'),
    OSParser('(CrOS) [a-z0-9_]+ (\\d+)\\.(\\d+)(?:\\.(\\d+)|)', 'Chrome OS'),
    OSParser('([Dd]ebian)', 'Debian'),
    OSParser('(Linux Mint)(?:/(\\d+)|)'),
    OSParser('(Mandriva)(?: Linux|)/(?:[\\d.-]+m[a-z]{2}(\\d+).(\\d)|)'),
    OSParser('(Symbian[Oo][Ss])[/ ](\\d+)\\.(\\d+)', 'Symbian OS'),
    OSParser('(Symbian/3).{1,200}NokiaBrowser/7\\.3', 'Symbian^3 Anna'),
    OSParser('(Symbian/3).{1,200}NokiaBrowser/7\\.4', 'Symbian^3 Belle'),
    OSParser('(Symbian/3)', 'Symbian^3'),
    OSParser('\\b(Series 60|SymbOS|S60Version|S60V\\d|S60\\b)', 'Symbian OS'),
    OSParser('(MeeGo)'),
    OSParser('Symbian [Oo][Ss]', 'Symbian OS'),
    OSParser('Series40;', 'Nokia Series 40'),
    OSParser('Series30Plus;', 'Nokia Series 30 Plus'),
    OSParser('(BB10);.{1,200}Version/(\\d+)\\.(\\d+)\\.(\\d+)', 'BlackBerry OS'),
    OSParser('(Black[Bb]erry)[0-9a-z]+/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+)|)', 'BlackBerry OS'),
    OSParser('(Black[Bb]erry).{1,200}Version/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+)|)', 'BlackBerry OS'),
    OSParser('(RIM Tablet OS) (\\d+)\\.(\\d+)\\.(\\d+)', 'BlackBerry Tablet OS'),
    OSParser('(Play[Bb]ook)', 'BlackBerry Tablet OS'),
    OSParser('(Black[Bb]erry)', 'BlackBerry OS'),
    OSParser('(K[Aa][Ii]OS)\\/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)', 'KaiOS'),
    OSParser('\\((?:Mobile|Tablet);.{1,200}Gecko/18.0 Firefox/\\d+\\.\\d+', 'Firefox OS', '1', '0', '1'),
    OSParser('\\((?:Mobile|Tablet);.{1,200}Gecko/18.1 Firefox/\\d+\\.\\d+', 'Firefox OS', '1', '1'),
    OSParser('\\((?:Mobile|Tablet);.{1,200}Gecko/26.0 Firefox/\\d+\\.\\d+', 'Firefox OS', '1', '2'),
    OSParser('\\((?:Mobile|Tablet);.{1,200}Gecko/28.0 Firefox/\\d+\\.\\d+', 'Firefox OS', '1', '3'),
    OSParser('\\((?:Mobile|Tablet);.{1,200}Gecko/30.0 Firefox/\\d+\\.\\d+', 'Firefox OS', '1', '4'),
    OSParser('\\((?:Mobile|Tablet);.{1,200}Gecko/32.0 Firefox/\\d+\\.\\d+', 'Firefox OS', '2', '0'),
    OSParser('\\((?:Mobile|Tablet);.{1,200}Gecko/34.0 Firefox/\\d+\\.\\d+', 'Firefox OS', '2', '1'),
    OSParser('\\((?:Mobile|Tablet);.{1,200}Firefox/\\d+\\.\\d+', 'Firefox OS'),
    OSParser('(BREW)[ /](\\d+)\\.(\\d+)\\.(\\d+)'),
    OSParser('(BREW);'),
    OSParser('(Brew MP|BMP)[ /](\\d+)\\.(\\d+)\\.(\\d+)', 'Brew MP'),
    OSParser('BMP;', 'Brew MP'),
    OSParser('(GoogleTV)(?: (\\d+)\\.(\\d+)(?:\\.(\\d+)|)|/[\\da-z]+)'),
    OSParser('(WebTV)/(\\d+).(\\d+)'),
    OSParser('(hpw|web)OS/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)', 'webOS'),
    OSParser('(VRE);'),
    OSParser('(Fedora|Red Hat|PCLinuxOS|Puppy|Ubuntu|Kindle|Bada|Sailfish|Lubuntu|BackTrack|Slackware|(?:Free|Open|Net|\\b)BSD)[/ ](\\d+)\\.(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)'),
    OSParser('(Linux)[ /](\\d+)\\.(\\d+)(?:\\.(\\d+)|).{0,100}gentoo', 'Gentoo'),
    OSParser('\\((Bada);'),
    OSParser('(Windows|Android|WeTab|Maemo|Web0S)'),
    OSParser('(Ubuntu|Kubuntu|Arch Linux|CentOS|Slackware|Gentoo|openSUSE|SUSE|Red Hat|Fedora|PCLinuxOS|Mageia|SerenityOS|(?:Free|Open|Net|\\b)BSD)'),
    OSParser('(Linux)(?:[ /](\\d+)\\.(\\d+)(?:\\.(\\d+)|)|)'),
    OSParser('SunOS', 'Solaris'),
    OSParser('\\(linux-gnu\\)', 'Linux'),
    OSParser('\\(x86_64-redhat-linux-gnu\\)', 'Red Hat'),
    OSParser('\\((freebsd)(\\d+)\\.(\\d+)\\)', 'FreeBSD'),
    OSParser('linux', 'Linux'),
    OSParser('^(Roku)/DVP-(\\d+)\\.(\\d+)'),
    OSParser('os\\/macos[#]?(\\d*)[.]?(\\d*)[.]?(\\d*)', 'Mac OS X', '$1', '$2', '$3'),
    OSParser('(HarmonyOS)[\\s;]+(\\d+|)\\.?(\\d+|)\\.?(\\d+|)'),
]

DEVICE_PARSERS = [
    DeviceParser('^.{0,100}?(?:(?:iPhone|Windows CE|Windows Phone|Android).{0,300}(?:(?:Bot|Yeti)-Mobile|YRSpider|BingPreview|bots?/\\d|(?:bot|spider)\\.html|Google-InspectionTool)|AdsBot-Google-Mobile.{0,200}iPhone)', 'i', 'Spider', 'Spider', 'Smartphone'),
    DeviceParser('^.{0,100}?(?:DoCoMo|\\bMOT\\b|\\bLG\\b|Nokia|Samsung|SonyEricsson).{0,200}(?:(?:Bot|Yeti)-Mobile|bots?/\\d|(?:bot|crawler)\\.html|(?:jump|google|Wukong)bot|ichiro/mobile|/spider|YahooSeeker)', 'i', 'Spider', 'Spider', 'Feature Phone'),
    DeviceParser(' PTST/\\d+(?:\\.\\d+|)$', None, 'Spider', 'Spider'),
    DeviceParser('X11; Datanyze; Linux', None, 'Spider', 'Spider'),
    DeviceParser('Mozilla.{1,100}Mobile.{1,100}(AspiegelBot|PetalBot)', None, 'Spider', 'Spider', 'Smartphone'),
    DeviceParser('Mozilla.{0,200}(AspiegelBot|PetalBot)', None, 'Spider', 'Spider', 'Desktop'),
    DeviceParser('\\bSmartWatch {0,2}\\( {0,2}([^;]{1,200}) {0,2}; {0,2}([^;]{1,200}) {0,2};', None, '$1 $2', '$1', '$2'),
    DeviceParser('Android Application[^\\-]{1,300} - (Sony) ?(Ericsson|) (.{1,200}) \\w{1,20} - ', None, '$1 $2', '$1$2', '$3'),
    DeviceParser('Android Application[^\\-]{1,300} - (?:HTC|HUAWEI|LGE|LENOVO|MEDION|TCT) (HTC|HUAWEI|LG|LENOVO|MEDION|ALCATEL)[ _\\-](.{1,200}) \\w{1,20} - ', 'i', '$1 $2', '$1', '$2'),
    DeviceParser('Android Application[^\\-]{1,300} - ([^ ]+) (.{1,200}) \\w{1,20} - ', None, '$1 $2', '$1', '$2'),
    DeviceParser('; {0,2}([BLRQ]C\\d{4}[A-Z]{1,100}?)(?: Build|\\) AppleWebKit)', None, '3Q $1', '3Q', '$1'),
    DeviceParser('; {0,2}(?:3Q_)([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '3Q $1', '3Q', '$1'),
    DeviceParser('Android [34].{0,200}; {0,2}(A100|A101|A110|A200|A210|A211|A500|A501|A510|A511|A700(?: Lite| 3G|)|A701|B1-A71|A1-\\d{3}|B1-\\d{3}|V360|V370|W500|W500P|W501|W501P|W510|W511|W700|Slider SL101|DA22[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Acer', '$1'),
    DeviceParser('; {0,2}Acer Iconia Tab ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Acer', '$1'),
    DeviceParser('; {0,2}(Z1[1235]0|E320[^/]{0,10}|S500|S510|Liquid[^;/]{0,30}|Iconia A\\d+)(?: Build|\\) AppleWebKit)', None, '$1', 'Acer', '$1'),
    DeviceParser('; {0,2}(Acer |ACER )([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1$2', 'Acer', '$2'),
    DeviceParser('; {0,2}(Advent |)(Vega(?:Bean|Comb|)).{0,200}?(?: Build|\\) AppleWebKit)', None, '$1$2', 'Advent', '$2'),
    DeviceParser('; {0,2}(Ainol |)((?:NOVO|[Nn]ovo)[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1$2', 'Ainol', '$2'),
    DeviceParser('; {0,2}AIRIS[ _\\-]?([^/;\\)]+) {0,2}(?:;|\\)|Build)', 'i', '$1', 'Airis', '$1'),
    DeviceParser('; {0,2}(OnePAD[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', 'i', '$1', 'Airis', '$1'),
    DeviceParser('; {0,2}Airpad[ \\-]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, 'Airpad $1', 'Airpad', '$1'),
    DeviceParser('; {0,2}(one ?touch) (EVO7|T10|T20)(?: Build|\\) AppleWebKit)', None, 'Alcatel One Touch $2', 'Alcatel', 'One Touch $2'),
    DeviceParser('; {0,2}(?:alcatel[ _]|)(?:(?:one[ _]?touch[ _])|ot[ \\-])([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', 'i', 'Alcatel One Touch $1', 'Alcatel', 'One Touch $1'),
    DeviceParser('; {0,2}(TCL)[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1 $2', '$1', '$2'),
    DeviceParser('; {0,2}(Vodafone Smart II|Optimus_Madrid)(?: Build|\\) AppleWebKit)', None, 'Alcatel $1', 'Alcatel', '$1'),
    DeviceParser('; {0,2}BASE_Lutea_3(?: Build|\\) AppleWebKit)', None, 'Alcatel One Touch 998', 'Alcatel', 'One Touch 998'),
    DeviceParser('; {0,2}BASE_Varia(?: Build|\\) AppleWebKit)', None, 'Alcatel One Touch 918D', 'Alcatel', 'One Touch 918D'),
    DeviceParser('; {0,2}((?:FINE|Fine)\\d[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Allfine', '$1'),
    DeviceParser('; {0,2}(ALLVIEW[ _]?|Allview[ _]?)((?:Speed|SPEED).{0,200}?)(?: Build|\\) AppleWebKit)', None, '$1$2', 'Allview', '$2'),
    DeviceParser('; {0,2}(ALLVIEW[ _]?|Allview[ _]?|)(AX1_Shine|AX2_Frenzy)(?: Build|\\) AppleWebKit)', None, '$1$2', 'Allview', '$2'),
    DeviceParser('; {0,2}(ALLVIEW[ _]?|Allview[ _]?)([^;/]*?)(?: Build|\\) AppleWebKit)', None, '$1$2', 'Allview', '$2'),
    DeviceParser('; {0,2}(A13-MID)(?: Build|\\) AppleWebKit)', None, '$1', 'Allwinner', '$1'),
    DeviceParser('; {0,2}(Allwinner)[ _\\-]?([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1 $2', 'Allwinner', '$1'),
    DeviceParser('; {0,2}(A651|A701B?|A702|A703|A705|A706|A707|A711|A712|A713|A717|A722|A785|A801|A802|A803|A901|A902|A1002|A1003|A1006|A1007|A9701|A9703|Q710|Q80)(?: Build|\\) AppleWebKit)', None, '$1', 'Amaway', '$1'),
    DeviceParser('; {0,2}(?:AMOI|Amoi)[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, 'Amoi $1', 'Amoi', '$1'),
    DeviceParser('^(?:AMOI|Amoi)[ _]([^;/]{1,100}?) Linux', None, 'Amoi $1', 'Amoi', '$1'),
    DeviceParser('; {0,2}(MW(?:0[789]|10)[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Aoc', '$1'),
    DeviceParser('; {0,2}(G7|M1013|M1015G|M11[CG]?|M-?12[B]?|M15|M19[G]?|M30[ACQ]?|M31[GQ]|M32|M33[GQ]|M36|M37|M38|M701T|M710|M712B|M713|M715G|M716G|M71(?:G|GS|T|)|M72[T]?|M73[T]?|M75[GT]?|M77G|M79T|M7L|M7LN|M81|M810|M81T|M82|M92|M92KS|M92S|M717G|M721|M722G|M723|M725G|M739|M785|M791|M92SK|M93D)(?: Build|\\) AppleWebKit)', None, 'Aoson $1', 'Aoson', '$1'),
    DeviceParser('; {0,2}Aoson ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', 'i', 'Aoson $1', 'Aoson', '$1'),
    DeviceParser('; {0,2}[Aa]panda[ _\\-]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, 'Apanda $1', 'Apanda', '$1'),
    DeviceParser('; {0,2}(?:ARCHOS|Archos) ?(GAMEPAD.{0,200}?)(?: Build|\\) AppleWebKit)', None, 'Archos $1', 'Archos', '$1'),
    DeviceParser('ARCHOS; GOGI; ([^;]{1,200});', None, 'Archos $1', 'Archos', '$1'),
    DeviceParser('(?:ARCHOS|Archos)[ _]?(.{0,200}?)(?: Build|[;/\\(\\)\\-]|$)', None, 'Archos $1', 'Archos', '$1'),
    DeviceParser('; {0,2}(AN(?:7|8|9|10|13)[A-Z0-9]{1,4})(?: Build|\\) AppleWebKit)', None, 'Archos $1', 'Archos', '$1'),
    DeviceParser('; {0,2}(A28|A32|A43|A70(?:BHT|CHT|HB|S|X)|A101(?:B|C|IT)|A7EB|A7EB-WK|101G9|80G9)(?: Build|\\) AppleWebKit)', None, 'Archos $1', 'Archos', '$1'),
    DeviceParser('; {0,2}(PAD-FMD[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Arival', '$1'),
    DeviceParser('; {0,2}(BioniQ) ?([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1 $2', 'Arival', '$1 $2'),
    DeviceParser('; {0,2}(AN\\d[^;/]{1,100}|ARCHM\\d+)(?: Build|\\) AppleWebKit)', None, 'Arnova $1', 'Arnova', '$1'),
    DeviceParser('; {0,2}(?:ARNOVA|Arnova) ?([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, 'Arnova $1', 'Arnova', '$1'),
    DeviceParser('; {0,2}(?:ASSISTANT |)(AP)-?([1789]\\d{2}[A-Z]{0,2}|80104)(?: Build|\\) AppleWebKit)', None, 'Assistant $1-$2', 'Assistant', '$1-$2'),
    DeviceParser('; {0,2}(ME17\\d[^;/]*|ME3\\d{2}[^;/]{1,100}|K00[A-Z]|Nexus 10|Nexus 7(?: 2013|)|PadFone[^;/]*|Transformer[^;/]*|TF\\d{3}[^;/]*|eeepc)(?: Build|\\) AppleWebKit)', None, 'Asus $1', 'Asus', '$1'),
    DeviceParser('; {0,2}ASUS[ _]{0,10}([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, 'Asus $1', 'Asus', '$1'),
    DeviceParser('; {0,2}Garmin-Asus ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, 'Garmin-Asus $1', 'Garmin-Asus', '$1'),
    DeviceParser('; {0,2}(Garminfone)(?: Build|\\) AppleWebKit)', None, 'Garmin $1', 'Garmin-Asus', '$1'),
    DeviceParser('; (@TAB-[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Attab', '$1'),
    DeviceParser('; {0,2}(T-(?:07|[^0]\\d)[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Audiosonic', '$1'),
    DeviceParser('; {0,2}(?:Axioo[ _\\-]([^;/]{1,100}?)|(picopad)[ _\\-]([^;/]{1,100}?))(?: Build|\\) AppleWebKit)', 'i', 'Axioo $1$2 $3', 'Axioo', '$1$2 $3'),
    DeviceParser('; {0,2}(V(?:100|700|800)[^;/]*)(?: Build|\\) AppleWebKit)', None, '$1', 'Azend', '$1'),
    DeviceParser('; {0,2}(IBAK\\-[^;/]*)(?: Build|\\) AppleWebKit)', 'i', '$1', 'Bak', '$1'),
    DeviceParser('; {0,2}(HY5001|HY6501|X12|X21|I5)(?: Build|\\) AppleWebKit)', None, 'Bedove $1', 'Bedove', '$1'),
    DeviceParser('; {0,2}(JC-[^;/]*)(?: Build|\\) AppleWebKit)', None, 'Benss $1', 'Benss', '$1'),
    DeviceParser('; {0,2}(BB) ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1 $2', 'Blackberry', '$2'),
    DeviceParser('; {0,2}(BlackBird)[ _](I8.{0,200}?)(?: Build|\\) AppleWebKit)', None, '$1 $2', '$1', '$2'),
    DeviceParser('; {0,2}(BlackBird)[ _](.{0,200}?)(?: Build|\\) AppleWebKit)', None, '$1 $2', '$1', '$2'),
    DeviceParser('; {0,2}([0-9]+BP[EM][^;/]*|Endeavour[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, 'Blaupunkt $1', 'Blaupunkt', '$1'),
    DeviceParser('; {0,2}((?:BLU|Blu)[ _\\-])([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1$2', 'Blu', '$2'),
    DeviceParser('; {0,2}(?:BMOBILE )?(Blu|BLU|DASH [^;/]{1,100}|VIVO 4\\.3|TANK 4\\.5)(?: Build|\\) AppleWebKit)', None, '$1', 'Blu', '$1'),
    DeviceParser('; {0,2}(TOUCH\\d[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Blusens', '$1'),
    DeviceParser('; {0,2}(AX5\\d+)(?: Build|\\) AppleWebKit)', None, '$1', 'Bmobile', '$1'),
    DeviceParser('; {0,2}([Bb]q) ([^;/]{1,100}?);?(?: Build|\\) AppleWebKit)', None, '$1 $2', 'bq', '$2'),
    DeviceParser('; {0,2}(Maxwell [^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'bq', '$1'),
    DeviceParser('; {0,2}((?:B-Tab|B-TAB) ?\\d[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Braun', '$1'),
    DeviceParser('; {0,2}(Broncho) ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1 $2', '$1', '$2'),
    DeviceParser('; {0,2}CAPTIVA ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, 'Captiva $1', 'Captiva', '$1'),
    DeviceParser('; {0,2}(C771|CAL21|IS11CA)(?: Build|\\) AppleWebKit)', None, '$1', 'Casio', '$1'),
    DeviceParser('; {0,2}(?:Cat|CAT) ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, 'Cat $1', 'Cat', '$1'),
    DeviceParser('; {0,2}(?:Cat)(Nova.{0,200}?)(?: Build|\\) AppleWebKit)', None, 'Cat $1', 'Cat', '$1'),
    DeviceParser('; {0,2}(INM8002KP|ADM8000KP_[AB])(?: Build|\\) AppleWebKit)', None, '$1', 'Cat', 'Tablet PHOENIX 8.1J0'),
    DeviceParser('; {0,2}(?:[Cc]elkon[ _\\*]|CELKON[ _\\*])([^;/\\)]+) ?(?:Build|;|\\))', None, '$1', 'Celkon', '$1'),
    DeviceParser('Build/(?:[Cc]elkon)+_?([^;/_\\)]+)', None, '$1', 'Celkon', '$1'),
    DeviceParser('; {0,2}(CT)-?(\\d+)(?: Build|\\) AppleWebKit)', None, '$1$2', 'Celkon', '$1$2'),
    DeviceParser('; {0,2}(A19|A19Q|A105|A107[^;/\\)]*) ?(?:Build|;|\\))', None, '$1', 'Celkon', '$1'),
    DeviceParser('; {0,2}(TPC[0-9]{4,5})(?: Build|\\) AppleWebKit)', None, '$1', 'ChangJia', '$1'),
    DeviceParser('CrKey.*DeviceType/([^/]*)', None, 'Chromecast', 'Google', '$1'),
    DeviceParser('Fuchsia.*CrKey', None, 'Chromecast', 'Google', 'Nest Hub'),
    DeviceParser('Linux.*CrKey/1.36', None, 'Chromecast', 'Google', 'First Generation'),
    DeviceParser('CrKey/', None, 'Chromecast', 'Google', 'Chromecast'),
    DeviceParser('; {0,2}(Cloudfone)[ _](Excite)([^ ][^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1 $2 $3', 'Cloudfone', '$1 $2 $3'),
    DeviceParser('; {0,2}(Excite|ICE)[ _](\\d+[^;/]{0,100}?)(?: Build|\\) AppleWebKit)', None, 'Cloudfone $1 $2', 'Cloudfone', 'Cloudfone $1 $2'),
    DeviceParser('; {0,2}(Cloudfone|CloudPad)[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1 $2', 'Cloudfone', '$1 $2'),
    DeviceParser('; {0,2}((?:Aquila|Clanga|Rapax)[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', 'i', '$1', 'Cmx', '$1'),
    DeviceParser('; {0,2}(?:CFW-|Kyros )?(MID[0-9]{4}(?:[ABC]|SR|TV)?)(\\(3G\\)-4G| GB 8K| 3G| 8K| GB)? {0,2}(?:Build|[;\\)])', None, 'CobyKyros $1$2', 'CobyKyros', '$1$2'),
    DeviceParser('; {0,2}([^;/]{0,50})Coolpad[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1$2', 'Coolpad', '$1$2'),
    DeviceParser('; {0,2}(CUBE[ _])?([KU][0-9]+ ?GT.{0,200}?|A5300)(?: Build|\\) AppleWebKit)', 'i', '$1$2', 'Cube', '$2'),
    DeviceParser('; {0,2}CUBOT ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', 'i', '$1', 'Cubot', '$1'),
    DeviceParser('; {0,2}(BOBBY)(?: Build|\\) AppleWebKit)', 'i', '$1', 'Cubot', '$1'),
    DeviceParser('; {0,2}(Dslide [^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Danew', '$1'),
    DeviceParser('; {0,2}(XCD)[ _]?(28|35)(?: Build|\\) AppleWebKit)', None, 'Dell $1$2', 'Dell', '$1$2'),
    DeviceParser('; {0,2}(001DL)(?: Build|\\) AppleWebKit)', None, 'Dell $1', 'Dell', 'Streak'),
    DeviceParser('; {0,2}(?:Dell|DELL) (Streak)(?: Build|\\) AppleWebKit)', None, 'Dell $1', 'Dell', 'Streak'),
    DeviceParser('; {0,2}(101DL|GS01|Streak Pro[^;/]{0,100})(?: Build|\\) AppleWebKit)', None, 'Dell $1', 'Dell', 'Streak Pro'),
    DeviceParser('; {0,2}([Ss]treak ?7)(?: Build|\\) AppleWebKit)', None, 'Dell $1', 'Dell', 'Streak 7'),
    DeviceParser('; {0,2}(Mini-3iX)(?: Build|\\) AppleWebKit)', None, 'Dell $1', 'Dell', '$1'),
    DeviceParser('; {0,2}(?:Dell|DELL)[ _](Aero|Venue|Thunder|Mini.{0,200}?|Streak[ _]Pro)(?: Build|\\) AppleWebKit)', None, 'Dell $1', 'Dell', '$1'),
    DeviceParser('; {0,2}Dell[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, 'Dell $1', 'Dell', '$1'),
    DeviceParser('; {0,2}(TA[CD]-\\d+[^;/]{0,100})(?: Build|\\) AppleWebKit)', None, '$1', 'Denver', '$1'),
    DeviceParser('; {0,2}(iP[789]\\d{2}(?:-3G)?|IP10\\d{2}(?:-8GB)?)(?: Build|\\) AppleWebKit)', None, '$1', 'Dex', '$1'),
    DeviceParser('; {0,2}(AirTab)[ _\\-]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1 $2', 'DNS', '$1 $2'),
    DeviceParser('; {0,2}(F\\-\\d[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Fujitsu', '$1'),
    DeviceParser('; {0,2}(HT-03A)(?: Build|\\) AppleWebKit)', None, '$1', 'HTC', 'Magic'),
    DeviceParser('; {0,2}(HT\\-\\d[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'HTC', '$1'),
    DeviceParser('; {0,2}(L\\-\\d[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'LG', '$1'),
    DeviceParser('; {0,2}(N\\-\\d[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Nec', '$1'),
    DeviceParser('; {0,2}(P\\-\\d[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Panasonic', '$1'),
    DeviceParser('; {0,2}(SC\\-\\d[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Samsung', '$1'),
    DeviceParser('; {0,2}(SH\\-\\d[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Sharp', '$1'),
    DeviceParser('; {0,2}(SO\\-\\d[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'SonyEricsson', '$1'),
    DeviceParser('; {0,2}(T\\-0[12][^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Toshiba', '$1'),
    DeviceParser('; {0,2}(DOOV)[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1 $2', 'DOOV', '$2'),
    DeviceParser('; {0,2}(Enot|ENOT)[ -]?([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1 $2', 'Enot', '$2'),
    DeviceParser('; {0,2}[^;/]{1,100} Build/(?:CROSS|Cross)+[ _\\-]([^\\)]+)', None, 'CROSS $1', 'Evercoss', 'Cross $1'),
    DeviceParser('; {0,2}(CROSS|Cross)[ _\\-]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1 $2', 'Evercoss', 'Cross $2'),
    DeviceParser('; {0,2}Explay[_ ](.{1,200}?)(?:[\\)]| Build)', None, '$1', 'Explay', '$1'),
    DeviceParser('; {0,2}(IQ.{0,200}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Fly', '$1'),
    DeviceParser('; {0,2}(Fly|FLY)[ _](IQ[^;]{1,100}?|F[34]\\d+[^;]{0,100}?);?(?: Build|\\) AppleWebKit)', None, '$1 $2', 'Fly', '$2'),
    DeviceParser('; {0,2}(M532|Q572|FJL21)(?: Build|\\) AppleWebKit)', None, '$1', 'Fujitsu', '$1'),
    DeviceParser('; {0,2}(G1)(?: Build|\\) AppleWebKit)', None, '$1', 'Galapad', '$1'),
    DeviceParser('; {0,2}(Geeksphone) ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1 $2', '$1', '$2'),
    DeviceParser('; {0,2}(G[^F]?FIVE) ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1 $2', 'Gfive', '$2'),
    DeviceParser('; {0,2}(Gionee)[ _\\-]([^;/]{1,100}?)(?:/[^;/]{1,100}|)(?: Build|\\) AppleWebKit)', 'i', '$1 $2', 'Gionee', '$2'),
    DeviceParser('; {0,2}(GN\\d+[A-Z]?|INFINITY_PASSION|Ctrl_V1)(?: Build|\\) AppleWebKit)', None, 'Gionee $1', 'Gionee', '$1'),
    DeviceParser('; {0,2}(E3) Build/JOP40D', None, 'Gionee $1', 'Gionee', '$1'),
    DeviceParser('\\sGIONEE[-\\s_](\\w*)', 'i', 'Gionee $1', 'Gionee', '$1'),
    DeviceParser('; {0,2}((?:FONE|QUANTUM|INSIGNIA) \\d+[^;/]{0,100}|PLAYTAB)(?: Build|\\) AppleWebKit)', None, 'GoClever $1', 'GoClever', '$1'),
    DeviceParser('; {0,2}GOCLEVER ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, 'GoClever $1', 'GoClever', '$1'),
    DeviceParser('; {0,2}(Glass \\d+)(?: Build|\\) AppleWebKit)', None, '$1', 'Google', '$1'),
    DeviceParser('; {0,2}([g|G]oogle)? (Pixel[ a-zA-z0-9]{1,100});(?: Build|.{0,50}\\) AppleWebKit)', None, '$2', 'Google', '$2'),
    DeviceParser('; {0,2}([g|G]oogle)? (Pixel.{0,200}?)(?: Build|\\) AppleWebKit)', None, '$2', 'Google', '$2'),
    DeviceParser('; {0,2}(GSmart)[ -]([^/]{1,50})(?: Build|\\) AppleWebKit)', None, '$1 $2', 'Gigabyte', '$1 $2'),
    DeviceParser('; {0,2}(imx5[13]_[^/]{1,50})(?: Build|\\) AppleWebKit)', None, 'Freescale $1', 'Freescale', '$1'),
    DeviceParser('; {0,2}Haier[ _\\-]([^/]{1,50})(?: Build|\\) AppleWebKit)', None, 'Haier $1', 'Haier', '$1'),
    DeviceParser('; {0,2}(PAD1016)(?: Build|\\) AppleWebKit)', None, 'Haipad $1', 'Haipad', '$1'),
    DeviceParser('; {0,2}(M701|M7|M8|M9)(?: Build|\\) AppleWebKit)', None, 'Haipad $1', 'Haipad', '$1'),
    DeviceParser('; {0,2}(SN\\d+T[^;\\)/]*)(?: Build|[;\\)])', None, 'Hannspree $1', 'Hannspree', '$1'),
    DeviceParser('Build/HCL ME Tablet ([^;\\)]{1,3})[\\);]', None, 'HCLme $1', 'HCLme', '$1'),
    DeviceParser('; {0,2}([^;\\/]+) Build/HCL', None, 'HCLme $1', 'HCLme', '$1'),
    DeviceParser('; {0,2}(MID-?\\d{4}C[EM])(?: Build|\\) AppleWebKit)', None, 'Hena $1', 'Hena', '$1'),
    DeviceParser('; {0,2}(EG\\d{2,}|HS-[^;/]{1,100}|MIRA[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, 'Hisense $1', 'Hisense', '$1'),
    DeviceParser('; {0,2}(andromax[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', 'i', 'Hisense $1', 'Hisense', '$1'),
    DeviceParser('; {0,2}(?:AMAZE[ _](S\\d+)|(S\\d+)[ _]AMAZE)(?: Build|\\) AppleWebKit)', None, 'AMAZE $1$2', 'hitech', 'AMAZE $1$2'),
    DeviceParser('; {0,2}(PlayBook)(?: Build|\\) AppleWebKit)', None, 'HP $1', 'HP', '$1'),
    DeviceParser('; {0,2}HP ([^/]{1,50})(?: Build|\\) AppleWebKit)', None, 'HP $1', 'HP', '$1'),
    DeviceParser('; {0,2}([^/]{1,30}_tenderloin)(?: Build|\\) AppleWebKit)', None, 'HP TouchPad', 'HP', 'TouchPad'),
    DeviceParser('; {0,2}(HUAWEI |Huawei-|)([UY][^;/]{1,100}) Build/(?:Huawei|HUAWEI)([UY][^\\);]+)\\)', None, '$1$2', 'Huawei', '$2'),
    DeviceParser('; {0,2}([^;/]{1,100}) Build[/ ]Huawei(MT1-U06|[A-Z]{1,50}\\d+[^\\);]{1,50})\\)', None, '$1', 'Huawei', '$2'),
    DeviceParser('; {0,2}(S7|M860) Build', None, '$1', 'Huawei', '$1'),
    DeviceParser('; {0,2}((?:HUAWEI|Huawei)[ \\-]?)(MediaPad) Build', None, '$1$2', 'Huawei', '$2'),
    DeviceParser('; {0,2}((?:HUAWEI[ _]?|Huawei[ _]|)Ascend[ _])([^;/]{1,100}) Build', None, '$1$2', 'Huawei', '$2'),
    DeviceParser('; {0,2}((?:HUAWEI|Huawei)[ _\\-]?)((?:G700-|MT-)[^;/]{1,100}) Build', None, '$1$2', 'Huawei', '$2'),
    DeviceParser('; {0,2}((?:HUAWEI|Huawei)[ _\\-]?)([^;/]{1,100}) Build', None, '$1$2', 'Huawei', '$2'),
    DeviceParser('; {0,2}(MediaPad[^;]{1,200}|SpringBoard) Build/Huawei', None, '$1', 'Huawei', '$1'),
    DeviceParser('; {0,2}([^;]{1,200}) Build/(?:Huawei|HUAWEI)', None, '$1', 'Huawei', '$1'),
    DeviceParser('; {0,2}([Uu])([89]\\d{3}) Build', None, '$1$2', 'Huawei', 'U$2'),
    DeviceParser('; {0,2}(?:Ideos |IDEOS )(S7) Build', None, 'Huawei Ideos$1', 'Huawei', 'Ideos$1'),
    DeviceParser('; {0,2}(?:Ideos |IDEOS )([^;/]{1,50}\\s{0,5}|\\s{0,5})Build', None, 'Huawei Ideos$1', 'Huawei', 'Ideos$1'),
    DeviceParser('; {0,2}(Orange Daytona|Pulse|Pulse Mini|Vodafone 858|C8500|C8600|C8650|C8660|Nexus 6P|ATH-.{1,200}?) Build[/ ]', None, 'Huawei $1', 'Huawei', '$1'),
    DeviceParser('; {0,2}((?:[A-Z]{3})\\-L[A-Za0-9]{2})[\\)]', None, 'Huawei $1', 'Huawei', '$1'),
    DeviceParser('; {0,2}([^;]{1,200}) Build/(HONOR|Honor)', None, 'Huawei Honor $1', 'Huawei', 'Honor $1'),
    DeviceParser('; {0,2}HTC[ _]([^;]{1,200}); Windows Phone', None, 'HTC $1', 'HTC', '$1'),
    DeviceParser('; {0,2}(?:HTC[ _/])+([^ _/]+)(?:[/\\\\]1\\.0 | V|/| +)\\d+\\.\\d[\\d\\.]*(?: {0,2}Build|\\))', None, 'HTC $1', 'HTC', '$1'),
    DeviceParser('; {0,2}(?:HTC[ _/])+([^ _/]+)(?:[ _/]([^ _/]+)|)(?:[/\\\\]1\\.0 | V|/| +)\\d+\\.\\d[\\d\\.]*(?: {0,2}Build|\\))', None, 'HTC $1 $2', 'HTC', '$1 $2'),
    DeviceParser('; {0,2}(?:HTC[ _/])+([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/]+)|)|)(?:[/\\\\]1\\.0 | V|/| +)\\d+\\.\\d[\\d\\.]*(?: {0,2}Build|\\))', None, 'HTC $1 $2 $3', 'HTC', '$1 $2 $3'),
    DeviceParser('; {0,2}(?:HTC[ _/])+([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/]+)|)|)|)(?:[/\\\\]1\\.0 | V|/| +)\\d+\\.\\d[\\d\\.]*(?: {0,2}Build|\\))', None, 'HTC $1 $2 $3 $4', 'HTC', '$1 $2 $3 $4'),
    DeviceParser('; {0,2}(?:(?:HTC|htc)(?:_blocked|)[ _/])+([^ _/;]+)(?: {0,2}Build|[;\\)]| - )', None, 'HTC $1', 'HTC', '$1'),
    DeviceParser('; {0,2}(?:(?:HTC|htc)(?:_blocked|)[ _/])+([^ _/]+)(?:[ _/]([^ _/;\\)]+)|)(?: {0,2}Build|[;\\)]| - )', None, 'HTC $1 $2', 'HTC', '$1 $2'),
    DeviceParser('; {0,2}(?:(?:HTC|htc)(?:_blocked|)[ _/])+([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/;\\)]+)|)|)(?: {0,2}Build|[;\\)]| - )', None, 'HTC $1 $2 $3', 'HTC', '$1 $2 $3'),
    DeviceParser('; {0,2}(?:(?:HTC|htc)(?:_blocked|)[ _/])+([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ _/]+)(?:[ _/]([^ /;]+)|)|)|)(?: {0,2}Build|[;\\)]| - )', None, 'HTC $1 $2 $3 $4', 'HTC', '$1 $2 $3 $4'),
    DeviceParser('HTC Streaming Player [^\\/]{0,30}/[^\\/]{0,10}/ htc_([^/]{1,10}) /', None, 'HTC $1', 'HTC', '$1'),
    DeviceParser('(?:[;,] {0,2}|^)(?:htccn_chs-|)HTC[ _-]?([^;]{1,200}?)(?: {0,2}Build|clay|Android|-?Mozilla| Opera| Profile| UNTRUSTED|[;/\\(\\)]|$)', 'i', 'HTC $1', 'HTC', '$1'),
    DeviceParser('; {0,2}(A6277|ADR6200|ADR6300|ADR6350|ADR6400[A-Z]*|ADR6425[A-Z]*|APX515CKT|ARIA|Desire[^_ ]*|Dream|EndeavorU|Eris|Evo|Flyer|HD2|Hero|HERO200|Hero CDMA|HTL21|Incredible|Inspire[A-Z0-9]*|Legend|Liberty|Nexus ?(?:One|HD2)|One|One S C2|One[ _]?(?:S|V|X\\+?)\\w*|PC36100|PG06100|PG86100|S31HT|Sensation|Wildfire)(?: Build|[/;\\(\\)])', 'i', 'HTC $1', 'HTC', '$1'),
    DeviceParser('; {0,2}(ADR6200|ADR6400L|ADR6425LVW|Amaze|DesireS?|EndeavorU|Eris|EVO|Evo\\d[A-Z]+|HD2|IncredibleS?|Inspire[A-Z0-9]*|Sensation[A-Z0-9]*|Wildfire)[ _-](.{1,200}?)(?:[/;\\)]|Build|MIUI|1\\.0)', 'i', 'HTC $1 $2', 'HTC', '$1 $2'),
    DeviceParser('; {0,2}HYUNDAI (T\\d[^/]{0,10})(?: Build|\\) AppleWebKit)', None, 'Hyundai $1', 'Hyundai', '$1'),
    DeviceParser('; {0,2}HYUNDAI ([^;/]{1,10}?)(?: Build|\\) AppleWebKit)', None, 'Hyundai $1', 'Hyundai', '$1'),
    DeviceParser('; {0,2}(X700|Hold X|MB-6900)(?: Build|\\) AppleWebKit)', None, 'Hyundai $1', 'Hyundai', '$1'),
    DeviceParser('; {0,2}(?:iBall[ _\\-]|)(Andi)[ _]?(\\d[^;/]*)(?: Build|\\) AppleWebKit)', 'i', '$1 $2', 'iBall', '$1 $2'),
    DeviceParser('; {0,2}(IBall)(?:[ _]([^;/]{1,100}?)|)(?: Build|\\) AppleWebKit)', 'i', '$1 $2', 'iBall', '$2'),
    DeviceParser('; {0,2}(NT-\\d+[^ ;/]{0,50}|Net[Tt]AB [^;/]{1,50}|Mercury [A-Z]{1,50}|iconBIT)(?: S/N:[^;/]{1,50}|)(?: Build|\\) AppleWebKit)', None, '$1', 'IconBIT', '$1'),
    DeviceParser('; {0,2}(IMO)[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', 'i', '$1 $2', 'IMO', '$2'),
    DeviceParser('; {0,2}i-?mobile[ _]([^/]{1,50})(?: Build|\\) AppleWebKit)', 'i', 'i-mobile $1', 'imobile', '$1'),
    DeviceParser('; {0,2}(i-(?:style|note)[^/]{0,10})(?: Build|\\) AppleWebKit)', 'i', 'i-mobile $1', 'imobile', '$1'),
    DeviceParser('; {0,2}(ImPAD) ?(\\d+(?:.){0,100}?)(?: Build|\\) AppleWebKit)', None, '$1 $2', 'Impression', '$1 $2'),
    DeviceParser('; {0,2}(Infinix)[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1 $2', 'Infinix', '$2'),
    DeviceParser('; {0,2}(Informer)[ \\-]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1 $2', 'Informer', '$2'),
    DeviceParser('; {0,2}(TAB) ?([78][12]4)(?: Build|\\) AppleWebKit)', None, 'Intenso $1', 'Intenso', '$1 $2'),
    DeviceParser('; {0,2}(?:Intex[ _]|)(AQUA|Aqua)([ _\\.\\-])([^;/]{1,100}?) {0,2}(?:Build|;)', None, '$1$2$3', 'Intex', '$1 $3'),
    DeviceParser('; {0,2}(?:INTEX|Intex)(?:[_ ]([^\\ _;/]+))(?:[_ ]([^\\ _;/]+)|) {0,2}(?:Build|;)', None, '$1 $2', 'Intex', '$1 $2'),
    DeviceParser('; {0,2}([iI]Buddy)[ _]?(Connect)(?:_|\\?_| |)([^;/]{0,50}) {0,2}(?:Build|;)', None, '$1 $2 $3', 'Intex', 'iBuddy $2 $3'),
    DeviceParser('; {0,2}(I-Buddy)[ _]([^;/]{1,100}?) {0,2}(?:Build|;)', None, '$1 $2', 'Intex', 'iBuddy $2'),
    DeviceParser('; {0,2}(iOCEAN) ([^/]{1,50})(?: Build|\\) AppleWebKit)', 'i', '$1 $2', 'iOCEAN', '$2'),
    DeviceParser('; {0,2}(TP\\d+(?:\\.\\d+|)\\-\\d[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, 'ionik $1', 'ionik', '$1'),
    DeviceParser('; {0,2}(M702pro)(?: Build|\\) AppleWebKit)', None, '$1', 'Iru', '$1'),
    DeviceParser('; {0,2}itel ([^;/]*)(?: Build|\\) AppleWebKit)', None, 'Itel $1', 'Itel', '$1'),
    DeviceParser('; {0,2}(DE88Plus|MD70)(?: Build|\\) AppleWebKit)', None, '$1', 'Ivio', '$1'),
    DeviceParser('; {0,2}IVIO[_\\-]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Ivio', '$1'),
    DeviceParser('; {0,2}(TPC-\\d+|JAY-TECH)(?: Build|\\) AppleWebKit)', None, '$1', 'Jaytech', '$1'),
    DeviceParser('; {0,2}(JY-[^;/]{1,100}|G[234]S?)(?: Build|\\) AppleWebKit)', None, '$1', 'Jiayu', '$1'),
    DeviceParser('; {0,2}(JXD)[ _\\-]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1 $2', 'JXD', '$2'),
    DeviceParser('; {0,2}Karbonn[ _]?([^;/]{1,100}) {0,2}(?:Build|;)', 'i', '$1', 'Karbonn', '$1'),
    DeviceParser('; {0,2}([^;]{1,200}) Build/Karbonn', None, '$1', 'Karbonn', '$1'),
    DeviceParser('; {0,2}(A11|A39|A37|A34|ST8|ST10|ST7|Smart Tab3|Smart Tab2|Titanium S\\d) +Build', None, '$1', 'Karbonn', '$1'),
    DeviceParser('; {0,2}(IS01|IS03|IS05|IS\\d{2}SH)(?: Build|\\) AppleWebKit)', None, '$1', 'Sharp', '$1'),
    DeviceParser('; {0,2}(IS04)(?: Build|\\) AppleWebKit)', None, '$1', 'Regza', '$1'),
    DeviceParser('; {0,2}(IS06|IS\\d{2}PT)(?: Build|\\) AppleWebKit)', None, '$1', 'Pantech', '$1'),
    DeviceParser('; {0,2}(IS11S)(?: Build|\\) AppleWebKit)', None, '$1', 'SonyEricsson', 'Xperia Acro'),
    DeviceParser('; {0,2}(IS11CA)(?: Build|\\) AppleWebKit)', None, '$1', 'Casio', 'GzOne $1'),
    DeviceParser('; {0,2}(IS11LG)(?: Build|\\) AppleWebKit)', None, '$1', 'LG', 'Optimus X'),
    DeviceParser('; {0,2}(IS11N)(?: Build|\\) AppleWebKit)', None, '$1', 'Medias', '$1'),
    DeviceParser('; {0,2}(IS11PT)(?: Build|\\) AppleWebKit)', None, '$1', 'Pantech', 'MIRACH'),
    DeviceParser('; {0,2}(IS12F)(?: Build|\\) AppleWebKit)', None, '$1', 'Fujitsu', 'Arrows ES'),
    DeviceParser('; {0,2}(IS12M)(?: Build|\\) AppleWebKit)', None, '$1', 'Motorola', 'XT909'),
    DeviceParser('; {0,2}(IS12S)(?: Build|\\) AppleWebKit)', None, '$1', 'SonyEricsson', 'Xperia Acro HD'),
    DeviceParser('; {0,2}(ISW11F)(?: Build|\\) AppleWebKit)', None, '$1', 'Fujitsu', 'Arrowz Z'),
    DeviceParser('; {0,2}(ISW11HT)(?: Build|\\) AppleWebKit)', None, '$1', 'HTC', 'EVO'),
    DeviceParser('; {0,2}(ISW11K)(?: Build|\\) AppleWebKit)', None, '$1', 'Kyocera', 'DIGNO'),
    DeviceParser('; {0,2}(ISW11M)(?: Build|\\) AppleWebKit)', None, '$1', 'Motorola', 'Photon'),
    DeviceParser('; {0,2}(ISW11SC)(?: Build|\\) AppleWebKit)', None, '$1', 'Samsung', 'GALAXY S II WiMAX'),
    DeviceParser('; {0,2}(ISW12HT)(?: Build|\\) AppleWebKit)', None, '$1', 'HTC', 'EVO 3D'),
    DeviceParser('; {0,2}(ISW13HT)(?: Build|\\) AppleWebKit)', None, '$1', 'HTC', 'J'),
    DeviceParser('; {0,2}(ISW?[0-9]{2}[A-Z]{0,2})(?: Build|\\) AppleWebKit)', None, '$1', 'KDDI', '$1'),
    DeviceParser('; {0,2}(INFOBAR [^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'KDDI', '$1'),
    DeviceParser('; {0,2}(JOYPAD|Joypad)[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1 $2', 'Kingcom', '$1 $2'),
    DeviceParser('; {0,2}(Vox|VOX|Arc|K080)(?: Build|\\) AppleWebKit)', 'i', '$1', 'Kobo', '$1'),
    DeviceParser('\\b(Kobo Touch)\\b', None, '$1', 'Kobo', '$1'),
    DeviceParser('; {0,2}(K-Touch)[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', 'i', '$1 $2', 'Ktouch', '$2'),
    DeviceParser('; {0,2}((?:EV|KM)-S\\d+[A-Z]?)(?: Build|\\) AppleWebKit)', 'i', '$1', 'KTtech', '$1'),
    DeviceParser('; {0,2}(Zio|Hydro|Torque|Event|EVENT|Echo|Milano|Rise|URBANO PROGRESSO|WX04K|WX06K|WX10K|KYL21|101K|C5[12]\\d{2})(?: Build|\\) AppleWebKit)', None, '$1', 'Kyocera', '$1'),
    DeviceParser('; {0,2}(?:LAVA[ _]|)IRIS[ _\\-]?([^/;\\)]+) {0,2}(?:;|\\)|Build)', 'i', 'Iris $1', 'Lava', 'Iris $1'),
    DeviceParser('; {0,2}LAVA[ _]([^;/]{1,100}) Build', None, '$1', 'Lava', '$1'),
    DeviceParser('; {0,2}(?:(Aspire A1)|(?:LEMON|Lemon)[ _]([^;/]{1,100}))_?(?: Build|\\) AppleWebKit)', None, 'Lemon $1$2', 'Lemon', '$1$2'),
    DeviceParser('; {0,2}(TAB-1012)(?: Build|\\) AppleWebKit)', None, 'Lenco $1', 'Lenco', '$1'),
    DeviceParser('; Lenco ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, 'Lenco $1', 'Lenco', '$1'),
    DeviceParser('; {0,2}(A1_07|A2107A-H|S2005A-H|S1-37AH0) Build', None, '$1', 'Lenovo', '$1'),
    DeviceParser('; {0,2}(Idea[Tp]ab)[ _]([^;/]{1,100});? Build', None, 'Lenovo $1 $2', 'Lenovo', '$1 $2'),
    DeviceParser('; {0,2}(Idea(?:Tab|pad)) ?([^;/]{1,100}) Build', None, 'Lenovo $1 $2', 'Lenovo', '$1 $2'),
    DeviceParser('; {0,2}(ThinkPad) ?(Tablet) Build/', None, 'Lenovo $1 $2', 'Lenovo', '$1 $2'),
    DeviceParser('; {0,2}(?:LNV-|)(?:=?[Ll]enovo[ _\\-]?|LENOVO[ _])(.{1,200}?)(?:Build|[;/\\)])', None, 'Lenovo $1', 'Lenovo', '$1'),
    DeviceParser('[;,] (?:Vodafone |)(SmartTab) ?(II) ?(\\d+) Build/', None, 'Lenovo $1 $2 $3', 'Lenovo', '$1 $2 $3'),
    DeviceParser('; {0,2}(?:Ideapad |)K1 Build/', None, 'Lenovo Ideapad K1', 'Lenovo', 'Ideapad K1'),
    DeviceParser('; {0,2}(3GC101|3GW10[01]|A390) Build/', None, '$1', 'Lenovo', '$1'),
    DeviceParser('\\b(?:Lenovo|LENOVO)+[ _\\-]?([^,;:/ ]+)', None, 'Lenovo $1', 'Lenovo', '$1'),
    DeviceParser('; {0,2}(MFC\\d+)[A-Z]{2}([^;,/]*),?(?: Build|\\) AppleWebKit)', None, '$1$2', 'Lexibook', '$1$2'),
    DeviceParser('; {0,2}(E[34][0-9]{2}|LS[6-8][0-9]{2}|VS[6-9][0-9]+[^;/]{1,30}|Nexus 4|Nexus 5X?|GT540f?|Optimus (?:2X|G|4X HD)|OptimusX4HD) {0,2}(?:Build|;)', None, '$1', 'LG', '$1'),
    DeviceParser('[;:] {0,2}(L-\\d+[A-Z]|LGL\\d+[A-Z]?)(?:/V\\d+|) {0,2}(?:Build|[;\\)])', None, '$1', 'LG', '$1'),
    DeviceParser('; {0,2}(LG-)([A-Z]{1,2}\\d{2,}[^,;/\\)\\(]*?)(?:Build| V\\d+|[,;/\\)\\(]|$)', None, '$1$2', 'LG', '$2'),
    DeviceParser('; {0,2}(LG[ \\-]|LG)([^;/]{1,100})[;/]? Build', None, '$1$2', 'LG', '$2'),
    DeviceParser('^(LG)-([^;/]{1,100})/ Mozilla/.{0,200}; Android', None, '$1 $2', 'LG', '$2'),
    DeviceParser('(Web0S); Linux/(SmartTV)', None, 'LG $1 $2', 'LG', '$1 $2'),
    DeviceParser('; {0,2}((?:SMB|smb)[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Malata', '$1'),
    DeviceParser('; {0,2}(?:Malata|MALATA) ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Malata', '$1'),
    DeviceParser('; {0,2}(MS[45][0-9]{3}|MID0[568][NS]?|MID[1-9]|MID[78]0[1-9]|MID970[1-9]|MID100[1-9])(?: Build|\\) AppleWebKit)', None, '$1', 'Manta', '$1'),
    DeviceParser('; {0,2}(M1052|M806|M9000|M9100|M9701|MID100|MID120|MID125|MID130|MID135|MID140|MID701|MID710|MID713|MID727|MID728|MID731|MID732|MID733|MID735|MID736|MID737|MID760|MID800|MID810|MID820|MID830|MID833|MID835|MID860|MID900|MID930|MID933|MID960|MID980)(?: Build|\\) AppleWebKit)', None, '$1', 'Match', '$1'),
    DeviceParser('; {0,2}(GenxDroid7|MSD7.{0,200}?|AX\\d.{0,200}?|Tab 701|Tab 722)(?: Build|\\) AppleWebKit)', None, 'Maxx $1', 'Maxx', '$1'),
    DeviceParser('; {0,2}(M-PP[^;/]{1,30}|PhonePad ?\\d{2,}[^;/]{1,30}?)(?: Build|\\) AppleWebKit)', None, 'Mediacom $1', 'Mediacom', '$1'),
    DeviceParser('; {0,2}(M-MP[^;/]{1,30}|SmartPad ?\\d{2,}[^;/]{1,30}?)(?: Build|\\) AppleWebKit)', None, 'Mediacom $1', 'Mediacom', '$1'),
    DeviceParser('; {0,2}(?:MD_|)LIFETAB[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', 'i', 'Medion Lifetab $1', 'Medion', 'Lifetab $1'),
    DeviceParser('; {0,2}MEDION ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, 'Medion $1', 'Medion', '$1'),
    DeviceParser('; {0,2}(M030|M031|M035|M040|M065|m9)(?: Build|\\) AppleWebKit)', None, 'Meizu $1', 'Meizu', '$1'),
    DeviceParser('; {0,2}(?:meizu_|MEIZU )(.{1,200}?) {0,2}(?:Build|[;\\)])', None, 'Meizu $1', 'Meizu', '$1'),
    DeviceParser('Quest 3', None, 'Quest', 'Meta', 'Quest 3'),
    DeviceParser('Quest 2', None, 'Quest', 'Meta', 'Quest 2'),
    DeviceParser('Quest Pro', None, 'Quest', 'Meta', 'Quest Pro'),
    DeviceParser('Quest', None, 'Quest', 'Meta', 'Quest'),
    DeviceParser('; {0,2}(?:Micromax[ _](A111|A240)|(A111|A240)) Build', 'i', 'Micromax $1$2', 'Micromax', '$1$2'),
    DeviceParser('; {0,2}Micromax[ _](A\\d{2,3}[^;/]*) Build', 'i', 'Micromax $1', 'Micromax', '$1'),
    DeviceParser('; {0,2}(A\\d{2}|A[12]\\d{2}|A90S|A110Q) Build', 'i', 'Micromax $1', 'Micromax', '$1'),
    DeviceParser('; {0,2}Micromax[ _](P\\d{3}[^;/]*) Build', 'i', 'Micromax $1', 'Micromax', '$1'),
    DeviceParser('; {0,2}(P\\d{3}|P\\d{3}\\(Funbook\\)) Build', 'i', 'Micromax $1', 'Micromax', '$1'),
    DeviceParser('; {0,2}(MITO)[ _\\-]?([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', 'i', '$1 $2', 'Mito', '$2'),
    DeviceParser('; {0,2}(Cynus)[ _](F5|T\\d|.{1,200}?) {0,2}(?:Build|[;/\\)])', 'i', '$1 $2', 'Mobistel', '$1 $2'),
    DeviceParser('; {0,2}(MODECOM |)(FreeTab) ?([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', 'i', '$1$2 $3', 'Modecom', '$2 $3'),
    DeviceParser('; {0,2}(MODECOM )([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', 'i', '$1 $2', 'Modecom', '$2'),
    DeviceParser('; {0,2}(MZ\\d{3}\\+?|MZ\\d{3} 4G|Xoom|XOOM[^;/]*) Build', None, 'Motorola $1', 'Motorola', '$1'),
    DeviceParser('; {0,2}(Milestone )(XT[^;/]*) Build', None, 'Motorola $1$2', 'Motorola', '$2'),
    DeviceParser('; {0,2}(Motoroi ?x|Droid X|DROIDX) Build', 'i', 'Motorola $1', 'Motorola', 'DROID X'),
    DeviceParser('; {0,2}(Droid[^;/]*|DROID[^;/]*|Milestone[^;/]*|Photon|Triumph|Devour|Titanium) Build', None, 'Motorola $1', 'Motorola', '$1'),
    DeviceParser('; {0,2}(A555|A85[34][^;/]*|A95[356]|ME[58]\\d{2}\\+?|ME600|ME632|ME722|MB\\d{3}\\+?|MT680|MT710|MT870|MT887|MT917|WX435|WX453|WX44[25]|XT\\d{3,4}[A-Z\\+]*|CL[iI]Q|CL[iI]Q XT) Build', None, '$1', 'Motorola', '$1'),
    DeviceParser('; {0,2}(Motorola MOT-|Motorola[ _\\-]|MOT\\-?)([^;/]{1,100}) Build', None, '$1$2', 'Motorola', '$2'),
    DeviceParser('; {0,2}(Moto[_ ]?|MOT\\-)([^;/]{1,100}) Build', None, '$1$2', 'Motorola', '$2'),
    DeviceParser('; {0,2}((?:MP[DQ]C|MPG\\d{1,4}|MP\\d{3,4}|MID(?:(?:10[234]|114|43|7[247]|8[24]|7)C|8[01]1))[^;/]*)(?: Build|\\) AppleWebKit)', None, '$1', 'Mpman', '$1'),
    DeviceParser('; {0,2}(?:MSI[ _]|)(Primo\\d+|Enjoy[ _\\-][^;/]{1,100}?)(?: Build|\\) AppleWebKit)', 'i', '$1', 'Msi', '$1'),
    DeviceParser('; {0,2}Multilaser[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Multilaser', '$1'),
    DeviceParser('; {0,2}(My)[_]?(Pad)[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1$2 $3', 'MyPhone', '$1$2 $3'),
    DeviceParser('; {0,2}(My)\\|?(Phone)[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1$2 $3', 'MyPhone', '$3'),
    DeviceParser('; {0,2}(A\\d+)[ _](Duo|)(?: Build|\\) AppleWebKit)', 'i', '$1 $2', 'MyPhone', '$1 $2'),
    DeviceParser('; {0,2}(myTab[^;/]*)(?: Build|\\) AppleWebKit)', None, '$1', 'Mytab', '$1'),
    DeviceParser('; {0,2}(NABI2?-)([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1$2', 'Nabi', '$2'),
    DeviceParser('; {0,2}(N-\\d+[CDE])(?: Build|\\) AppleWebKit)', None, '$1', 'Nec', '$1'),
    DeviceParser('; ?(NEC-)(.{0,200}?)(?: Build|\\) AppleWebKit)', None, '$1$2', 'Nec', '$2'),
    DeviceParser('; {0,2}(LT-NA7)(?: Build|\\) AppleWebKit)', None, '$1', 'Nec', 'Lifetouch Note'),
    DeviceParser('; {0,2}(NXM\\d+[A-Za-z0-9_]{0,50}|Next\\d[A-Za-z0-9_ \\-]{0,50}|NEXT\\d[A-Za-z0-9_ \\-]{0,50}|Nextbook [A-Za-z0-9_ ]{0,50}|DATAM803HC|M805)(?: Build|[\\);])', None, '$1', 'Nextbook', '$1'),
    DeviceParser('; {0,2}(Nokia)([ _\\-]{0,5})([^;/]{0,50}) Build', 'i', '$1$2$3', 'Nokia', '$3'),
    DeviceParser('; {0,2}(TA\\-\\d{4})(?: Build|\\) AppleWebKit)', None, 'Nokia $1', 'Nokia', '$1'),
    DeviceParser('; {0,2}(Nook ?|Barnes & Noble Nook |BN )([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1$2', 'Nook', '$2'),
    DeviceParser('; {0,2}(NOOK |)(BNRV200|BNRV200A|BNTV250|BNTV250A|BNTV400|BNTV600|LogicPD Zoom2)(?: Build|\\) AppleWebKit)', None, '$1$2', 'Nook', '$2'),
    DeviceParser('; Build/(Nook)', None, '$1', 'Nook', 'Tablet'),
    DeviceParser('; {0,2}(OP110|OliPad[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, 'Olivetti $1', 'Olivetti', '$1'),
    DeviceParser('; {0,2}OMEGA[ _\\-](MID[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, 'Omega $1', 'Omega', '$1'),
    DeviceParser('^(MID7500|MID\\d+) Mozilla/5\\.0 \\(iPad;', None, 'Omega $1', 'Omega', '$1'),
    DeviceParser('; {0,2}((?:CIUS|cius)[^;/]*)(?: Build|\\) AppleWebKit)', None, 'Openpeak $1', 'Openpeak', '$1'),
    DeviceParser('; {0,2}(Find ?(?:5|7a)|R8[012]\\d{1,2}|T703\\d?|U70\\d{1,2}T?|X90\\d{1,2}|[AFR]\\d{1,2}[a-z]{1,2})(?: Build|\\) AppleWebKit)', None, 'Oppo $1', 'Oppo', '$1'),
    DeviceParser('; {0,2}OPPO ?([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, 'Oppo $1', 'Oppo', '$1'),
    DeviceParser('; {0,2}(CPH\\d{1,4}|RMX\\d{1,4}|P[A-Z]{3}\\d{2})(?: Build|\\) AppleWebKit)', None, 'Oppo $1', 'Oppo'),
    DeviceParser('; {0,2}(A1601)(?: Build|\\) AppleWebKit)', None, 'Oppo F1s', 'Oppo', '$1'),
    DeviceParser('; {0,2}(?:Odys\\-|ODYS\\-|ODYS )([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, 'Odys $1', 'Odys', '$1'),
    DeviceParser('; {0,2}(SELECT) ?(7)(?: Build|\\) AppleWebKit)', None, 'Odys $1 $2', 'Odys', '$1 $2'),
    DeviceParser('; {0,2}(PEDI)_(PLUS)_(W)(?: Build|\\) AppleWebKit)', None, 'Odys $1 $2 $3', 'Odys', '$1 $2 $3'),
    DeviceParser('; {0,2}(AEON|BRAVIO|FUSION|FUSION2IN1|Genio|EOS10|IEOS[^;/]*|IRON|Loox|LOOX|LOOX Plus|Motion|NOON|NOON_PRO|NEXT|OPOS|PEDI[^;/]*|PRIME[^;/]*|STUDYTAB|TABLO|Tablet-PC-4|UNO_X8|XELIO[^;/]*|Xelio ?\\d+ ?[Pp]ro|XENO10|XPRESS PRO)(?: Build|\\) AppleWebKit)', None, 'Odys $1', 'Odys', '$1'),
    DeviceParser('; (ONE [a-zA-Z]\\d+)(?: Build|\\) AppleWebKit)', None, 'OnePlus $1', 'OnePlus', '$1'),
    DeviceParser('; (ONEPLUS [a-zA-Z]\\d+)(?: Build|\\) AppleWebKit)', None, 'OnePlus $1', 'OnePlus', '$1'),
    DeviceParser('; {0,2}(HD1903|GM1917|IN2025|LE2115|LE2127|HD1907|BE2012|BE2025|BE2026|BE2028|BE2029|DE2117|DE2118|EB2101|GM1900|GM1910|GM1915|HD1905|HD1925|IN2015|IN2017|IN2019|KB2005|KB2007|LE2117|LE2125|BE2015|GM1903|HD1900|HD1901|HD1910|HD1913|IN2010|IN2013|IN2020|LE2111|LE2120|LE2121|LE2123|BE2011|IN2023|KB2003|LE2113|NE2215|DN2101)(?: Build|\\) AppleWebKit)', None, 'OnePlus $1', 'OnePlus', 'OnePlus $1'),
    DeviceParser('; (OnePlus[ a-zA-z0-9]{0,50});((?: Build|.{0,50}\\) AppleWebKit))', None, '$1', 'OnePlus', '$1'),
    DeviceParser('; (OnePlus[ a-zA-z0-9]{0,50})((?: Build|\\) AppleWebKit))', None, '$1', 'OnePlus', '$1'),
    DeviceParser('; {0,2}(TP-\\d+)(?: Build|\\) AppleWebKit)', None, 'Orion $1', 'Orion', '$1'),
    DeviceParser('; {0,2}(G100W?)(?: Build|\\) AppleWebKit)', None, 'PackardBell $1', 'PackardBell', '$1'),
    DeviceParser('; {0,2}(Panasonic)[_ ]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1 $2', '$1', '$2'),
    DeviceParser('; {0,2}(FZ-A1B|JT-B1)(?: Build|\\) AppleWebKit)', None, 'Panasonic $1', 'Panasonic', '$1'),
    DeviceParser('; {0,2}(dL1|DL1)(?: Build|\\) AppleWebKit)', None, 'Panasonic $1', 'Panasonic', '$1'),
    DeviceParser('; {0,2}(SKY[ _]|)(IM\\-[AT]\\d{3}[^;/]{1,100}).{0,30} Build/', None, 'Pantech $1$2', 'Pantech', '$1$2'),
    DeviceParser('; {0,2}((?:ADR8995|ADR910L|ADR930L|ADR930VW|PTL21|P8000)(?: 4G|)) Build/', None, '$1', 'Pantech', '$1'),
    DeviceParser('; {0,2}Pantech([^;/]{1,30}).{0,200}? Build/', None, 'Pantech $1', 'Pantech', '$1'),
    DeviceParser('; {0,2}(papyre)[ _\\-]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', 'i', '$1 $2', 'Papyre', '$2'),
    DeviceParser('; {0,2}(?:Touchlet )?(X10\\.[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, 'Pearl $1', 'Pearl', '$1'),
    DeviceParser('; PHICOMM (i800)(?: Build|\\) AppleWebKit)', None, 'Phicomm $1', 'Phicomm', '$1'),
    DeviceParser('; PHICOMM ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, 'Phicomm $1', 'Phicomm', '$1'),
    DeviceParser('; {0,2}(FWS\\d{3}[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, 'Phicomm $1', 'Phicomm', '$1'),
    DeviceParser('; {0,2}(D633|D822|D833|T539|T939|V726|W335|W336|W337|W3568|W536|W5510|W626|W632|W6350|W6360|W6500|W732|W736|W737|W7376|W820|W832|W8355|W8500|W8510|W930)(?: Build|\\) AppleWebKit)', None, '$1', 'Philips', '$1'),
    DeviceParser('; {0,2}(?:Philips|PHILIPS)[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, 'Philips $1', 'Philips', '$1'),
    DeviceParser('Android 4\\..{0,200}; {0,2}(M[12356789]|U[12368]|S[123])\\ ?(pro)?(?: Build|\\) AppleWebKit)', None, 'Pipo $1$2', 'Pipo', '$1$2'),
    DeviceParser('; {0,2}(MOMO[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Ployer', '$1'),
    DeviceParser('; {0,2}(?:Polaroid[ _]|)((?:MIDC\\d{3,}|PMID\\d{2,}|PTAB\\d{3,})[^;/]{0,30}?)(\\/[^;/]{0,30}|)(?: Build|\\) AppleWebKit)', None, '$1', 'Polaroid', '$1'),
    DeviceParser('; {0,2}(?:Polaroid )(Tablet)(?: Build|\\) AppleWebKit)', None, '$1', 'Polaroid', '$1'),
    DeviceParser('; {0,2}(POMP)[ _\\-](.{1,200}?) {0,2}(?:Build|[;/\\)])', None, '$1 $2', 'Pomp', '$2'),
    DeviceParser('; {0,2}(TB07STA|TB10STA|TB07FTA|TB10FTA)(?: Build|\\) AppleWebKit)', None, '$1', 'Positivo', '$1'),
    DeviceParser('; {0,2}(?:Positivo |)((?:YPY|Ypy)[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Positivo', '$1'),
    DeviceParser('; {0,2}(MOB-[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'POV', '$1'),
    DeviceParser('; {0,2}POV[ _\\-]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, 'POV $1', 'POV', '$1'),
    DeviceParser('; {0,2}((?:TAB-PLAYTAB|TAB-PROTAB|PROTAB|PlayTabPro|Mobii[ _\\-]|TAB-P)[^;/]*)(?: Build|\\) AppleWebKit)', None, 'POV $1', 'POV', '$1'),
    DeviceParser('; {0,2}(?:Prestigio |)((?:PAP|PMP)\\d[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, 'Prestigio $1', 'Prestigio', '$1'),
    DeviceParser('; {0,2}(PLT[0-9]{4}.{0,200}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Proscan', '$1'),
    DeviceParser('; {0,2}(A2|A5|A8|A900)_?(Classic|)(?: Build|\\) AppleWebKit)', None, '$1 $2', 'Qmobile', '$1 $2'),
    DeviceParser('; {0,2}(Q[Mm]obile)_([^_]+)_([^_]+?)(?: Build|\\) AppleWebKit)', None, 'Qmobile $2 $3', 'Qmobile', '$2 $3'),
    DeviceParser('; {0,2}(Q\\-?[Mm]obile)[_ ](A[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, 'Qmobile $2', 'Qmobile', '$2'),
    DeviceParser('; {0,2}(Q\\-Smart)[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1 $2', 'Qmobilevn', '$2'),
    DeviceParser('; {0,2}(Q\\-?[Mm]obile)[ _\\-](S[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1 $2', 'Qmobilevn', '$2'),
    DeviceParser('; {0,2}(TA1013)(?: Build|\\) AppleWebKit)', None, '$1', 'Quanta', '$1'),
    DeviceParser('; (RCT\\w+)(?: Build|\\) AppleWebKit)', None, '$1', 'RCA', '$1'),
    DeviceParser('; RCA (\\w+)(?: Build|\\) AppleWebKit)', None, 'RCA $1', 'RCA', '$1'),
    DeviceParser('; {0,2}(RK\\d+),?(?: Build|\\) AppleWebKit)', None, '$1', 'Rockchip', '$1'),
    DeviceParser(' Build/(RK\\d+)', None, '$1', 'Rockchip', '$1'),
    DeviceParser('; {0,2}(SAMSUNG |Samsung |)((?:Galaxy (?:Note II|S\\d)|GT-I9082|GT-I9205|GT-N7\\d{3}|SM-N9005)[^;/]{0,100})\\/?[^;/]{0,50} Build/', None, 'Samsung $1$2', 'Samsung', '$2'),
    DeviceParser('; {0,2}(Google |)(Nexus [Ss](?: 4G|)) Build/', None, 'Samsung $1$2', 'Samsung', '$2'),
    DeviceParser('; {0,2}(SAMSUNG |Samsung )([^\\/]{0,50})\\/[^ ]{0,50} Build/', None, 'Samsung $2', 'Samsung', '$2'),
    DeviceParser('; {0,2}(Galaxy(?: Ace| Nexus| S ?II+|Nexus S| with MCR 1.2| Mini Plus 4G|)) Build/', None, 'Samsung $1', 'Samsung', '$1'),
    DeviceParser('; {0,2}(SAMSUNG[ _\\-]|)(?:SAMSUNG[ _\\-])([^;/]{1,100}) Build', None, 'Samsung $2', 'Samsung', '$2'),
    DeviceParser('; {0,2}(SAMSUNG-|)(GT\\-[BINPS]\\d{4}[^\\/]{0,50})(\\/[^ ]{0,50}) Build', None, 'Samsung $1$2$3', 'Samsung', '$2'),
    DeviceParser('(?:; {0,2}|^)((?:GT\\-[BIiNPS]\\d{4}|I9\\d{2}0[A-Za-z\\+]?\\b)[^;/\\)]*?)(?:Build|Linux|MIUI|[;/\\)])', None, 'Samsung $1', 'Samsung', '$1'),
    DeviceParser('; (SAMSUNG-)([A-Za-z0-9\\-]{0,50}).{0,200} Build/', None, 'Samsung $1$2', 'Samsung', '$2'),
    DeviceParser('; {0,2}((?:SCH|SGH|SHV|SHW|SPH|SC|SM)\\-[A-Za-z0-9 ]{1,50})(/?[^ ]*|) Build', None, 'Samsung $1', 'Samsung', '$1'),
    DeviceParser('; {0,2}((?:SC)\\-[A-Za-z0-9 ]{1,50})(/?[^ ]*|)\\)', None, 'Samsung $1', 'Samsung', '$1'),
    DeviceParser(' ((?:SCH)\\-[A-Za-z0-9 ]{1,50})(/?[^ ]*|) Build', None, 'Samsung $1', 'Samsung', '$1'),
    DeviceParser('; {0,2}(Behold ?(?:2|II)|YP\\-G[^;/]{1,100}|EK-GC100|SCL21|I9300) Build', None, 'Samsung $1', 'Samsung', '$1'),
    DeviceParser('; {0,2}((?:SCH|SGH|SHV|SHW|SPH|SC|SM)\\-[A-Za-z0-9]{5,6})[\\)]', None, 'Samsung $1', 'Samsung', '$1'),
    DeviceParser('; {0,2}(SH\\-?\\d\\d[^;/]{1,100}|SBM\\d[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Sharp', '$1'),
    DeviceParser('; {0,2}(SHARP[ -])([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1$2', 'Sharp', '$2'),
    DeviceParser('; {0,2}(SPX[_\\-]\\d[^;/]*)(?: Build|\\) AppleWebKit)', None, '$1', 'Simvalley', '$1'),
    DeviceParser('; {0,2}(SX7\\-PEARL\\.GmbH)(?: Build|\\) AppleWebKit)', None, '$1', 'Simvalley', '$1'),
    DeviceParser('; {0,2}(SP[T]?\\-\\d{2}[^;/]*)(?: Build|\\) AppleWebKit)', None, '$1', 'Simvalley', '$1'),
    DeviceParser('; {0,2}(SK\\-.{0,200}?)(?: Build|\\) AppleWebKit)', None, '$1', 'SKtelesys', '$1'),
    DeviceParser('; {0,2}(?:SKYTEX|SX)-([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Skytex', '$1'),
    DeviceParser('; {0,2}(IMAGINE [^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Skytex', '$1'),
    DeviceParser('; {0,2}(SmartQ) ?([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1 $2', '$1', '$2'),
    DeviceParser('; {0,2}(WF7C|WF10C|SBT[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Smartbitt', '$1'),
    DeviceParser('; {0,2}(SBM(?:003SH|005SH|006SH|007SH|102SH)) Build', None, '$1', 'Sharp', '$1'),
    DeviceParser('; {0,2}(003P|101P|101P11C|102P) Build', None, '$1', 'Panasonic', '$1'),
    DeviceParser('; {0,2}(00\\dZ) Build/', None, '$1', 'ZTE', '$1'),
    DeviceParser('; HTC(X06HT) Build', None, '$1', 'HTC', '$1'),
    DeviceParser('; {0,2}(001HT|X06HT) Build', None, '$1', 'HTC', '$1'),
    DeviceParser('; {0,2}(201M) Build', None, '$1', 'Motorola', 'XT902'),
    DeviceParser('; {0,2}(ST\\d{4}.{0,200})Build/ST', None, 'Trekstor $1', 'Trekstor', '$1'),
    DeviceParser('; {0,2}(ST\\d{4}.{0,200}?)(?: Build|\\) AppleWebKit)', None, 'Trekstor $1', 'Trekstor', '$1'),
    DeviceParser('; {0,2}(Sony ?Ericsson ?)([^;/]{1,100}) Build', None, '$1$2', 'SonyEricsson', '$2'),
    DeviceParser('; {0,2}((?:SK|ST|E|X|LT|MK|MT|WT)\\d{2}[a-z0-9]*(?:-o|)|R800i|U20i) Build', None, '$1', 'SonyEricsson', '$1'),
    DeviceParser('; {0,2}(Xperia (?:A8|Arc|Acro|Active|Live with Walkman|Mini|Neo|Play|Pro|Ray|X\\d+)[^;/]{0,50}) Build', 'i', '$1', 'SonyEricsson', '$1'),
    DeviceParser('; Sony (Tablet[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, 'Sony $1', 'Sony', '$1'),
    DeviceParser('; Sony ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, 'Sony $1', 'Sony', '$1'),
    DeviceParser('; {0,2}(Sony)([A-Za-z0-9\\-]+)(?: Build|\\) AppleWebKit)', None, '$1 $2', '$1', '$2'),
    DeviceParser('; {0,2}(Xperia [^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Sony', '$1'),
    DeviceParser('; {0,2}(C(?:1[0-9]|2[0-9]|53|55|6[0-9])[0-9]{2}|D[25]\\d{3}|D6[56]\\d{2})(?: Build|\\) AppleWebKit)', None, '$1', 'Sony', '$1'),
    DeviceParser('; {0,2}(SGP\\d{3}|SGPT\\d{2})(?: Build|\\) AppleWebKit)', None, '$1', 'Sony', '$1'),
    DeviceParser('; {0,2}(NW-Z1000Series)(?: Build|\\) AppleWebKit)', None, '$1', 'Sony', '$1'),
    DeviceParser('PLAYSTATION 3', None, 'PlayStation 3', 'Sony', 'PlayStation 3'),
    DeviceParser('(PlayStation (?:Portable|Vita|\\d+))', None, '$1', 'Sony', '$1'),
    DeviceParser('; {0,2}((?:CSL_Spice|Spice|SPICE|CSL)[ _\\-]?|)([Mm][Ii])([ _\\-]|)(\\d{3}[^;/]*)(?: Build|\\) AppleWebKit)', None, '$1$2$3$4', 'Spice', 'Mi$4'),
    DeviceParser('; {0,2}(Sprint )(.{1,200}?) {0,2}(?:Build|[;/])', None, '$1$2', 'Sprint', '$2'),
    DeviceParser('\\b(Sprint)[: ]([^;,/ ]+)', None, '$1$2', 'Sprint', '$2'),
    DeviceParser('; {0,2}(TAGI[ ]?)(MID) ?([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1$2$3', 'Tagi', '$2$3'),
    DeviceParser('; {0,2}(Oyster500|Opal 800)(?: Build|\\) AppleWebKit)', None, 'Tecmobile $1', 'Tecmobile', '$1'),
    DeviceParser('; {0,2}(TECNO[ _])([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1$2', 'Tecno', '$2'),
    DeviceParser('; {0,2}Android for (Telechips|Techvision) ([^ ]+) ', 'i', '$1 $2', '$1', '$2'),
    DeviceParser('; {0,2}(T-Hub2)(?: Build|\\) AppleWebKit)', None, '$1', 'Telstra', '$1'),
    DeviceParser('; {0,2}(PAD) ?(100[12])(?: Build|\\) AppleWebKit)', None, 'Terra $1$2', 'Terra', '$1$2'),
    DeviceParser('; {0,2}(T[BM]-\\d{3}[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Texet', '$1'),
    DeviceParser('; {0,2}(tolino [^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Thalia', '$1'),
    DeviceParser('; {0,2}Build/.{0,200} (TOLINO_BROWSER)', None, '$1', 'Thalia', 'Tolino Shine'),
    DeviceParser('; {0,2}(?:CJ[ -])?(ThL|THL)[ -]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1 $2', 'Thl', '$2'),
    DeviceParser('; {0,2}(T100|T200|T5|W100|W200|W8s)(?: Build|\\) AppleWebKit)', None, '$1', 'Thl', '$1'),
    DeviceParser('; {0,2}(T-Mobile[ _]G2[ _]Touch) Build', None, '$1', 'HTC', 'Hero'),
    DeviceParser('; {0,2}(T-Mobile[ _]G2) Build', None, '$1', 'HTC', 'Desire Z'),
    DeviceParser('; {0,2}(T-Mobile myTouch Q) Build', None, '$1', 'Huawei', 'U8730'),
    DeviceParser('; {0,2}(T-Mobile myTouch) Build', None, '$1', 'Huawei', 'U8680'),
    DeviceParser('; {0,2}(T-Mobile_Espresso) Build', None, '$1', 'HTC', 'Espresso'),
    DeviceParser('; {0,2}(T-Mobile G1) Build', None, '$1', 'HTC', 'Dream'),
    DeviceParser('\\b(T-Mobile ?|)(myTouch)[ _]?([34]G)[ _]?([^\\/]*) (?:Mozilla|Build)', None, '$1$2 $3 $4', 'HTC', '$2 $3 $4'),
    DeviceParser('\\b(T-Mobile)_([^_]+)_(.{0,200}) Build', None, '$1 $2 $3', 'Tmobile', '$2 $3'),
    DeviceParser('\\b(T-Mobile)[_ ]?(.{0,200}?)Build', None, '$1 $2', 'Tmobile', '$2'),
    DeviceParser(' (ATP[0-9]{4})(?: Build|\\) AppleWebKit)', None, '$1', 'Tomtec', '$1'),
    DeviceParser(' ?(TOOKY)[ _\\-]([^;/]{1,100}) ?(?:Build|;)', 'i', '$1 $2', 'Tooky', '$2'),
    DeviceParser('\\b(TOSHIBA_AC_AND_AZ|TOSHIBA_FOLIO_AND_A|FOLIO_AND_A)', None, '$1', 'Toshiba', 'Folio 100'),
    DeviceParser('; {0,2}([Ff]olio ?100)(?: Build|\\) AppleWebKit)', None, '$1', 'Toshiba', 'Folio 100'),
    DeviceParser('; {0,2}(AT[0-9]{2,3}(?:\\-A|LE\\-A|PE\\-A|SE|a|)|AT7-A|AT1S0|Hikari-iFrame/WDPF-[^;/]{1,100}|THRiVE|Thrive)(?: Build|\\) AppleWebKit)', None, 'Toshiba $1', 'Toshiba', '$1'),
    DeviceParser('; {0,2}(TM-MID\\d+[^;/]{1,50}|TOUCHMATE|MID-750)(?: Build|\\) AppleWebKit)', None, '$1', 'Touchmate', '$1'),
    DeviceParser('; {0,2}(TM-SM\\d+[^;/]{1,50}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Touchmate', '$1'),
    DeviceParser('; {0,2}(A10 [Bb]asic2?)(?: Build|\\) AppleWebKit)', None, '$1', 'Treq', '$1'),
    DeviceParser('; {0,2}(TREQ[ _\\-])([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', 'i', '$1$2', 'Treq', '$2'),
    DeviceParser('; {0,2}(X-?5|X-?3)(?: Build|\\) AppleWebKit)', None, '$1', 'Umeox', '$1'),
    DeviceParser('; {0,2}(A502\\+?|A936|A603|X1|X2)(?: Build|\\) AppleWebKit)', None, '$1', 'Umeox', '$1'),
    DeviceParser('; thor Build/', None, 'Thor', 'Vernee', 'Thor'),
    DeviceParser('; Thor (E)? Build/', None, 'Thor $1', 'Vernee', 'Thor'),
    DeviceParser('; Apollo Lite Build/', None, 'Apollo Lite', 'Vernee', 'Apollo'),
    DeviceParser('(TOUCH(?:TAB|PAD).{1,200}?)(?: Build|\\) AppleWebKit)', 'i', 'Versus $1', 'Versus', '$1'),
    DeviceParser('(VERTU) ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1 $2', 'Vertu', '$2'),
    DeviceParser('; {0,2}(Videocon)[ _\\-]([^;/]{1,100}?) {0,2}(?:Build|;)', None, '$1 $2', 'Videocon', '$2'),
    DeviceParser(' (VT\\d{2}[A-Za-z]*)(?: Build|\\) AppleWebKit)', None, '$1', 'Videocon', '$1'),
    DeviceParser('; {0,2}((?:ViewPad|ViewPhone|VSD)[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Viewsonic', '$1'),
    DeviceParser('; {0,2}(ViewSonic-)([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1$2', 'Viewsonic', '$2'),
    DeviceParser('; {0,2}(GTablet.{0,200}?)(?: Build|\\) AppleWebKit)', None, '$1', 'Viewsonic', '$1'),
    DeviceParser('; {0,2}([Vv]ivo)[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, '$1 $2', 'vivo', '$2'),
    DeviceParser('(Vodafone) (.{0,200}?)(?: Build|\\) AppleWebKit)', None, '$1 $2', '$1', '$2'),
    DeviceParser('; {0,2}(?:Walton[ _\\-]|)(Primo[ _\\-][^;/]{1,100}?)(?: Build|\\) AppleWebKit)', 'i', 'Walton $1', 'Walton', '$1'),
    DeviceParser('; {0,2}(?:WIKO[ \\-]|)(CINK\\+?|BARRY|BLOOM|DARKFULL|DARKMOON|DARKNIGHT|DARKSIDE|FIZZ|HIGHWAY|IGGY|OZZY|RAINBOW|STAIRWAY|SUBLIM|WAX|CINK [^;/]{1,100}?)(?: Build|\\) AppleWebKit)', 'i', 'Wiko $1', 'Wiko', '$1'),
    DeviceParser('; {0,2}WellcoM-([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, 'Wellcom $1', 'Wellcom', '$1'),
    DeviceParser('(?:(WeTab)-Browser|; (wetab) Build)', None, '$1', 'WeTab', 'WeTab'),
    DeviceParser('; {0,2}(AT-AS[^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, 'Wolfgang $1', 'Wolfgang', '$1'),
    DeviceParser('; {0,2}(?:Woxter|Wxt) ([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, 'Woxter $1', 'Woxter', '$1'),
    DeviceParser('; {0,2}(?:Xenta |Luna |)(TAB[234][0-9]{2}|TAB0[78]-\\d{3}|TAB0?9-\\d{3}|TAB1[03]-\\d{3}|SMP\\d{2}-\\d{3})(?: Build|\\) AppleWebKit)', None, 'Yarvik $1', 'Yarvik', '$1'),
    DeviceParser('; {0,2}([A-Z]{2,4})(M\\d{3,}[A-Z]{2})([^;\\)\\/]*)(?: Build|[;\\)])', None, 'Yifang $1$2$3', 'Yifang', '$2'),
    DeviceParser('; {0,2}((Mi|MI|HM|MI-ONE|Redmi)[ -](NOTE |Note |)[^;/]*) (Build|MIUI)/', None, 'XiaoMi $1', 'XiaoMi', '$1'),
    DeviceParser('; {0,2}((Mi|MI|HM|MI-ONE|Redmi)[ -](NOTE |Note |)[^;/\\)]*)', None, 'XiaoMi $1', 'XiaoMi', '$1'),
    DeviceParser('; {0,2}(MIX) (Build|MIUI)/', None, 'XiaoMi $1', 'XiaoMi', '$1'),
    DeviceParser('; {0,2}((MIX) ([^;/]*)) (Build|MIUI)/', None, 'XiaoMi $1', 'XiaoMi', '$1'),
    DeviceParser('; {0,2}XOLO[ _]([^;/]{0,30}tab.{0,30})(?: Build|\\) AppleWebKit)', 'i', 'Xolo $1', 'Xolo', '$1'),
    DeviceParser('; {0,2}XOLO[ _]([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', 'i', 'Xolo $1', 'Xolo', '$1'),
    DeviceParser('; {0,2}(q\\d0{2,3}[a-z]?)(?: Build|\\) AppleWebKit)', 'i', 'Xolo $1', 'Xolo', '$1'),
    DeviceParser('; {0,2}(PAD ?[79]\\d+[^;/]{0,50}|TelePAD\\d+[^;/])(?: Build|\\) AppleWebKit)', None, 'Xoro $1', 'Xoro', '$1'),
    DeviceParser('; {0,2}(?:(?:ZOPO|Zopo)[ _]([^;/]{1,100}?)|(ZP ?(?:\\d{2}[^;/]{1,100}|C2))|(C[2379]))(?: Build|\\) AppleWebKit)', None, '$1$2$3', 'Zopo', '$1$2$3'),
    DeviceParser('; {0,2}(ZiiLABS) (Zii[^;/]*)(?: Build|\\) AppleWebKit)', None, '$1 $2', 'ZiiLabs', '$2'),
    DeviceParser('; {0,2}(Zii)_([^;/]*)(?: Build|\\) AppleWebKit)', None, '$1 $2', 'ZiiLabs', '$2'),
    DeviceParser('; {0,2}(ARIZONA|(?:ATLAS|Atlas) W|D930|Grand (?:[SX][^;]{0,200}?|Era|Memo[^;]{0,200}?)|JOE|(?:Kis|KIS)\\b[^;]{0,200}?|Libra|Light [^;]{0,200}?|N8[056][01]|N850L|N8000|N9[15]\\d{2}|N9810|NX501|Optik|(?:Vip )Racer[^;]{0,200}?|RacerII|RACERII|San Francisco[^;]{0,200}?|V9[AC]|V55|V881|Z[679][0-9]{2}[A-z]?)(?: Build|\\) AppleWebKit)', None, '$1', 'ZTE', '$1'),
    DeviceParser('; {0,2}([A-Z]\\d+)_USA_[^;]{0,200}(?: Build|\\) AppleWebKit)', None, '$1', 'ZTE', '$1'),
    DeviceParser('; {0,2}(SmartTab\\d+)[^;]{0,50}(?: Build|\\) AppleWebKit)', None, '$1', 'ZTE', '$1'),
    DeviceParser('; {0,2}(?:Blade|BLADE|ZTE-BLADE)([^;/]*)(?: Build|\\) AppleWebKit)', None, 'ZTE Blade$1', 'ZTE', 'Blade$1'),
    DeviceParser('; {0,2}(?:Skate|SKATE|ZTE-SKATE)([^;/]*)(?: Build|\\) AppleWebKit)', None, 'ZTE Skate$1', 'ZTE', 'Skate$1'),
    DeviceParser('; {0,2}(Orange |Optimus )(Monte Carlo|San Francisco)(?: Build|\\) AppleWebKit)', None, '$1$2', 'ZTE', '$1$2'),
    DeviceParser('; {0,2}(?:ZXY-ZTE_|ZTE\\-U |ZTE[\\- _]|ZTE-C[_ ])([^;/]{1,100}?)(?: Build|\\) AppleWebKit)', None, 'ZTE $1', 'ZTE', '$1'),
    DeviceParser('; (BASE) (lutea|Lutea 2|Tab[^;]{0,200}?)(?: Build|\\) AppleWebKit)', None, '$1 $2', 'ZTE', '$1 $2'),
    DeviceParser('; (Avea inTouch 2|soft stone|tmn smart a7|Movistar[ _]Link)(?: Build|\\) AppleWebKit)', 'i', '$1', 'ZTE', '$1'),
    DeviceParser('; {0,2}(vp9plus)\\)', None, '$1', 'ZTE', '$1'),
    DeviceParser('; ?(Cloud[ _]Z5|z1000|Z99 2G|z99|z930|z999|z990|z909|Z919|z900)(?: Build|\\) AppleWebKit)', None, '$1', 'Zync', '$1'),
    DeviceParser('; ?(KFOT|Kindle Fire) Build\\b', None, 'Kindle Fire', 'Amazon', 'Kindle Fire'),
    DeviceParser('; ?(KFOTE|Amazon Kindle Fire2) Build\\b', None, 'Kindle Fire 2', 'Amazon', 'Kindle Fire 2'),
    DeviceParser('; ?(KFTT) Build\\b', None, 'Kindle Fire HD', 'Amazon', 'Kindle Fire HD 7"'),
    DeviceParser('; ?(KFJWI) Build\\b', None, 'Kindle Fire HD 8.9" WiFi', 'Amazon', 'Kindle Fire HD 8.9" WiFi'),
    DeviceParser('; ?(KFJWA) Build\\b', None, 'Kindle Fire HD 8.9" 4G', 'Amazon', 'Kindle Fire HD 8.9" 4G'),
    DeviceParser('; ?(KFSOWI) Build\\b', None, 'Kindle Fire HD 7" WiFi', 'Amazon', 'Kindle Fire HD 7" WiFi'),
    DeviceParser('; ?(KFTHWI) Build\\b', None, 'Kindle Fire HDX 7" WiFi', 'Amazon', 'Kindle Fire HDX 7" WiFi'),
    DeviceParser('; ?(KFTHWA) Build\\b', None, 'Kindle Fire HDX 7" 4G', 'Amazon', 'Kindle Fire HDX 7" 4G'),
    DeviceParser('; ?(KFAPWI) Build\\b', None, 'Kindle Fire HDX 8.9" WiFi', 'Amazon', 'Kindle Fire HDX 8.9" WiFi'),
    DeviceParser('; ?(KFAPWA) Build\\b', None, 'Kindle Fire HDX 8.9" 4G', 'Amazon', 'Kindle Fire HDX 8.9" 4G'),
    DeviceParser('; ?Amazon ([^;/]{1,100}) Build\\b', None, '$1', 'Amazon', '$1'),
    DeviceParser('; ?(Kindle) Build\\b', None, 'Kindle', 'Amazon', 'Kindle'),
    DeviceParser('; ?(Silk)/(\\d+)\\.(\\d+)(?:\\.([0-9\\-]+)|) Build\\b', None, 'Kindle Fire', 'Amazon', 'Kindle Fire$2'),
    DeviceParser(' (Kindle)/(\\d+\\.\\d+)', None, 'Kindle', 'Amazon', '$1 $2'),
    DeviceParser(' (Silk|Kindle)/(\\d+)\\.', None, 'Kindle', 'Amazon', 'Kindle'),
    DeviceParser('(sprd)\\-([^/]{1,50})/', None, '$1 $2', '$1', '$2'),
    DeviceParser('; {0,2}(H\\d{2}00\\+?) Build', None, '$1', 'Hero', '$1'),
    DeviceParser('; {0,2}(iphone|iPhone5) Build/', None, 'Xianghe $1', 'Xianghe', '$1'),
    DeviceParser('; {0,2}(e\\d{4}[a-z]?_?v\\d+|v89_[^;/]{1,100})[^;/]{1,30} Build/', None, 'Xianghe $1', 'Xianghe', '$1'),
    DeviceParser('\\bUSCC[_\\-]?([^ ;/\\)]+)', None, '$1', 'Cellular', '$1'),
    DeviceParser('Windows Phone [^;]{1,30}; .{0,100}?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|)(?:ALCATEL)[^;]{0,200}; {0,2}([^;,\\)]+)', None, 'Alcatel $1', 'Alcatel', '$1'),
    DeviceParser('Windows Phone [^;]{1,30}; .{0,100}?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?|)(?:ASUS|Asus)[^;]{0,200}; {0,2}([^;,\\)]+)', None, 'Asus $1', 'Asus', '$1'),
    DeviceParser('Windows Phone [^;]{1,30}; .{0,100}?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|)(?:DELL|Dell)[^;]{0,200}; {0,2}([^;,\\)]+)', None, 'Dell $1', 'Dell', '$1'),
    DeviceParser('Windows Phone [^;]{1,30}; .{0,100}?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?|)(?:HTC|Htc|HTC_blocked[^;]{0,200})[^;]{0,200}; {0,2}(?:HTC|)([^;,\\)]+)', None, 'HTC $1', 'HTC', '$1'),
    DeviceParser('Windows Phone [^;]{1,30}; .{0,100}?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|)(?:HUAWEI)[^;]{0,200}; {0,2}(?:HUAWEI |)([^;,\\)]+)', None, 'Huawei $1', 'Huawei', '$1'),
    DeviceParser('Windows Phone [^;]{1,30}; .{0,100}?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|)(?:LG|Lg)[^;]{0,200}; {0,2}(?:LG[ \\-]|)([^;,\\)]+)', None, 'LG $1', 'LG', '$1'),
    DeviceParser('Windows Phone [^;]{1,30}; .{0,100}?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|)(?:rv:11; |)(?:NOKIA|Nokia)[^;]{0,200}; {0,2}(?:NOKIA ?|Nokia ?|LUMIA ?|[Ll]umia ?|)(\\d{3,10}[^;\\)]*)', None, 'Lumia $1', 'Nokia', 'Lumia $1'),
    DeviceParser('Windows Phone [^;]{1,30}; .{0,100}?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|)(?:NOKIA|Nokia)[^;]{0,200}; {0,2}(RM-\\d{3,})', None, 'Nokia $1', 'Nokia', '$1'),
    DeviceParser('(?:Windows Phone [^;]{1,30}; .{0,100}?IEMobile/[^;\\)]+[;\\)]|WPDesktop;) ?(?:ARM; ?Touch; ?|Touch; ?|)(?:NOKIA|Nokia)[^;]{0,200}; {0,2}(?:NOKIA ?|Nokia ?|LUMIA ?|[Ll]umia ?|)([^;\\)]+)', None, 'Nokia $1', 'Nokia', '$1'),
    DeviceParser('Windows Phone [^;]{1,30}; .{0,100}?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|)(?:Microsoft(?: Corporation|))[^;]{0,200}; {0,2}([^;,\\)]+)', None, 'Microsoft $1', 'Microsoft', '$1'),
    DeviceParser('Windows Phone [^;]{1,30}; .{0,100}?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?|)(?:SAMSUNG)[^;]{0,200}; {0,2}(?:SAMSUNG |)([^;,\\.\\)]+)', None, 'Samsung $1', 'Samsung', '$1'),
    DeviceParser('Windows Phone [^;]{1,30}; .{0,100}?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?|)(?:TOSHIBA|FujitsuToshibaMobileCommun)[^;]{0,200}; {0,2}([^;,\\)]+)', None, 'Toshiba $1', 'Toshiba', '$1'),
    DeviceParser('Windows Phone [^;]{1,30}; .{0,100}?IEMobile/[^;\\)]+[;\\)] ?(?:ARM; ?Touch; ?|Touch; ?|WpsLondonTest; ?|)([^;]{1,200}); {0,2}([^;,\\)]+)', None, '$1 $2', '$1', '$2'),
    DeviceParser('(?:^|; )SAMSUNG\\-([A-Za-z0-9\\-]{1,50}).{0,200} Bada/', None, 'Samsung $1', 'Samsung', '$1'),
    DeviceParser('\\(Mobile; ALCATEL ?(One|ONE) ?(Touch|TOUCH) ?([^;/]{1,100}?)(?:/[^;]{1,200}|); rv:[^\\)]{1,200}\\) Gecko/[^\\/]{1,200} Firefox/', None, 'Alcatel $1 $2 $3', 'Alcatel', 'One Touch $3'),
    DeviceParser('\\(Mobile; (?:ZTE([^;]{1,200})|(OpenC)); rv:[^\\)]{1,200}\\) Gecko/[^\\/]{1,200} Firefox/', None, 'ZTE $1$2', 'ZTE', '$1$2'),
    DeviceParser('\\(Mobile; ALCATEL([A-Za-z0-9\\-]+); rv:[^\\)]{1,200}\\) Gecko/[^\\/]{1,200} Firefox/[^\\/]{1,200} KaiOS/', None, 'Alcatel $1', 'Alcatel', '$1'),
    DeviceParser('\\(Mobile; LYF\\/([A-Za-z0-9\\-]{1,100})\\/.{0,100};.{0,100}rv:[^\\)]{1,100}\\) Gecko/[^\\/]{1,100} Firefox/[^\\/]{1,100} KAIOS/', None, 'LYF $1', 'LYF', '$1'),
    DeviceParser('\\(Mobile; Nokia_([A-Za-z0-9\\-]{1,100})_.{1,100}; rv:[^\\)]{1,100}\\) Gecko/[^\\/]{1,100} Firefox/[^\\/]{1,100} KAIOS/', None, 'Nokia $1', 'Nokia', '$1'),
    DeviceParser('Nokia(N[0-9]+)([A-Za-z_\\-][A-Za-z0-9_\\-]*)', None, 'Nokia $1', 'Nokia', '$1$2'),
    DeviceParser('(?:NOKIA|Nokia)(?:\\-| {0,2})(?:([A-Za-z0-9]+)\\-[0-9a-f]{32}|([A-Za-z0-9\\-]+)(?:UCBrowser)|([A-Za-z0-9\\-]+))', None, 'Nokia $1$2$3', 'Nokia', '$1$2$3'),
    DeviceParser('Lumia ([A-Za-z0-9\\-]+)', None, 'Lumia $1', 'Nokia', 'Lumia $1'),
    DeviceParser('\\(Symbian; U; S60 V5; [A-z]{2}\\-[A-z]{2}; (SonyEricsson|Samsung|Nokia|LG)([^;/]{1,100}?)\\)', None, '$1 $2', '$1', '$2'),
    DeviceParser('\\(Symbian(?:/3|); U; ([^;]{1,200});', None, 'Nokia $1', 'Nokia', '$1'),
    DeviceParser('BB10; ([A-Za-z0-9\\- ]+)\\)', None, 'BlackBerry $1', 'BlackBerry', '$1'),
    DeviceParser('Play[Bb]ook.{1,200}RIM Tablet OS', None, 'BlackBerry Playbook', 'BlackBerry', 'Playbook'),
    DeviceParser('Black[Bb]erry ([0-9]+);', None, 'BlackBerry $1', 'BlackBerry', '$1'),
    DeviceParser('Black[Bb]erry([0-9]+)', None, 'BlackBerry $1', 'BlackBerry', '$1'),
    DeviceParser('Black[Bb]erry;', None, 'BlackBerry', 'BlackBerry'),
    DeviceParser('(Pre|Pixi)/\\d+\\.\\d+', None, 'Palm $1', 'Palm', '$1'),
    DeviceParser('Palm([0-9]+)', None, 'Palm $1', 'Palm', '$1'),
    DeviceParser('Treo([A-Za-z0-9]+)', None, 'Palm Treo $1', 'Palm', 'Treo $1'),
    DeviceParser('webOS.{0,200}(P160U(?:NA|))/(\\d+).(\\d+)', None, 'HP Veer', 'HP', 'Veer'),
    DeviceParser('(Touch[Pp]ad)/\\d+\\.\\d+', None, 'HP TouchPad', 'HP', 'TouchPad'),
    DeviceParser('HPiPAQ([A-Za-z0-9]{1,20})/\\d+\\.\\d+', None, 'HP iPAQ $1', 'HP', 'iPAQ $1'),
    DeviceParser('PDA; (PalmOS)/sony/model ([a-z]+)/Revision', None, '$1', 'Sony', '$1 $2'),
    DeviceParser('(Apple\\s?TV)', None, 'AppleTV', 'Apple', 'AppleTV'),
    DeviceParser('(QtCarBrowser)', None, 'Tesla Model S', 'Tesla', 'Model S'),
    DeviceParser('(iPhone|iPad|iPod)(\\d+,\\d+)', None, '$1', 'Apple', '$1$2'),
    DeviceParser('(iPad)(?:;| Simulator;)', None, '$1', 'Apple', '$1'),
    DeviceParser('(iPod)(?:;| touch;| Simulator;)', None, '$1', 'Apple', '$1'),
    DeviceParser('(iPhone)(?:;| Simulator;)', None, '$1', 'Apple', '$1'),
    DeviceParser('(Watch)(\\d+,\\d+)', None, 'Apple $1', 'Apple', '$1$2'),
    DeviceParser('(Apple Watch)(?:;| Simulator;)', None, '$1', 'Apple', '$1'),
    DeviceParser('(HomePod)(?:;| Simulator;)', None, '$1', 'Apple', '$1'),
    DeviceParser('iPhone', None, 'iPhone', 'Apple', 'iPhone'),
    DeviceParser('CFNetwork/.{0,100} Darwin/\\d.{0,100}\\(((?:Mac|iMac|PowerMac|PowerBook)[^\\d]*)(\\d+)(?:,|%2C)(\\d+)', None, '$1$2,$3', 'Apple', '$1$2,$3'),
    DeviceParser('CFNetwork/.{0,100} Darwin/\\d+\\.\\d+\\.\\d+ \\(x86_64\\)', None, 'Mac', 'Apple', 'Mac'),
    DeviceParser('CFNetwork/.{0,100} Darwin/\\d', None, 'iOS-Device', 'Apple', 'iOS-Device'),
    DeviceParser('Outlook-(iOS)/\\d+\\.\\d+\\.prod\\.iphone', None, 'iPhone', 'Apple', 'iPhone'),
    DeviceParser('acer_([A-Za-z0-9]+)_', None, 'Acer $1', 'Acer', '$1'),
    DeviceParser('(?:ALCATEL|Alcatel)-([A-Za-z0-9\\-]+)', None, 'Alcatel $1', 'Alcatel', '$1'),
    DeviceParser('(?:Amoi|AMOI)\\-([A-Za-z0-9]+)', None, 'Amoi $1', 'Amoi', '$1'),
    DeviceParser('(?:; |\\/|^)((?:Transformer (?:Pad|Prime) |Transformer |PadFone[ _]?)[A-Za-z0-9]*)', None, 'Asus $1', 'Asus', '$1'),
    DeviceParser('(?:asus.{0,200}?ASUS|Asus|ASUS|asus)[\\- ;]*((?:Transformer (?:Pad|Prime) |Transformer |Padfone |Nexus[ _]|)[A-Za-z0-9]+)', None, 'Asus $1', 'Asus', '$1'),
    DeviceParser('(?:ASUS)_([A-Za-z0-9\\-]+)', None, 'Asus $1', 'Asus', '$1'),
    DeviceParser('\\bBIRD[ \\-\\.]([A-Za-z0-9]+)', None, 'Bird $1', 'Bird', '$1'),
    DeviceParser('\\bDell ([A-Za-z0-9]+)', None, 'Dell $1', 'Dell', '$1'),
    DeviceParser('DoCoMo/2\\.0 ([A-Za-z0-9]+)', None, 'DoCoMo $1', 'DoCoMo', '$1'),
    DeviceParser('^.{0,50}?([A-Za-z0-9]{1,30})_W;FOMA', None, 'DoCoMo $1', 'DoCoMo', '$1'),
    DeviceParser('^.{0,50}?([A-Za-z0-9]{1,30});FOMA', None, 'DoCoMo $1', 'DoCoMo', '$1'),
    DeviceParser('\\b(?:HTC/|HTC/[a-z0-9]{1,20}/|)HTC[ _\\-;]? {0,2}(.{0,200}?)(?:-?Mozilla|fingerPrint|[;/\\(\\)]|$)', None, 'HTC $1', 'HTC', '$1'),
    DeviceParser('Huawei([A-Za-z0-9]+)', None, 'Huawei $1', 'Huawei', '$1'),
    DeviceParser('HUAWEI-([A-Za-z0-9]+)', None, 'Huawei $1', 'Huawei', '$1'),
    DeviceParser('HUAWEI ([A-Za-z0-9\\-]+)', None, 'Huawei $1', 'Huawei', '$1'),
    DeviceParser('vodafone([A-Za-z0-9]+)', None, 'Huawei Vodafone $1', 'Huawei', 'Vodafone $1'),
    DeviceParser('i\\-mate ([A-Za-z0-9]+)', None, 'i-mate $1', 'i-mate', '$1'),
    DeviceParser('Kyocera\\-([A-Za-z0-9]+)', None, 'Kyocera $1', 'Kyocera', '$1'),
    DeviceParser('KWC\\-([A-Za-z0-9]+)', None, 'Kyocera $1', 'Kyocera', '$1'),
    DeviceParser('Lenovo[_\\-]([A-Za-z0-9]+)', None, 'Lenovo $1', 'Lenovo', '$1'),
    DeviceParser('(HbbTV)/[0-9]+\\.[0-9]+\\.[0-9]+ \\( ?;(LG)E ?;([^;]{0,30})', None, '$1', '$2', '$3'),
    DeviceParser('(HbbTV)/1\\.1\\.1.{0,200}CE-HTML/1\\.\\d;(Vendor/|)(THOM[^;]{0,200}?)[;\\s].{0,30}(LF[^;]{1,200});?', None, '$1', 'Thomson', '$4'),
    DeviceParser('(HbbTV)(?:/1\\.1\\.1|) ?(?: \\(;;;;;\\)|); {0,2}CE-HTML(?:/1\\.\\d|); {0,2}([^ ]{1,30}) ([^;]{1,200});', None, '$1', '$2', '$3'),
    DeviceParser('(HbbTV)/1\\.1\\.1 \\(;;;;;\\) Maple_2011', None, '$1', 'Samsung'),
    DeviceParser('(HbbTV)/[0-9]+\\.[0-9]+\\.[0-9]+ \\([^;]{0,30}; ?(?:CUS:([^;]{0,200})|([^;]{1,200})) ?; ?([^;]{0,30})', None, '$1', '$2$3', '$4'),
    DeviceParser('(HbbTV)/[0-9]+\\.[0-9]+\\.[0-9]+', None, '$1'),
    DeviceParser('LGE; (?:Media\\/|)([^;]{0,200});[^;]{0,200};[^;]{0,200};?\\); "?LG NetCast(\\.TV|\\.Media|)-\\d+', None, 'NetCast$2', 'LG', '$1'),
    DeviceParser('InettvBrowser/[0-9]{1,30}\\.[0-9A-Z]{1,30} \\([^;]{0,200};(Sony)([^;]{0,200});[^;]{0,200};[^\\)]{0,10}\\)', None, 'Inettv', '$1', '$2'),
    DeviceParser('InettvBrowser/[0-9]{1,30}\\.[0-9A-Z]{1,30} \\([^;]{0,200};([^;]{0,200});[^;]{0,200};[^\\)]{0,10}\\)', None, 'Inettv', 'Generic_Inettv', '$1'),
    DeviceParser('(?:InettvBrowser|TSBNetTV|NETTV|HBBTV)', None, 'Inettv', 'Generic_Inettv'),
    DeviceParser('Series60/\\d\\.\\d (LG)[\\-]?([A-Za-z0-9 \\-]+)', None, '$1 $2', '$1', '$2'),
    DeviceParser('\\b(?:LGE[ \\-]LG\\-(?:AX|)|LGE |LGE?-LG|LGE?[ \\-]|LG[ /\\-]|lg[\\-])([A-Za-z0-9]+)\\b', None, 'LG $1', 'LG', '$1'),
    DeviceParser('(?:^LG[\\-]?|^LGE[\\-/]?)([A-Za-z]+[0-9]+[A-Za-z]*)', None, 'LG $1', 'LG', '$1'),
    DeviceParser('^LG([0-9]+[A-Za-z]*)', None, 'LG $1', 'LG', '$1'),
    DeviceParser('(KIN\\.[^ ]+) (\\d+)\\.(\\d+)', None, 'Microsoft $1', 'Microsoft', '$1'),
    DeviceParser('(?:MSIE|XBMC).{0,200}\\b(Xbox)\\b', None, '$1', 'Microsoft', '$1'),
    DeviceParser('; ARM; Trident/6\\.0; Touch[\\);]', None, 'Microsoft Surface RT', 'Microsoft', 'Surface RT'),
    DeviceParser('Motorola\\-([A-Za-z0-9]+)', None, 'Motorola $1', 'Motorola', '$1'),
    DeviceParser('MOTO\\-([A-Za-z0-9]+)', None, 'Motorola $1', 'Motorola', '$1'),
    DeviceParser('MOT\\-([A-z0-9][A-z0-9\\-]*)', None, 'Motorola $1', 'Motorola', '$1'),
    DeviceParser('; (moto[ a-zA-z0-9()]{0,50});((?: Build|.{0,50}\\) AppleWebKit))', None, '$1', 'Motorola', '$1'),
    DeviceParser('; {0,2}(moto)(.{0,50})(?: Build|\\) AppleWebKit)', None, 'Motorola$2', 'Motorola', '$2'),
    DeviceParser('Nintendo WiiU', None, 'Nintendo Wii U', 'Nintendo', 'Wii U'),
    DeviceParser('Nintendo (Switch|DS|3DS|DSi|Wii);', None, 'Nintendo $1', 'Nintendo', '$1'),
    DeviceParser('(?:Pantech|PANTECH)[ _-]?([A-Za-z0-9\\-]+)', None, 'Pantech $1', 'Pantech', '$1'),
    DeviceParser('Philips([A-Za-z0-9]+)', None, 'Philips $1', 'Philips', '$1'),
    DeviceParser('Philips ([A-Za-z0-9]+)', None, 'Philips $1', 'Philips', '$1'),
    DeviceParser('(SMART-TV); .{0,200} Tizen ', None, 'Samsung $1', 'Samsung', '$1'),
    DeviceParser('SymbianOS/9\\.\\d.{0,200} Samsung[/\\-]([A-Za-z0-9 \\-]+)', None, 'Samsung $1', 'Samsung', '$1'),
    DeviceParser('(Samsung)(SGH)(i[0-9]+)', None, '$1 $2$3', '$1', '$2-$3'),
    DeviceParser('SAMSUNG-ANDROID-MMS/([^;/]{1,100})', None, '$1', 'Samsung', '$1'),
    DeviceParser('SAMSUNG(?:; |[ -/])([A-Za-z0-9\\-]+)', 'i', 'Samsung $1', 'Samsung', '$1'),
    DeviceParser('(Dreamcast)', None, 'Sega $1', 'Sega', '$1'),
    DeviceParser('^SIE-([A-Za-z0-9]+)', None, 'Siemens $1', 'Siemens', '$1'),
    DeviceParser('Softbank/[12]\\.0/([A-Za-z0-9]+)', None, 'Softbank $1', 'Softbank', '$1'),
    DeviceParser('SonyEricsson ?([A-Za-z0-9\\-]+)', None, 'Ericsson $1', 'SonyEricsson', '$1'),
    DeviceParser('Android [^;]{1,200}; ([^ ]+) (Sony)/', None, '$2 $1', '$2', '$1'),
    DeviceParser('(Sony)(?:BDP\\/|\\/|)([^ /;\\)]+)[ /;\\)]', None, '$1 $2', '$1', '$2'),
    DeviceParser('Puffin/[\\d\\.]+IT', None, 'iPad', 'Apple', 'iPad'),
    DeviceParser('Puffin/[\\d\\.]+IP', None, 'iPhone', 'Apple', 'iPhone'),
    DeviceParser('Puffin/[\\d\\.]+AT', None, 'Generic Tablet', 'Generic', 'Tablet'),
    DeviceParser('Puffin/[\\d\\.]+AP', None, 'Generic Smartphone', 'Generic', 'Smartphone'),
    DeviceParser('Android[\\- ][\\d]+\\.[\\d]+; [A-Za-z]{2}\\-[A-Za-z]{0,2}; WOWMobile (.{1,200})( Build[/ ]|\\))', None, None, 'Generic_Android', '$1'),
    DeviceParser('Android[\\- ][\\d]+\\.[\\d]+\\-update1; [A-Za-z]{2}\\-[A-Za-z]{0,2} {0,2}; {0,2}(.{1,200}?)( Build[/ ]|\\))', None, None, 'Generic_Android', '$1'),
    DeviceParser('Android[\\- ][\\d]+(?:\\.[\\d]+)(?:\\.[\\d]+|); {0,2}[A-Za-z]{2}[_\\-][A-Za-z]{0,2}\\-? {0,2}; {0,2}(.{1,200}?)( Build[/ ]|\\))', None, None, 'Generic_Android', '$1'),
    DeviceParser('Android[\\- ][\\d]+(?:\\.[\\d]+)(?:\\.[\\d]+|); {0,2}[A-Za-z]{0,2}\\- {0,2}; {0,2}(.{1,200}?)( Build[/ ]|\\))', None, None, 'Generic_Android', '$1'),
    DeviceParser('Android[\\- ][\\d]+(?:\\.[\\d]+)(?:\\.[\\d]+|); {0,2}[a-z]{0,2}[_\\-]?[A-Za-z]{0,2};?( Build[/ ]|\\))', None, 'Generic Smartphone', 'Generic', 'Smartphone'),
    DeviceParser('Android[\\- ][\\d]+(?:\\.[\\d]+)(?:\\.[\\d]+|); {0,3}\\-?[A-Za-z]{2}; {0,2}(.{1,50}?)( Build[/ ]|\\))', None, None, 'Generic_Android', '$1'),
    DeviceParser('Android \\d+?(?:\\.\\d+|)(?:\\.\\d+|); ([^;]{1,100}?)(?: Build|\\) AppleWebKit).{1,200}? Mobile Safari', None, None, 'Generic_Android', '$1'),
    DeviceParser('Android \\d+?(?:\\.\\d+|)(?:\\.\\d+|); ([^;]{1,100}?)(?: Build|\\) AppleWebKit).{1,200}? Safari', None, None, 'Generic_Android_Tablet', '$1'),
    DeviceParser('Android \\d+?(?:\\.\\d+|)(?:\\.\\d+|); ([^;]{1,100}?)(?: Build|\\))', None, None, 'Generic_Android', '$1'),
    DeviceParser('(GoogleTV)', None, None, 'Generic_Inettv', '$1'),
    DeviceParser('(WebTV)/\\d+.\\d+', None, None, 'Generic_Inettv', '$1'),
    DeviceParser('^(Roku)/DVP-\\d+\\.\\d+', None, None, 'Generic_Inettv', '$1'),
    DeviceParser('(Android 3\\.\\d|Opera Tablet|Tablet; .{1,100}Firefox/|Android.{0,100}(?:Tab|Pad))', 'i', 'Generic Tablet', 'Generic', 'Tablet'),
    DeviceParser('(Symbian|\\bS60(Version|V\\d)|\\bS60\\b|\\((Series 60|Windows Mobile|Palm OS|Bada); Opera Mini|Windows CE|Opera Mobi|BREW|Brew|Mobile; .{1,200}Firefox/|iPhone OS|Android|MobileSafari|Windows {0,2}Phone|\\(webOS/|PalmOS)', None, 'Generic Smartphone', 'Generic', 'Smartphone'),
    DeviceParser('(hiptop|avantgo|plucker|xiino|blazer|elaine)', 'i', 'Generic Smartphone', 'Generic', 'Smartphone'),
    DeviceParser('^.{0,100}(bot|BUbiNG|zao|borg|DBot|oegp|silk|Xenu|zeal|^NING|CCBot|crawl|htdig|lycos|slurp|teoma|voila|yahoo|Sogou|CiBra|Nutch|^Java/|^JNLP/|Daumoa|Daum|Genieo|ichiro|larbin|pompos|Scrapy|snappy|speedy|spider|msnbot|msrbot|vortex|^vortex|crawler|favicon|indexer|Riddler|scooter|scraper|scrubby|WhatWeb|WinHTTP|bingbot|BingPreview|openbot|gigabot|furlbot|polybot|seekbot|^voyager|archiver|Icarus6j|mogimogi|Netvibes|blitzbot|altavista|charlotte|findlinks|Retreiver|TLSProber|WordPress|SeznamBot|ProoXiBot|wsr\\-agent|Squrl Java|EtaoSpider|PaperLiBot|SputnikBot|A6\\-Indexer|netresearch|searchsight|baiduspider|YisouSpider|ICC\\-Crawler|http%20client|Python-urllib|dataparksearch|converacrawler|Screaming Frog|AppEngine-Google|YahooCacheSystem|fast\\-webcrawler|Sogou Pic Spider|semanticdiscovery|Innovazion Crawler|facebookexternalhit|Google.{0,200}/\\+/web/snippet|Google-HTTP-Java-Client|BlogBridge|IlTrovatore-Setaccio|InternetArchive|GomezAgent|WebThumbnail|heritrix|NewsGator|PagePeeker|Reaper|ZooShot|holmes|NL-Crawler|Pingdom|StatusCake|WhatsApp|masscan|Google Web Preview|Qwantify|Yeti|OgScrper|RecipeRadar|GPTBot|Google-InspectionTool)', 'i', 'Spider', 'Spider', 'Desktop'),
    DeviceParser('^(1207|3gso|4thp|501i|502i|503i|504i|505i|506i|6310|6590|770s|802s|a wa|acer|acs\\-|airn|alav|asus|attw|au\\-m|aur |aus |abac|acoo|aiko|alco|alca|amoi|anex|anny|anyw|aptu|arch|argo|bmobile|bell|bird|bw\\-n|bw\\-u|beck|benq|bilb|blac|c55/|cdm\\-|chtm|capi|comp|cond|dall|dbte|dc\\-s|dica|ds\\-d|ds12|dait|devi|dmob|doco|dopo|dorado|el(?:38|39|48|49|50|55|58|68)|el[3456]\\d{2}dual|erk0|esl8|ex300|ez40|ez60|ez70|ezos|ezze|elai|emul|eric|ezwa|fake|fly\\-|fly_|g\\-mo|g1 u|g560|gf\\-5|grun|gene|go.w|good|grad|hcit|hd\\-m|hd\\-p|hd\\-t|hei\\-|hp i|hpip|hs\\-c|htc |htc\\-|htca|htcg)', 'i', 'Generic Feature Phone', 'Generic', 'Feature Phone'),
    DeviceParser('^(htcp|htcs|htct|htc_|haie|hita|huaw|hutc|i\\-20|i\\-go|i\\-ma|i\\-mobile|i230|iac|iac\\-|iac/|ig01|im1k|inno|iris|jata|kddi|kgt|kgt/|kpt |kwc\\-|klon|lexi|lg g|lg\\-a|lg\\-b|lg\\-c|lg\\-d|lg\\-f|lg\\-g|lg\\-k|lg\\-l|lg\\-m|lg\\-o|lg\\-p|lg\\-s|lg\\-t|lg\\-u|lg\\-w|lg/k|lg/l|lg/u|lg50|lg54|lge\\-|lge/|leno|m1\\-w|m3ga|m50/|maui|mc01|mc21|mcca|medi|meri|mio8|mioa|mo01|mo02|mode|modo|mot |mot\\-|mt50|mtp1|mtv |mate|maxo|merc|mits|mobi|motv|mozz|n100|n101|n102|n202|n203|n300|n302|n500|n502|n505|n700|n701|n710|nec\\-|nem\\-|newg|neon)', 'i', 'Generic Feature Phone', 'Generic', 'Feature Phone'),
    DeviceParser('^(netf|noki|nzph|o2 x|o2\\-x|opwv|owg1|opti|oran|ot\\-s|p800|pand|pg\\-1|pg\\-2|pg\\-3|pg\\-6|pg\\-8|pg\\-c|pg13|phil|pn\\-2|pt\\-g|palm|pana|pire|pock|pose|psio|qa\\-a|qc\\-2|qc\\-3|qc\\-5|qc\\-7|qc07|qc12|qc21|qc32|qc60|qci\\-|qwap|qtek|r380|r600|raks|rim9|rove|s55/|sage|sams|sc01|sch\\-|scp\\-|sdk/|se47|sec\\-|sec0|sec1|semc|sgh\\-|shar|sie\\-|sk\\-0|sl45|slid|smb3|smt5|sp01|sph\\-|spv |spv\\-|sy01|samm|sany|sava|scoo|send|siem|smar|smit|soft|sony|t\\-mo|t218|t250|t600|t610|t618|tcl\\-|tdg\\-|telm|tim\\-|ts70|tsm\\-|tsm3|tsm5|tx\\-9|tagt)', 'i', 'Generic Feature Phone', 'Generic', 'Feature Phone'),
    DeviceParser('^(talk|teli|topl|tosh|up.b|upg1|utst|v400|v750|veri|vk\\-v|vk40|vk50|vk52|vk53|vm40|vx98|virg|vertu|vite|voda|vulc|w3c |w3c\\-|wapj|wapp|wapu|wapm|wig |wapi|wapr|wapv|wapy|wapa|waps|wapt|winc|winw|wonu|x700|xda2|xdag|yas\\-|your|zte\\-|zeto|aste|audi|avan|blaz|brew|brvw|bumb|ccwa|cell|cldc|cmd\\-|dang|eml2|fetc|hipt|http|ibro|idea|ikom|ipaq|jbro|jemu|jigs|keji|kyoc|kyok|libw|m\\-cr|midp|mmef|moto|mwbp|mywa|newt|nok6|o2im|pant|pdxg|play|pluc|port|prox|rozo|sama|seri|smal|symb|treo|upsi|vx52|vx53|vx60|vx61|vx70|vx80|vx81|vx83|vx85|wap\\-|webc|whit|wmlb|xda\\-|xda_)', 'i', 'Generic Feature Phone', 'Generic', 'Feature Phone'),
    DeviceParser('^(Ice)$', None, 'Generic Feature Phone', 'Generic', 'Feature Phone'),
    DeviceParser('(wap[\\-\\ ]browser|maui|netfront|obigo|teleca|up\\.browser|midp|Opera Mini)', 'i', 'Generic Feature Phone', 'Generic', 'Feature Phone'),
    DeviceParser('Mac OS', None, 'Mac', 'Apple', 'Mac'),
]
