diff -Nru ruby-browser-2.5.3/bin/rake ruby-browser-4.2.0/bin/rake --- ruby-browser-2.5.3/bin/rake 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/bin/rake 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true -# -# This file was generated by Bundler. -# -# The application 'rake' is installed as part of a gem, and -# this file is here to facilitate running it. -# - -require "pathname" -ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", - Pathname.new(__FILE__).realpath) - -require "rubygems" -require "bundler/setup" - -load Gem.bin_path("rake", "rake") diff -Nru ruby-browser-2.5.3/bot_exceptions.yml ruby-browser-4.2.0/bot_exceptions.yml --- ruby-browser-2.5.3/bot_exceptions.yml 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/bot_exceptions.yml 2020-06-19 05:24:10.000000000 +0000 @@ -1,3 +1,5 @@ +--- - ruby build - pinterest/android - pinterest/ios +- yandexsearchbrowser diff -Nru ruby-browser-2.5.3/bots.yml ruby-browser-4.2.0/bots.yml --- ruby-browser-2.5.3/bots.yml 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/bots.yml 2020-06-19 05:24:10.000000000 +0000 @@ -1,267 +1,305 @@ -200pleasebot: "200PleaseBot" -360spider: "360Spider" -abot: "CrawlDaddy, abot" -addthis: "AddThis" -adldxbot: "Microsoft Bing Ads" -admantx: "ADmantX Platform Semantic Analyzer" -adsbot-google: "Google Adwords" -advbot: "AdvBot" -ahrefsbot: "Ahrefs backlinks research tool" -alexa: "Alexa Crawler" -anderspink: "AndersPinkBot" -apache-httpclient: "Java http library" -apachebench: "ApacheBench (ab)" +--- +200pleasebot: 200PleaseBot +360spider: 360Spider +abot: CrawlDaddy, abot +addthis: AddThis +adldxbot: Microsoft Bing Ads +admantx: ADmantX Platform Semantic Analyzer +adsbot-google: Google Adwords +adstxtcrawler: AdsTxtCrawler +advbot: AdvBot +ahrefsbot: Ahrefs backlinks research tool +alexa: Alexa Crawler +anderspink: AndersPinkBot +apache-httpclient: Java http library +apachebench: ApacheBench (ab) apis-google: APIs-Google -appengine-google: "Google App Engine" -applebot: "Apple Bot" -archive.org_bot: "Internet Archive (archive.org)" -ask jeeves: "Ask Jeeves" -asynchttpclient: "Java http and WebSocket client library" -awe.sm: "Awe.sm URL expander" -baidu: "Baidu" -barkrowler: "Barkrowler" -bdcbot: "Big Data Corp" -bingbot: "Microsoft Bing" -bingpreview: "Microsoft Bing preview" -bitlybot: "bit.ly bot" -blekkobot: "Blekkobot" -blexbot: "BLEXBot (webmeup)" -bot@linkfluence.net: "Linkfluence bot" -bubing: "BUbiNG" -bufferbot: "BufferBot" -buibui-checkbot: "buibui" -butterfly: "Topsy Labs" -buzzbot: "Buzzbot" -buzztalk: "buzztalk" -catchbot: "CatchBot (catchbot.com)" -check_http: "Nagios monitor" -cipacrawler: "CipaCrawler" -cliqzbot: "Cliqzbot" -cloudflare: "CloudFlare-AlwaysOnline" -cmradar/0.1: "CMRadar/0.1" -coldfusion: "ColdFusion http library" -commoncrawl: "CCBot" -comodo ssl checker: 'COMODO SSL Checker' -comodo-webinspector-crawler: "Comodo" -copypants: "BotPants" -crowsnest: "Crowsnest" -curabot: "cura.yt" -curl: "curl unix CLI http client" -dap/nethttp: "DAP/NetHTTP" -datagnionbot: "datagnion.com/bot.html" -daumoa: "Korean portal and search engine indexing bot" -developers.google.com/+/web/snippet/: "Google Plus" -diffbot: "Diffbot" -digitalpersona fingerprint software: "HP Fingerprint scanner" -domain re-animator bot: "Domain Re-Animator Bot" -domainsbot: "DomainsBot" -domaintunocrawler: "DomainTuno" -dotbot: "Dot Bot" -duckduck: "Duck Duck Go" -elb-healthchecker: "AWS ELB HealthChecker" -embedly: "Embedly" -eoaagent: "EOAAgent" -eventmachine httpclient: "Ruby http library" -everyonesocialbot: "EveryoneSocial" -evrinid: "Evri bot" -exabot: "Exalead's bot" -exaleadcloudview: "ExaleadCloudView" -facebookexternalhit: "Facebook Bot" -facebot: "Facebook Bot" -feedburner: "RSS bot" -feedfetcher-google: "Google Feedfetcher" -findxbot: "Findxbot" -flipboardproxy: "FlipboardProxy" -friendfeedbot: "FriendFeed" -genieo: "Genieo Web filter bot" -getprismatic.com: "getprismatic.com" -gigabot: "Gigabot spider" -gimme60bot: "Gimme60 (gimme60.com)" -gimmeusabot: "Gimme60 (gimme60.com)" -go http package: "Go http library" -google page speed insights: "Google Page Speed Insights" -google Web Preview: "Google Instant Previews crawler" -google-site-verification: Google-Site-Verification -google-structured-data-testing-tool: "Google-StructuredDataTestingTool" -google-structureddatatestingtool: "Google-StructuredDataTestingTool" -googlebot: "Google Bot" -googlestackdrivermonitoring-uptimechecks: "GoogleStackdriverMonitoring-UptimeChecks" -grapeshotcrawler: "GrapeshotCrawler" -gravitybot: "Gravity Bot" -hatena::bookmark: "Hatena::Bookmark" -heritrix: "heritrix" -htmlparser: "HTMLParser" -http_request2: "HTTP_Request2" -httpclient: "HTTPClient" -https://developers.google.com/+/web/snippet: "Google+ Snippet Fetcher" -hubspot: "HubSpot" -ia_archiver: "Internet Archive (WayBackMachine)" -icoreservice: "iCoreService" -idmarch: "idmarch.org/bot.html" -inagist: "URL resolver" -insieve: "Insieve Bot" -insitesbot: "Insitesbot" -instapaper: "Instapaper" -istellabot: "IstellaBot" -jack: "jack" -jakarta commons: "Jakarta Commons HttpClient" -java: "Generic Java http library" -jetslide: "Jetslide" -jobseeker: "jobseeker.com.au/bot.html" -js-kit: "URL resolver" -kemvibot: "Kemvi" -kimengi: "Kimengi Bot" -knows.is: "knows.is" -kojitsubot: "Kojitsubot" -komodiabot: "KomodiaBot" -kraken: "kraken" -laconica: "Laconica" -libwww-perl: "Perl client-server library" -lijit crawler: "Lijit" -linkdexbot: "Linkdex Bot" -linkedinbot: "LinkedIn" -linkscrawler: "LinksCrawler" -linode: "Linode Longview" -lipperhey: "Lipperhey" -livelapbot: "Livelapbot" -loadtimebot: "Load Time Bot" -longurl: "URL expander service" -ltx71: "ltx71.com" -lumibot: "Lumibot" -lwp-trivial: "Another Perl library" -magpie-crawler: "magpie-crawler" -mail.ru_bot: "Mail.ru Bot" -mappydata: "Mappy" -meanpathbot: "meanpath" -mediapartners-google: "Google Adsense bot" -megaindex.ru: "MegaIndex" -memorybot: "mignify.com/bot.html" -metauri: "MetaURI" -mfe_expand: "Mcafee spider" -mir web crawler: "MIR web crawler" -mj12bot: "Majestic-12 spider" -mojeekbot: "Mojeek UK search crawler" -mrchrome: "MrChrome" -ms search 6.0 robot: "MS Search 6.0 Robot" -msnbot-media: "Microsoft media bot" -msnbot: "Microsoft bot" -nerdybot: "NerdyBot" -netcraft: "Netcraft" -netstate: "netEstate NE Crawler" -netvibes: "Personalized dashboard bot" -netzcheckbot: "netzcheck" -newrelicmonitor: "NewRelic monitor" -newrelicpinger: "NewRelicPinger" -newsme: "newsme" -niki-bot: "niki-bot" -ning: "NING - Yet Another Twitter Swarmer" -nutch: "Apache search spider" -openhosebot: "OpenHoseBot" -orangebot: "OrangeBot" -paessler: "paessler.com - PRTG Network Monitor" -pagesinventory: "pagesinventory.com" -panopta: "Monitoring service" -paperlibot: "PaperLi" -peerindex: "peerindex" -percolatecrawler: "PercolateCrawler" -perfectmarketkwtbot: "PerfectMarket" -phantomjs: "PhantomJS" -pingdom: "Pingdom monitoring" -pinterest: "Pinterest" -plukkie: "botje.com/plukkie.htm" -privacyawarebot: "PrivacyAwareBot" -proximic: "Proximic Spider" -psbot-page: "Picsearch" -publiclibraryarchive.org: "publiclibraryarchive.org" -pycurl: "Python http library" -python-httplib2: "Python-httplib2" -python-requests: "Python http library" -python-urllib: "Python http library" -queryseeker: "QuerySeekerSpider" -quicklook: "QuickLook" -re-animator: "Domain Re-Animator Bot" -readability: "Readability" -rebelmouse: "RebelMouse" -redditbot: "Reddit Bot" -relateiq: "RelateIQ" -riddler: "Riddler Bot" -rogerbot: "SeoMoz spider" -rssmicro: "RSS/Atom Feed Robot (rssmicro.com)" -ruby: "Ruby" -scrapy: "Scrapy" +appengine-google: Google App Engine +applebot: Apple Bot +archive.org_bot: Internet Archive (archive.org) +archiveteam archivebot: ArchiveTeam ArchiveBot +ask jeeves: Ask Jeeves +asynchttpclient: Java http and WebSocket client library +awe.sm: Awe.sm URL expander +baidu: Baidu +barkrowler: Barkrowler +bdcbot: Big Data Corp +bingbot: Microsoft Bing +bingpreview: Microsoft Bing preview +bitlybot: bit.ly bot +blekkobot: Blekkobot +blexbot: BLEXBot (webmeup) +bot@linkfluence.net: Linkfluence bot +bubing: BUbiNG +bufferbot: BufferBot +buibui-checkbot: buibui +butterfly: Topsy Labs +buzzbot: Buzzbot +buzztalk: buzztalk +catchbot: CatchBot (catchbot.com) +check_http: Nagios monitor +chrome-lighthouse: Chrome-Lighthouse +cipacrawler: CipaCrawler +cliqzbot: Cliqzbot +cloudflare: CloudFlare-AlwaysOnline +cmradar/0.1: CMRadar/0.1 +coldfusion: ColdFusion http library +commoncrawl: CCBot +comodo ssl checker: COMODO SSL Checker +comodo-webinspector-crawler: Comodo +copypants: BotPants +crowsnest: Crowsnest +curabot: cura.yt +curl: curl unix CLI http client +dap/nethttp: DAP/NetHTTP +datafeedwatch: DataFeedWatch +datagnionbot: datagnion.com/bot.html +datanyze: Datanyze +daumoa: Korean portal and search engine indexing bot +developers.google.com/+/web/snippet/: Google Plus +diffbot: Diffbot +digitalpersona fingerprint software: HP Fingerprint scanner +domain re-animator bot: Domain Re-Animator Bot +domainsbot: DomainsBot +domaintunocrawler: DomainTuno +dotbot: Dot Bot +duckduck: Duck Duck Go +elb-healthchecker: AWS ELB HealthChecker +embedly: Embedly +eoaagent: EOAAgent +everyonesocialbot: EveryoneSocial +evrinid: Evri bot +exabot: Exalead's bot +exaleadcloudview: ExaleadCloudView +ez publish: eZ Publish Link Validator +facebookexternalhit: Facebook Bot +facebot: Facebook Bot +feedburner: RSS bot +feedfetcher-google: Google Feedfetcher +findxbot: Findxbot +flipboardproxy: FlipboardProxy +friendfeedbot: FriendFeed +fyrebot: Fyrebot +garlik: GarlikCrawler +genieo: Genieo Web filter bot +germcrawler: GermCrawler +getprismatic.com: getprismatic.com +gigabot: Gigabot spider +gimme60bot: Gimme60 (gimme60.com) +gimmeusabot: Gimme60 (gimme60.com) +go http package: Go http library +go-http-client: Go http client +google page speed insights: Google Page Speed Insights +google web preview: Google Instant Previews crawler +google-site-verification: Google Site Verification +google-structured-data-testing-tool: Google Structured Data Testing Tool +google-structureddatatestingtool: Google Structured Data Testing Tool +google-xrawler: Google Shopping +googlebot: Google Bot +googleimageproxy: Google Image Proxy +googlestackdrivermonitoring-uptimechecks: Google Stackdriver Monitoring - Uptime Checks +grapeshotcrawler: GrapeshotCrawler +gravitybot: Gravity Bot +hatena::bookmark: Hatena::Bookmark +heritrix: heritrix +https://developers.google.com/+/web/snippet: Google+ Snippet Fetcher +httrack: HTTrack +hubspot: HubSpot +ia_archiver: Internet Archive (WayBackMachine) +icoreservice: iCoreService +idmarch: idmarch.org/bot.html +implisensebot: ImplisenseBot +inagist: URL resolver +insieve: Insieve Bot +insitesbot: Insitesbot +instapaper: Instapaper +istellabot: IstellaBot +jaunt: Jaunt - Java Web Scraping & JSON Querying +jetslide: Jetslide +jobseeker: jobseeker.com.au/bot.html +jooble: Jooble +js-kit: URL resolver +kemvibot: Kemvi +kimengi: Kimengi Bot +knows.is: knows.is +kojitsubot: Kojitsubot +komodiabot: KomodiaBot +kraken: kraken +laconica: Laconica +lijit crawler: Lijit +linkdexbot: Linkdex Bot +linkedinbot: LinkedIn +linkscrawler: LinksCrawler +linode: Linode Longview +lipperhey: Lipperhey +livelapbot: Livelapbot +loadtimebot: Load Time Bot +longurl: URL expander service +ltx71: ltx71.com +lumibot: Lumibot +magpie-crawler: magpie-crawler +mail.ru_bot: Mail.ru Bot +mappydata: Mappy +mastodon: Mastodon URL expander +mauibot: MauiBot +meanpathbot: meanpath +mediapartners-google: Google Adsense bot +megaindex.ru: MegaIndex +memorybot: mignify.com/bot.html +metauri: MetaURI +mfe_expand: Mcafee spider +mir web crawler: MIR web crawler +mj12bot: Majestic-12 spider +mojeekbot: Mojeek UK search crawler +ms search 6.0 robot: MS Search 6.0 Robot +msnbot-media: Microsoft media bot +msnbot: Microsoft bot +nerdybot: NerdyBot +netcraft: Netcraft +netstate: netEstate NE Crawler +netvibes: Personalized dashboard bot +netzcheckbot: netzcheck +newrelicmonitor: NewRelic monitor +newrelicpinger: NewRelicPinger +newsme: newsme +niki-bot: niki-bot +ning: NING - Yet Another Twitter Swarmer +nutch: Apache search spider +openhosebot: OpenHoseBot +orangebot: OrangeBot +paessler: paessler.com - PRTG Network Monitor +pagesinventory: pagesinventory.com +panopta: Monitoring service +paperlibot: PaperLi +peerindex: peerindex +percolatecrawler: PercolateCrawler +perfectmarketkwtbot: PerfectMarket +phantomjs: PhantomJS +pingdom: Pingdom monitoring +pinterest: Pinterest +plukkie: botje.com/plukkie.htm +pr-cy.ru: PR-CY.RU +privacyawarebot: PrivacyAwareBot +proximic: Proximic Spider +psbot-page: Picsearch +pu_in: Pu_iN Crawler +publiclibraryarchive.org: publiclibraryarchive.org +pycurl: Python http library +python-httplib2: Python-httplib2 +python-requests: Python http library +python-urllib: Python http library +queryseeker: QuerySeekerSpider +quick-crawler: Quick-Crawler +quicklook: QuickLook +re-animator: Domain Re-Animator Bot +readability: Readability +rebelmouse: RebelMouse +redditbot: Reddit Bot +relateiq: RelateIQ +riddler: Riddler Bot +rogerbot: SeoMoz spider +rssmicro: RSS/Atom Feed Robot (rssmicro.com) +scouturlmonitor: ScoutURLMonitor +scrapy: Scrapy screaming frog seo spider: Screaming Frog SEO Spider -searchmetricsbot: "SearchmetricsBot" -semanticbot: "Semanticbot" -semrushbot: "SEO analysis bot" -seo-audit: "seo-audit-check-bot" -seodiver: "SEOdiver" -seokicks: "SEOKicks" -seznambot: "SeznamBot" -shopwiki: "ShopWiki" -shortlinktranslate: "Link shortener" -showyoubot: "Showyou iOS app spider" -siege: "Joe Dog Siege" -sistrix: "SISTRIX" -siteuptime: "Site monitoring services" -slack: "Slackbot-LinkExpanding" -slackbot: "Slack Bot" -slurp: "Yahoo spider" -smtbot: "SimilarTech" -socialrank: "SocialRankIOBot" -sogou: "Chinese search engine" -spbot: "OpenLinkProfiler" -spider: "generic web spider" -spinn3r: "Spinn3r aggregator" -sputnikbot: "SputnikBot" -squider: "Squider" -statuscake: "StatusCake" -stripe: "Stripe" -swiftbot: "Swiftype Bot" -teeraid: "TeeRaidBot" -test certificate info: "C http library?" -tineye: "TinEye Bot" -traackr: "Traackr Bot" -trendictionbot: "Trendiction Search" -turnitinbot: "TurnitinBot" -tweetedtimes: "The Tweeted Times" -tweetmemebot: "TweetMeMe Crawler" -twikle: "Social web search bot" -twitjobsearch: "TwitJobSearch" -twitmunin: "Twitmunin" -twitterbot: "Twitter URL expander" -twurly: "Twurly" -typhoeus: "Typhoeus" -umbot: "uberMetrics" -unwindfetch: "Gnip" -uptimerobot: "Uptime Robot" -vagabondo: "Vagabondo" -vb project: "Visual Basic" -vigil: "Vigil" -vkshare: "VKontake Sharer" -voilabot: "VoilaBot" -vrcrawler: "Venture Radar" -wasalive-bot: "Wasalive Bots" -watchsumo: "WatchSumo" -wbsearchbot: "Ware Bay Best Buys" -webceo: "online-webceo-bot" -webscout: "Webscout" -wesee: "WeSEE" -wget: "wget unix CLI http client" -whatsapp: "WhatsApp" -wordpress: "WordPress spider" -woriobot: "woriobot" -wormly: "WormlyBot" -wotbox: "Wotbox" -xenu link sleuth: "Xenu Link Sleuth" -xing-contenttabreceiver: "Xing bot" -xovibot: "XoviBot" -yacybot: "YaCy" -yahoo-ad-monitoring: "Yahoo Ad monitoring" -yandex: "Yandex" -yanga: "Yanga WorldSearch Bot" -yeti: "Naver Corp" -yourls: "YOURLS" -zelist.ro: "feed parser" -zibb: "ZIBB spider" -zitebot: "Zite" -zyborg: "Zyborg" +searchmetricsbot: SearchmetricsBot +semanticbot: Semanticbot +semrushbot: SEO analysis bot +seo-audit: seo-audit-check-bot +seobilitybot: SeobilityBot +seodiver: SEOdiver +seokicks: SEOKicks +seznambot: SeznamBot +shopwiki: ShopWiki +shortlinktranslate: Link shortener +showyoubot: Showyou iOS app spider +siege: Joe Dog Siege +sistrix: SISTRIX +sitecheck: SiteCheck sitecrawl +siteuptime: Site monitoring services +skypeuripreview: SkypeUriPreview +slack-imgproxy: Slack Image Proxy +slack-linkexpanding: Slack Link Expanding +slack: Slack Link Expanding +slackbot: Slackbot +slurp: Yahoo spider +smtbot: SimilarTech +snapchat: Snapchat +socialrank: SocialRankIOBot +sogou: Chinese search engine +spbot: OpenLinkProfiler +spinn3r: Spinn3r aggregator +sputnikbot: SputnikBot +squider: Squider +statuscake: StatusCake +stripe: Stripe +swiftbot: Swiftype Bot +tangibleebot: TangibleeBot +teeraid: TeeRaidBot +test certificate info: C http library? +the knowledge ai: Knowledge AI Bot +tineye: TinEye Bot +traackr: Traackr Bot +trendictionbot: Trendiction Search +trendsmap: Trendsmap Resolver +turnitinbot: TurnitinBot +tweetedtimes: The Tweeted Times +tweetmemebot: TweetMeMe Crawler +twikle: Social web search bot +twitjobsearch: TwitJobSearch +twitmunin: Twitmunin +twitterbot: Twitter URL expander +twurly: Twurly +typhoeus: Typhoeus +umbot: uberMetrics +unwindfetch: Gnip +updown: Updown.io monitor +uptimerobot: Uptime Robot +vagabondo: Vagabondo +vb project: Visual Basic +vigil: Vigil +vkshare: VKontake Sharer +voilabot: VoilaBot +vrcrawler: Venture Radar +wasalive-bot: Wasalive Bots +watchsumo: WatchSumo +wbsearchbot: Ware Bay Best Buys +webceo: online-webceo-bot +webscout: Webscout +wesee: WeSEE +wget: wget unix CLI http client +whatsapp: WhatsApp +wikido: WikiDo +woorank: WooRank +wordpress: WordPress spider +woriobot: woriobot +wormly: WormlyBot +wotbox: Wotbox +xenu link sleuth: Xenu Link Sleuth +xing-contenttabreceiver: Xing bot +xovibot: XoviBot +yacybot: YaCy +yahoo-ad-monitoring: Yahoo Ad monitoring +yandex: Yandex +yanga: Yanga WorldSearch Bot +yeti: Naver Corp +yourls: YOURLS +zabbix: Zabbix +zelist.ro: feed parser +zibb: ZIBB spider +zitebot: Zite +zoombot: ZoomBot +zoominfobot: ZoominfoBot +zyborg: Zyborg + +# Generic lib user agents go here. +eventmachine httpclient: Ruby http library +go 1.1 package http: Go 1.1 package http +htmlparser: HTMLParser +http_request2: HTTP_Request2 +httpclient: HTTPClient +jakarta commons: Jakarta Commons HttpClient +java: Generic Java http library +libwww-perl: Perl client-server library +lwp-trivial: Another Perl library +ruby: Ruby diff -Nru ruby-browser-2.5.3/browser.gemspec ruby-browser-4.2.0/browser.gemspec --- ruby-browser-2.5.3/browser.gemspec 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/browser.gemspec 2020-06-19 05:24:10.000000000 +0000 @@ -1,17 +1,20 @@ +# frozen_string_literal: true + require "./lib/browser/version" Gem::Specification.new do |s| - s.required_ruby_version = ">= 2.0" s.name = "browser" s.version = Browser::VERSION s.platform = Gem::Platform::RUBY s.authors = ["Nando Vieira"] s.email = ["fnando.vieira@gmail.com"] - s.homepage = "http://github.com/fnando/browser" + s.homepage = "https://github.com/fnando/browser" s.summary = "Do some browser detection with Ruby." s.description = s.summary s.license = "MIT" + s.metadata["changelog_uri"] = "https://github.com/fnando/browser/blob/master/CHANGELOG.md" + s.files = `git ls-files`.split("\n") s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") s.executables = `git ls-files -- exe/*` @@ -20,13 +23,14 @@ s.require_paths = ["lib"] s.add_development_dependency "bundler", ">= 0" - s.add_development_dependency "rake" - s.add_development_dependency "rails" - s.add_development_dependency "rack-test" s.add_development_dependency "minitest" + s.add_development_dependency "minitest-autotest" s.add_development_dependency "minitest-utils" s.add_development_dependency "pry-meta" - s.add_development_dependency "minitest-autotest" - s.add_development_dependency "codeclimate-test-reporter" + s.add_development_dependency "rack-test" + s.add_development_dependency "rails" + s.add_development_dependency "rake" s.add_development_dependency "rubocop" + s.add_development_dependency "rubocop-fnando", "~> 0.0.3" + s.add_development_dependency "simplecov" end diff -Nru ruby-browser-2.5.3/.bundle/config ruby-browser-4.2.0/.bundle/config --- ruby-browser-2.5.3/.bundle/config 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/.bundle/config 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ ---- -BUNDLE_BIN: bin diff -Nru ruby-browser-2.5.3/CHANGELOG.md ruby-browser-4.2.0/CHANGELOG.md --- ruby-browser-2.5.3/CHANGELOG.md 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/CHANGELOG.md 2020-06-19 05:24:10.000000000 +0000 @@ -1,5 +1,117 @@ # Changelog +## Unreleased + +- Fix Chrome Lighthouse detection. +- Add Skype to bot list. + +## 4.1.0 + +- Add Samsung browser. +- Add Google Image Proxy to the bot list. +- Add The Knowledge AI bot to the bot list. +- Add Go HttpClient to the bot list. +- Fix Microsoft Edge detection on Android and iOS. +- Fix MicroMessenger detection on Android + +## 4.0.0 + +- Add Chrome Lighthouse to bot list. +- Add SeobilityBot to the bot list. +- Detect Mac-based platforms differently, depending on the version; "Mac OS X" + will be returned for versions prior to 10.12, and "macOS" for newer versions. +- Remove `Browser.modern_rules` and `Browser::Base#modern?`. +- Add DuckDuckGo browser. + +# 3.0.3 + +- Deprecate `Browser.modern_rules` and `Browser::Base#modern?`. Theses methods + will be removed on the next major released, or by June 1st 2020. + +## 3.0.2 + +- Remove .bundle directory from package. + +## 3.0.1 + +- Fix issue with MS Edge detection as a modern browser. + +## 3.0.0 + +- Add ArchiveTeam's ArchiveBot to the bot list. +- Fix QQ Browser detection. +- Update modern rules. +- You can now define new bot matchers by adding a callable object to + `Browser::Bot.matchers`. +- Fix `browser.yandex?` and `browser.sputnik?`. +- [BREAKING CHANGE] Removed methods to enable the bot's empty user agent + detection (`Browser::Bot.detect_empty_ua!` and + `Browser::Bot.detect_empty_ua?`). +- [BREAKING CHANGE] Bot detection is now more aggressive by default. It matches + empty user agents, anything that matches + `crawl|fetch|search|monitoring|spider|bot`, and anything listed under + https://github.com/fnando/browser/blob/master/bots.yml. +- Add Jaunt to the bot list. + +## 2.7.1 + +- Handle Snapchat user agents that have a space or an empty string instead of a + slash before the version. +- Fix iOS 10+ version detection. +- Add fallback versions for instagram and snapchat to avoid NoMethodErrors on + unexpected user agents. + +## 2.7.0 + +- Add more Slack bots. +- Handle instagram user agents that have a slash instead of a space. +- Add `Browser::Bot.why?(ua)` to help debugging why a user agent is considered + bot. +- Promote Snapchat to a browser (it was detected as a bot previously). +- Detect Edge based on Chrome correctly. +- Improve Yandex detection. +- Add Sputnik (https://browser.sputnik.ru) +- Detect Android devices. +- Add ScoutURLMonitor to the bot list. + +## 2.6.1 + +- Also include controller extensions to `ActionController::Base`. + +## 2.6.0 + +- Add GarlikCrawler, ImplisenseBot and WikiDo bots. +- Add Mastodon URL expander bot. +- Add eZ Publish Link Validator, GermCrawler, Pu_iN Crawler, ZoomBot, and + ZoominfoBot bots. +- Add Datanyze bot. +- Add support for Instagram in-app browser. +- Add Updown.io monitor bot. +- Add Snapshat detection. +- Add Instagram detection. +- Add Nintendo Switch detection. +- Add WooRank bot. +- Add Trendsmap bot. +- Add Go 1.1 package http bot. +- Add MauiBot. +- Add SiteCheck-sitecrawl bot. +- Add PR-CY.RU bot. +- Add AdsTxtCrawler bot. +- Add HTTrack bot. +- Add Google Shopping bot. +- Add DataFeedWatch bot. +- Add Zabbix bot. +- Add TangibleeBot. +- Add Jooble bot. +- Add Fyre bot. +- Drop Rails 4 official support. +- Fix accept-language sorting (If HTTP-header has value `en,fr`—without + qualities—the first language should be `en` instead of `fr`). +- Ignore malformed strings when comparing versions. +- Fix Facebook detection on newer apps. +- Change precedence for bot detection when common libs are used. +- Add Yandex's search browser to the exception list. + ## v2.5.3 - Add Google Site Verification to the bot list. @@ -40,8 +152,10 @@ - Add Google Drive API, Proximic Spider, NewRelic pinger and SocialRank bots. - Add Pinboard in-app browser to the bot exception list. - All browser detection methods can now compare versions. -- All platform detection methods can now compare versions (except `#linux?` and `#firefox_os?`). -- Add `browser/aliases`, so you can have methods on the base object (e.g. `browser.mobile?`). See README for instructions. +- All platform detection methods can now compare versions (except `#linux?` and + `#firefox_os?`). +- Add `browser/aliases`, so you can have methods on the base object (e.g. + `browser.mobile?`). See README for instructions. - Remove official support for Rails 3 and Ruby 2.1. ## v2.3.0 @@ -72,7 +186,8 @@ ## v2.0.3 -- Fix issue with version detection when no actual version is provided (i.e. the user agent doesn't have any version information). +- Fix issue with version detection when no actual version is provided (i.e. the + user agent doesn't have any version information). ## v2.0.2 @@ -85,9 +200,12 @@ ## v2.0.0 -- `Browser#platform` now returns instance of `Browser::Platform`, instead of a `String`. It contains information about the platform (software). -- `Browser#device` was added. It returns information about the device (hardware). -- `Browser#accept_language` now returns a list of `Browser::AcceptLanguage` objects. +- `Browser#platform` now returns instance of `Browser::Platform`, instead of a + `String`. It contains information about the platform (software). +- `Browser#device` was added. It returns information about the device + (hardware). +- `Browser#accept_language` now returns a list of `Browser::AcceptLanguage` + objects. - `Browser#bot` now returns a `Browser::Bot` instance. - Safari running as web app mode is not recognized as Safari anymore. - ruby-2.3+ will always activate frozen strings. diff -Nru ruby-browser-2.5.3/debian/changelog ruby-browser-4.2.0/debian/changelog --- ruby-browser-2.5.3/debian/changelog 2018-09-21 17:49:10.000000000 +0000 +++ ruby-browser-4.2.0/debian/changelog 2020-08-18 14:51:43.000000000 +0000 @@ -1,3 +1,27 @@ +ruby-browser (4.2.0-3) unstable; urgency=medium + + * Reupload to unstable + + -- Pirate Praveen Tue, 18 Aug 2020 20:21:43 +0530 + +ruby-browser (4.2.0-2) experimental; urgency=medium + + [ Utkarsh Gupta ] + * Add salsa-ci.yml + + [ Pirate Praveen ] + * New upstream version 4.2.0 + * Bump Standards-Version to 4.5.0 (no changes needed) + * Drop compat file, rely on debhelper-compat and bump compat level to 12 + * Refresh patches + + [ Antonio Terceiro ] + * debian/rules: install *.yml + * Add patch to drop usage from gemspec + * debian/ruby-tests.rake: ensure lib/ is in the LOAD_PATH (Closes: #952044) + + -- Antonio Terceiro Sat, 18 Jul 2020 16:22:36 -0300 + ruby-browser (2.5.3-1) unstable; urgency=medium * Team upload diff -Nru ruby-browser-2.5.3/debian/compat ruby-browser-4.2.0/debian/compat --- ruby-browser-2.5.3/debian/compat 2018-09-21 17:49:10.000000000 +0000 +++ ruby-browser-4.2.0/debian/compat 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -11 diff -Nru ruby-browser-2.5.3/debian/control ruby-browser-4.2.0/debian/control --- ruby-browser-2.5.3/debian/control 2018-09-21 17:49:10.000000000 +0000 +++ ruby-browser-4.2.0/debian/control 2020-08-18 14:51:43.000000000 +0000 @@ -4,13 +4,13 @@ Maintainer: Debian Ruby Extras Maintainers Uploaders: Balasankar C , Pirate Praveen -Build-Depends: debhelper (>= 11~), +Build-Depends: debhelper-compat (= 12), gem2deb, ruby-minitest-utils, ruby-railties, ruby-rspec, ruby-simplecov -Standards-Version: 4.2.1 +Standards-Version: 4.5.0 Vcs-Git: https://salsa.debian.org/ruby-team/ruby-browser.git Vcs-Browser: https://salsa.debian.org/ruby-team/ruby-browser Homepage: http://github.com/fnando/browser diff -Nru ruby-browser-2.5.3/debian/patches/0002-browser-drop-git-usage.patch ruby-browser-4.2.0/debian/patches/0002-browser-drop-git-usage.patch --- ruby-browser-2.5.3/debian/patches/0002-browser-drop-git-usage.patch 1970-01-01 00:00:00.000000000 +0000 +++ ruby-browser-4.2.0/debian/patches/0002-browser-drop-git-usage.patch 2020-08-18 14:51:43.000000000 +0000 @@ -0,0 +1,29 @@ +From: Antonio Terceiro +Date: Sat, 18 Jul 2020 15:21:02 -0300 +Subject: browser: drop git usage + +--- + browser.gemspec | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/browser.gemspec b/browser.gemspec +index 66aae14..eb53df9 100644 +--- a/browser.gemspec ++++ b/browser.gemspec +@@ -14,12 +14,10 @@ Gem::Specification.new do |s| + s.license = "MIT" + + s.metadata["changelog_uri"] = "https://github.com/fnando/browser/blob/master/CHANGELOG.md" +- +- s.files = `git ls-files`.split("\n") +- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") +- s.executables = `git ls-files -- exe/*` +- .split("\n") +- .map {|f| File.basename(f) } ++ ++ s.files = Dir['**/*'] - Dir["debian/**/*"] ++ s.test_files = Dir['test/**/*'] ++ s.executables = [] + s.require_paths = ["lib"] + + s.add_development_dependency "bundler", ">= 0" diff -Nru ruby-browser-2.5.3/debian/patches/bundler ruby-browser-4.2.0/debian/patches/bundler --- ruby-browser-2.5.3/debian/patches/bundler 2018-09-21 17:49:10.000000000 +0000 +++ ruby-browser-4.2.0/debian/patches/bundler 2020-08-18 14:51:43.000000000 +0000 @@ -1,16 +1,24 @@ -Description: Remove bundler dependency - Remove need of bundler while running tests. -Author: Balasankar C +From: Balasankar C +Date: Sat, 18 Jul 2020 15:19:59 -0300 +Subject: Remove bundler dependency + Forwarded: not-needed Last-Update: 2015-05-28 + +Remove need of bundler while running tests. +Last-Update: 2015-05-28 --- -This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ + test/test_helper.rb | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/test/test_helper.rb b/test/test_helper.rb +index 8fb6252..d23d72d 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb -@@ -4,7 +4,6 @@ +@@ -4,7 +4,6 @@ require "simplecov" SimpleCov.start - ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", __FILE__) + ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) -require "bundler/setup" require "minitest/autorun" require "minitest/utils" diff -Nru ruby-browser-2.5.3/debian/patches/series ruby-browser-4.2.0/debian/patches/series --- ruby-browser-2.5.3/debian/patches/series 2018-09-21 17:49:10.000000000 +0000 +++ ruby-browser-4.2.0/debian/patches/series 2020-08-18 14:51:43.000000000 +0000 @@ -1 +1,2 @@ bundler +0002-browser-drop-git-usage.patch diff -Nru ruby-browser-2.5.3/debian/ruby-tests.rake ruby-browser-4.2.0/debian/ruby-tests.rake --- ruby-browser-2.5.3/debian/ruby-tests.rake 2018-09-21 17:49:10.000000000 +0000 +++ ruby-browser-4.2.0/debian/ruby-tests.rake 2020-08-18 14:51:43.000000000 +0000 @@ -1,6 +1,9 @@ -require 'gem2deb/rake/testtask' +require 'rake/testtask' -Gem2Deb::Rake::TestTask.new do |t| - t.libs << 'test' +Rake::TestTask.new do |t| + t.libs << 'lib' << 'test' t.test_files = FileList['test/*_test.rb'] + t.verbose = true end + +task default: :test diff -Nru ruby-browser-2.5.3/debian/rules ruby-browser-4.2.0/debian/rules --- ruby-browser-2.5.3/debian/rules 2018-09-21 17:49:10.000000000 +0000 +++ ruby-browser-4.2.0/debian/rules 2020-08-18 14:51:43.000000000 +0000 @@ -2,7 +2,7 @@ export GEM2DEB_TEST_RUNNER = --check-dependencies export DH_RUBY = --gem-install -export DH_RUBY_GEM_INSTALL_WHITELIST_APPEND = test/*.yml +export DH_RUBY_GEM_INSTALL_WHITELIST_APPEND = test/*.yml *.yml %: dh $@ --buildsystem=ruby --with ruby diff -Nru ruby-browser-2.5.3/debian/salsa-ci.yml ruby-browser-4.2.0/debian/salsa-ci.yml --- ruby-browser-2.5.3/debian/salsa-ci.yml 1970-01-01 00:00:00.000000000 +0000 +++ ruby-browser-4.2.0/debian/salsa-ci.yml 2020-08-18 14:51:43.000000000 +0000 @@ -0,0 +1,4 @@ +--- +include: + - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/salsa-ci.yml + - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/pipeline-jobs.yml diff -Nru ruby-browser-2.5.3/Gemfile ruby-browser-4.2.0/Gemfile --- ruby-browser-2.5.3/Gemfile 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/Gemfile 2020-06-19 05:24:10.000000000 +0000 @@ -1,2 +1,4 @@ +# frozen_string_literal: true + source "http://rubygems.org" gemspec diff -Nru ruby-browser-2.5.3/gemfiles/rails4.gemfile ruby-browser-4.2.0/gemfiles/rails4.gemfile --- ruby-browser-2.5.3/gemfiles/rails4.gemfile 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/gemfiles/rails4.gemfile 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -source "https://rubygems.org" -gemspec path: ".." - -gem "rails", '~> 4.0' diff -Nru ruby-browser-2.5.3/gemfiles/rails5.gemfile ruby-browser-4.2.0/gemfiles/rails5.gemfile --- ruby-browser-2.5.3/gemfiles/rails5.gemfile 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/gemfiles/rails5.gemfile 2020-06-19 05:24:10.000000000 +0000 @@ -1,4 +1,6 @@ +# frozen_string_literal: true + source "https://rubygems.org" gemspec path: ".." -gem "rails", '~> 5.0' +gem "rails", "~> 5.0" diff -Nru ruby-browser-2.5.3/gemfiles/rails6.gemfile ruby-browser-4.2.0/gemfiles/rails6.gemfile --- ruby-browser-2.5.3/gemfiles/rails6.gemfile 1970-01-01 00:00:00.000000000 +0000 +++ ruby-browser-4.2.0/gemfiles/rails6.gemfile 2020-06-19 05:24:10.000000000 +0000 @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +source "https://rubygems.org" +gemspec path: ".." + +gem "rails", "~> 6.0" diff -Nru ruby-browser-2.5.3/.github/ISSUE_TEMPLATE.md ruby-browser-4.2.0/.github/ISSUE_TEMPLATE.md --- ruby-browser-2.5.3/.github/ISSUE_TEMPLATE.md 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/.github/ISSUE_TEMPLATE.md 2020-06-19 05:24:10.000000000 +0000 @@ -27,4 +27,4 @@ ## Report -[Visit and paste the URL here] +[Visit and paste the URL here] diff -Nru ruby-browser-2.5.3/.gitignore ruby-browser-4.2.0/.gitignore --- ruby-browser-2.5.3/.gitignore 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/.gitignore 2020-06-19 05:24:10.000000000 +0000 @@ -4,3 +4,4 @@ log *.lock bin/ +.bundle diff -Nru ruby-browser-2.5.3/lib/browser/accept_language.rb ruby-browser-4.2.0/lib/browser/accept_language.rb --- ruby-browser-2.5.3/lib/browser/accept_language.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/accept_language.rb 2020-06-19 05:24:10.000000000 +0000 @@ -14,8 +14,7 @@ .map {|string| string.squeeze(" ").strip } .map {|part| new(part) } .reject {|al| al.quality.zero? } - .sort_by(&:quality) - .reverse + .sort_by.with_index {|al, idx| [-al.quality, idx] } end attr_reader :part @@ -35,28 +34,26 @@ def code @code ||= begin code = part[/\A([^-;]+)/, 1] - code.downcase if code + code&.downcase end end def region @region ||= begin region = part[/\A(?:.*?)-([^;-]+)/, 1] - region.upcase if region + region&.upcase end end def quality @quality ||= begin Float(quality_value || 1.0) - rescue ArgumentError - 0.1 + rescue ArgumentError + 0.1 end end - private - - def quality_value + private def quality_value qvalue = part[/;q=([\d.]+)/, 1] qvalue = qvalue =~ /\A0\.0?\z/ ? "0.0" : qvalue qvalue = qvalue.gsub(/\.+/, ".") if qvalue diff -Nru ruby-browser-2.5.3/lib/browser/action_controller.rb ruby-browser-4.2.0/lib/browser/action_controller.rb --- ruby-browser-2.5.3/lib/browser/action_controller.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/action_controller.rb 2020-06-19 05:24:10.000000000 +0000 @@ -10,9 +10,7 @@ helper_method(:browser) if respond_to?(:helper_method) end - private - - def browser + private def browser @browser ||= Browser.new( request.headers["User-Agent"], accept_language: request.headers["Accept-Language"] diff -Nru ruby-browser-2.5.3/lib/browser/aliases.rb ruby-browser-4.2.0/lib/browser/aliases.rb --- ruby-browser-2.5.3/lib/browser/aliases.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/aliases.rb 2020-06-19 05:24:10.000000000 +0000 @@ -1,6 +1,6 @@ # frozen_string_literal: true -require "browser" +require_relative "../browser" require "forwardable" module Browser @@ -15,10 +15,10 @@ DEVICE_ALIASES = %w[ blackberry_playbook? console? ipad? iphone? ipod_touch? kindle? - kindle_fire? mobile? nintendo? nintendo_wii? nintendo_wiiu? playbook? - playstation3? playstation4? playstation? playstation_vita? ps3? ps4? psp? - psp_vita? silk? surface? tablet? tv? vita? wii? wiiu? xbox? xbox_360? - xbox_one? + kindle_fire? mobile? nintendo? nintendo_switch? nintendo_wii? + nintendo_wiiu? playbook? playstation3? playstation4? playstation? + playstation_vita? ps3? ps4? psp? psp_vita? silk? surface? tablet? tv? + vita? wii? wiiu? xbox? xbox_360? xbox_one? ].freeze def self.included(target) diff -Nru ruby-browser-2.5.3/lib/browser/alipay.rb ruby-browser-4.2.0/lib/browser/alipay.rb --- ruby-browser-2.5.3/lib/browser/alipay.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/alipay.rb 2020-06-19 05:24:10.000000000 +0000 @@ -11,7 +11,7 @@ end def full_version - ua[%r[(?:AlipayClient)/([\d.]+)]i, 1] || "0.0" + ua[%r{(?:AlipayClient)/([\d.]+)}i, 1] || "0.0" end def match? diff -Nru ruby-browser-2.5.3/lib/browser/base.rb ruby-browser-4.2.0/lib/browser/base.rb --- ruby-browser-2.5.3/lib/browser/base.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/base.rb 2020-06-19 05:24:10.000000000 +0000 @@ -50,11 +50,6 @@ @device ||= Device.new(ua) end - # Return true if browser is modern (Webkit, Firefox 17+, IE9+, Opera 12+). - def modern? - Browser.modern_rules.any? {|rule| rule === self } # rubocop:disable Metrics/LineLength, Style/CaseEquality - end - # Detect if browser is Microsoft Internet Explorer. def ie?(expected_version = nil) InternetExplorer.new(ua).match? && @@ -78,6 +73,18 @@ "0" end + # Detect if browser is Instagram. + def instagram?(expected_version = nil) + Instagram.new(ua).match? && + detect_version?(full_version, expected_version) + end + + # Detect if browser is Snapchat. + def snapchat?(expected_version = nil) + Snapchat.new(ua).match? && + detect_version?(full_version, expected_version) + end + # Detect if browser if Facebook. def facebook?(expected_version = nil) Facebook.new(ua).match? && @@ -93,7 +100,7 @@ # Detect if browser is WebKit-based. def webkit?(expected_version = nil) ua =~ /AppleWebKit/i && - !edge? && + (!edge? || Edge.new(ua).chrome_based?) && detect_version?(webkit_full_version, expected_version) end @@ -137,10 +144,16 @@ Opera.new(ua).match? && detect_version?(full_version, expected_version) end + # Detect if browser is Sputnik. + def sputnik?(expected_version = nil) + Sputnik.new(ua).match? && detect_version?(full_version, expected_version) + end + # Detect if browser is Yandex. def yandex?(expected_version = nil) - ua =~ /YaBrowser/ && detect_version?(full_version, expected_version) + Yandex.new(ua).match? && detect_version?(full_version, expected_version) end + alias_method :yandex_browser?, :yandex? # Detect if browser is UCBrowser. def uc_browser?(expected_version = nil) @@ -174,8 +187,18 @@ ua =~ /Opera Mini/ && detect_version?(full_version, expected_version) end + # Detect if browser is DuckDuckGo. + def duck_duck_go?(expected_version = nil) + ua =~ /DuckDuckGo/ && detect_version?(full_version, expected_version) + end + + # Detect if browser is Samsung. + def samsung_browser?(expected_version = nil) + ua =~ /SamsungBrowser/ && detect_version?(full_version, expected_version) + end + def webkit_full_version - ua[%r[AppleWebKit/([\d.]+)], 1] || "0.0" + ua[%r{AppleWebKit/([\d.]+)}, 1] || "0.0" end def known? diff -Nru ruby-browser-2.5.3/lib/browser/blackberry.rb ruby-browser-4.2.0/lib/browser/blackberry.rb --- ruby-browser-2.5.3/lib/browser/blackberry.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/blackberry.rb 2020-06-19 05:24:10.000000000 +0000 @@ -11,8 +11,8 @@ end def full_version - ua[%r[BlackBerry[\da-z]+/([\d.]+)], 1] || - ua[%r[Version/([\d.]+)], 1] || + ua[%r{BlackBerry[\da-z]+/([\d.]+)}, 1] || + ua[%r{Version/([\d.]+)}, 1] || "0.0" end diff -Nru ruby-browser-2.5.3/lib/browser/bot/empty_user_agent_matcher.rb ruby-browser-4.2.0/lib/browser/bot/empty_user_agent_matcher.rb --- ruby-browser-2.5.3/lib/browser/bot/empty_user_agent_matcher.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/bot/empty_user_agent_matcher.rb 2020-06-19 05:24:10.000000000 +0000 @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Browser + class Bot + class EmptyUserAgentMatcher + def self.call(ua, _browser) + ua == "" + end + end + end +end diff -Nru ruby-browser-2.5.3/lib/browser/bot/keyword_matcher.rb ruby-browser-4.2.0/lib/browser/bot/keyword_matcher.rb --- ruby-browser-2.5.3/lib/browser/bot/keyword_matcher.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/bot/keyword_matcher.rb 2020-06-19 05:24:10.000000000 +0000 @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Browser + class Bot + class KeywordMatcher + def self.call(ua, _browser) + ua =~ /crawl|fetch|search|monitoring|spider|bot/ + end + end + end +end diff -Nru ruby-browser-2.5.3/lib/browser/bot/known_bots_matcher.rb ruby-browser-4.2.0/lib/browser/bot/known_bots_matcher.rb --- ruby-browser-2.5.3/lib/browser/bot/known_bots_matcher.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/bot/known_bots_matcher.rb 2020-06-19 05:24:10.000000000 +0000 @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module Browser + class Bot + class KnownBotsMatcher + def self.call(ua, _browser) + Browser::Bot.bots.any? {|key, _| ua.include?(key) } + end + end + end +end diff -Nru ruby-browser-2.5.3/lib/browser/bot.rb ruby-browser-4.2.0/lib/browser/bot.rb --- ruby-browser-2.5.3/lib/browser/bot.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/bot.rb 2020-06-19 05:24:10.000000000 +0000 @@ -2,64 +2,76 @@ module Browser class Bot - def self.detect_empty_ua! - @detect_empty_ua = true + GENERIC_NAME = "Generic Bot" + + def self.matchers + @matchers ||= default_matchers + end + + def self.default_matchers + [ + EmptyUserAgentMatcher, + KnownBotsMatcher, + KeywordMatcher + ] end - def self.detect_empty_ua? - @detect_empty_ua + def self.load_yaml(path) + YAML.load_file(Browser.root.join(path)) end def self.bots - @bots ||= YAML.load_file(Browser.root.join("bots.yml")) + @bots ||= load_yaml("bots.yml") end def self.bot_exceptions - @bot_exceptions ||= YAML - .load_file(Browser.root.join("bot_exceptions.yml")) + @bot_exceptions ||= load_yaml("bot_exceptions.yml") end def self.search_engines - @search_engines ||= YAML - .load_file(Browser.root.join("search_engines.yml")) + @search_engines ||= load_yaml("search_engines.yml") + end + + def self.why?(ua) + ua = ua.downcase.strip + browser = Browser.new(ua) + matchers.find {|matcher| matcher.call(ua, browser) } end - attr_reader :ua + attr_reader :ua, :browser def initialize(ua) - @ua = ua + @ua = ua.downcase.strip + @browser = Browser.new(@ua) end def bot? - bot_with_empty_ua? || (!bot_exception? && detect_bot?) + !bot_exception? && detect_bot? + end + + def why? + self.class.matchers.find {|matcher| matcher.call(ua, self) } end def search_engine? - self.class.search_engines.any? {|key, _| downcased_ua.include?(key) } + self.class.search_engines.any? {|key, _| ua.include?(key) } end def name return unless bot? - return "Generic Bot" if bot_with_empty_ua? - self.class.bots.find {|key, _| downcased_ua.include?(key) }.last - end - private - - def bot_with_empty_ua? - self.class.detect_empty_ua? && ua.strip == "" + self.class.bots.find {|key, _| ua.include?(key) }&.last || GENERIC_NAME end - def bot_exception? - self.class.bot_exceptions.any? {|key| downcased_ua.include?(key) } + private def bot_exception? + self.class.bot_exceptions.any? {|key| ua.include?(key) } end - def detect_bot? - self.class.bots.any? {|key, _| downcased_ua.include?(key) } + private def detect_bot? + self.class.matchers.any? {|matcher| matcher.call(ua, browser) } end - def downcased_ua - @downcased_ua ||= ua.downcase - end + private :ua + private :browser end end diff -Nru ruby-browser-2.5.3/lib/browser/browser.rb ruby-browser-4.2.0/lib/browser/browser.rb --- ruby-browser-2.5.3/lib/browser/browser.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/browser.rb 2020-06-19 05:24:10.000000000 +0000 @@ -4,41 +4,50 @@ require "yaml" require "pathname" -require "browser/version" -require "browser/detect_version" -require "browser/accept_language" -require "browser/base" -require "browser/safari" -require "browser/chrome" -require "browser/internet_explorer" -require "browser/firefox" -require "browser/edge" -require "browser/opera" -require "browser/blackberry" -require "browser/generic" -require "browser/phantom_js" -require "browser/uc_browser" -require "browser/nokia" -require "browser/micro_messenger" -require "browser/weibo" -require "browser/qq" -require "browser/alipay" -require "browser/electron" -require "browser/facebook" -require "browser/otter" - -require "browser/bot" -require "browser/middleware" - -require "browser/platform" -require "browser/device" -require "browser/meta" +require_relative "version" +require_relative "detect_version" +require_relative "accept_language" +require_relative "base" +require_relative "safari" +require_relative "chrome" +require_relative "internet_explorer" +require_relative "firefox" +require_relative "edge" +require_relative "opera" +require_relative "blackberry" +require_relative "generic" +require_relative "phantom_js" +require_relative "uc_browser" +require_relative "nokia" +require_relative "micro_messenger" +require_relative "weibo" +require_relative "qq" +require_relative "alipay" +require_relative "electron" +require_relative "facebook" +require_relative "otter" +require_relative "instagram" +require_relative "yandex" +require_relative "sputnik" +require_relative "snapchat" +require_relative "duck_duck_go" +require_relative "samsung_browser" + +require_relative "bot" +require_relative "bot/empty_user_agent_matcher" +require_relative "bot/keyword_matcher" +require_relative "bot/known_bots_matcher" + +require_relative "middleware" +require_relative "platform" +require_relative "device" +require_relative "meta" module Browser - EMPTY_STRING = "".freeze + EMPTY_STRING = "" def self.root - @root ||= Pathname.new(File.expand_path("../../..", __FILE__)) + @root ||= Pathname.new(File.expand_path("../..", __dir__)) end # Hold the list of browser matchers. @@ -55,40 +64,23 @@ Firefox, Otter, Facebook, # must be placed before Chrome and Safari + Instagram, # must be placed before Chrome and Safari + Snapchat, # must be placed before Chrome and Safari Weibo, # must be placed before Chrome and Safari + MicroMessenger, # must be placed before QQ QQ, # must be placed before Chrome and Safari Alipay, # must be placed before Chrome and Safari Electron, # must be placed before Chrome and Safari + Yandex, # must be placed before Chrome and Safari + Sputnik, # must be placed before Chrome and Safari + DuckDuckGo, # must be placed before Chrome and Safari + SamsungBrowser, # must be placed before Chrome and Safari Chrome, Safari, - MicroMessenger, Generic ] end - # Define the rules which define a modern browser. - # A rule must be a proc/lambda or any object that implements the method - # === and accepts the browser object. - # - # To redefine all rules, clear the existing rules before adding your own. - # - # # Only Chrome Canary is considered modern. - # Browser.modern_rules.clear - # Browser.modern_rules << -> b { b.chrome? && b.version >= "37" } - # - def self.modern_rules - @modern_rules ||= [] - end - - modern_rules.tap do |rules| - rules << ->(b) { b.webkit? } - rules << ->(b) { b.firefox? && b.version.to_i >= 17 } - rules << ->(b) { b.ie? && b.version.to_i >= 9 && !b.compatibility_view? } - rules << ->(b) { b.edge? && !b.compatibility_view? } - rules << ->(b) { b.opera? && b.version.to_i >= 12 } - rules << ->(b) { b.firefox? && b.device.tablet? && b.platform.android? && b.version.to_i >= 14 } # rubocop:disable Metrics/LineLength - end - def self.new(user_agent, **kwargs) matchers .map {|klass| klass.new(user_agent || EMPTY_STRING, **kwargs) } diff -Nru ruby-browser-2.5.3/lib/browser/chrome.rb ruby-browser-4.2.0/lib/browser/chrome.rb --- ruby-browser-2.5.3/lib/browser/chrome.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/chrome.rb 2020-06-19 05:24:10.000000000 +0000 @@ -12,15 +12,22 @@ def full_version # Each regex on its own line to enforce precedence. - ua[%r[Chrome/([\d.]+)], 1] || - ua[%r[CriOS/([\d.]+)], 1] || - ua[%r[Safari/([\d.]+)], 1] || - ua[%r[AppleWebKit/([\d.]+)], 1] || + ua[%r{Chrome/([\d.]+)}, 1] || + ua[%r{CriOS/([\d.]+)}, 1] || + ua[%r{Safari/([\d.]+)}, 1] || + ua[%r{AppleWebKit/([\d.]+)}, 1] || "0.0" end def match? - ua =~ /Chrome|CriOS/ && !opera? && !edge? + ua =~ /Chrome|CriOS/ && + ua !~ /PhantomJS|FxiOS|ArchiveBot/ && + !opera? && + !edge? && + !duck_duck_go? && + !yandex? && + !sputnik? && + !samsung_browser? end end end diff -Nru ruby-browser-2.5.3/lib/browser/detect_version.rb ruby-browser-4.2.0/lib/browser/detect_version.rb --- ruby-browser-2.5.3/lib/browser/detect_version.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/detect_version.rb 2020-06-19 05:24:10.000000000 +0000 @@ -2,9 +2,7 @@ module Browser module DetectVersion - private - - def detect_version?(actual_version, expected_version) + private def detect_version?(actual_version, expected_version) return true unless expected_version return false if expected_version && !actual_version @@ -13,10 +11,12 @@ Gem::Requirement.create(expected_version) .satisfied_by?(Gem::Version.create(actual_version)) + rescue ArgumentError + false end - def parse_version(version) - version.kind_of?(Numeric) ? version.to_s : version + private def parse_version(version) + version.is_a?(Numeric) ? version.to_s : version end end end diff -Nru ruby-browser-2.5.3/lib/browser/device/android.rb ruby-browser-4.2.0/lib/browser/device/android.rb --- ruby-browser-2.5.3/lib/browser/device/android.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/device/android.rb 2020-06-19 05:24:10.000000000 +0000 @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module Browser + class Device + class Android < Base + def id + :unknown + end + + def name + ua[/\(Linux.*?; Android.*?; ([-_a-z0-9 ]+) Build[^)]+\)/i, 1] || + "Unknown" + end + + def match? + ua =~ /Android/ + end + end + end +end diff -Nru ruby-browser-2.5.3/lib/browser/device/surface.rb ruby-browser-4.2.0/lib/browser/device/surface.rb --- ruby-browser-2.5.3/lib/browser/device/surface.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/device/surface.rb 2020-06-19 05:24:10.000000000 +0000 @@ -15,9 +15,7 @@ platform.windows_rt? && ua =~ /Touch/ end - private - - def platform + private def platform @platform ||= Platform.new(ua) end end diff -Nru ruby-browser-2.5.3/lib/browser/device/switch.rb ruby-browser-4.2.0/lib/browser/device/switch.rb --- ruby-browser-2.5.3/lib/browser/device/switch.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/device/switch.rb 2020-06-19 05:24:10.000000000 +0000 @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module Browser + class Device + class Switch < Base + def id + :switch + end + + def name + "Nintendo Switch" + end + + def match? + ua =~ /Nintendo Switch/i + end + end + end +end diff -Nru ruby-browser-2.5.3/lib/browser/device/tv.rb ruby-browser-4.2.0/lib/browser/device/tv.rb --- ruby-browser-2.5.3/lib/browser/device/tv.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/device/tv.rb 2020-06-19 05:24:10.000000000 +0000 @@ -12,7 +12,7 @@ end def match? - ua =~ /(tv|Android.*?ADT-1|Nexus Player)/i + ua =~ /(\btv|Android.*?ADT-1|Nexus Player)/i end end end diff -Nru ruby-browser-2.5.3/lib/browser/device.rb ruby-browser-4.2.0/lib/browser/device.rb --- ruby-browser-2.5.3/lib/browser/device.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/device.rb 2020-06-19 05:24:10.000000000 +0000 @@ -1,23 +1,25 @@ # frozen_string_literal: true -require "browser/device/base" -require "browser/device/unknown" -require "browser/device/ipad" -require "browser/device/ipod_touch" -require "browser/device/iphone" -require "browser/device/playstation3" -require "browser/device/playstation4" -require "browser/device/psp" -require "browser/device/psvita" -require "browser/device/kindle" -require "browser/device/kindle_fire" -require "browser/device/wii" -require "browser/device/wiiu" -require "browser/device/blackberry_playbook" -require "browser/device/surface" -require "browser/device/tv" -require "browser/device/xbox_one" -require "browser/device/xbox_360" +require_relative "device/base" +require_relative "device/android" +require_relative "device/unknown" +require_relative "device/ipad" +require_relative "device/ipod_touch" +require_relative "device/iphone" +require_relative "device/playstation3" +require_relative "device/playstation4" +require_relative "device/psp" +require_relative "device/psvita" +require_relative "device/kindle" +require_relative "device/kindle_fire" +require_relative "device/wii" +require_relative "device/wiiu" +require_relative "device/blackberry_playbook" +require_relative "device/surface" +require_relative "device/switch" +require_relative "device/tv" +require_relative "device/xbox_one" +require_relative "device/xbox_360" module Browser class Device @@ -34,6 +36,7 @@ BlackBerryPlaybook, WiiU, Wii, + Switch, KindleFire, Kindle, PlayStation4, @@ -43,6 +46,7 @@ Ipad, Iphone, IpodTouch, + Android, Unknown ] end @@ -134,6 +138,11 @@ end alias_method :wiiu?, :nintendo_wiiu? + def nintendo_switch? + id == :switch + end + alias_method :switch?, :nintendo_switch? + def blackberry_playbook? id == :playbook end @@ -174,7 +183,7 @@ # Detect if browser is Nintendo. def nintendo? - wii? || wiiu? + wii? || wiiu? || switch? end # Detect if browser is console (currently Xbox, PlayStation, or Nintendo). @@ -182,20 +191,21 @@ xbox? || playstation? || nintendo? end - private - # Regex taken from http://detectmobilebrowsers.com - # rubocop:disable Metrics/LineLength - def detect_mobile? + # rubocop:disable Layout/LineLength + private def detect_mobile? psp? || - /zunewp7/i.match(ua) || - /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.match(ua) || - /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.match(ua[0..3]) + /zunewp7/i.match(ua) || + %r{(android|bb\d+|meego).+mobile|avantgo|bada/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino}i.match(ua) || + %r{1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-}i.match(ua[0..3]) end - # rubocop:enable Metrics/LineLength + # rubocop:enable Layout/LineLength - def platform + private def platform @platform ||= Platform.new(ua) end + + private :subject + private :ua end end diff -Nru ruby-browser-2.5.3/lib/browser/duck_duck_go.rb ruby-browser-4.2.0/lib/browser/duck_duck_go.rb --- ruby-browser-2.5.3/lib/browser/duck_duck_go.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/duck_duck_go.rb 2020-06-19 05:24:10.000000000 +0000 @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module Browser + class DuckDuckGo < Base + def id + :duckduckgo + end + + def name + "DuckDuckGo" + end + + def full_version + ua[%r{DuckDuckGo/([\d.]+)}, 1] || + "0.0" + end + + def match? + ua =~ /DuckDuckGo/ + end + end +end diff -Nru ruby-browser-2.5.3/lib/browser/edge.rb ruby-browser-4.2.0/lib/browser/edge.rb --- ruby-browser-2.5.3/lib/browser/edge.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/edge.rb 2020-06-19 05:24:10.000000000 +0000 @@ -11,11 +11,15 @@ end def full_version - ua[%r[Edge/([\d.]+)], 1] || super + ua[%r{(?:Edge|Edg|EdgiOS|EdgA)/([\d.]+)}, 1] || super end def match? - ua =~ %r[(Edge/[\d.]+|Trident/8)] + ua =~ %r{((?:Edge|Edg|EdgiOS|EdgA)/[\d.]+|Trident/8)} + end + + def chrome_based? + match? && ua =~ /\bEdg\b/ end end end diff -Nru ruby-browser-2.5.3/lib/browser/electron.rb ruby-browser-4.2.0/lib/browser/electron.rb --- ruby-browser-2.5.3/lib/browser/electron.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/electron.rb 2020-06-19 05:24:10.000000000 +0000 @@ -11,7 +11,7 @@ end def full_version - ua[%r[Electron/([\d.]+)], 1] || + ua[%r{Electron/([\d.]+)}, 1] || "0.0" end diff -Nru ruby-browser-2.5.3/lib/browser/facebook.rb ruby-browser-4.2.0/lib/browser/facebook.rb --- ruby-browser-2.5.3/lib/browser/facebook.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/facebook.rb 2020-06-19 05:24:10.000000000 +0000 @@ -11,11 +11,13 @@ end def full_version - ua[%r[FBAV/([\d.]+)], 1] + ua[%r{FBAV/([\d.]+)}, 1] || + ua[%r{AppleWebKit/([\d.]+)}, 0] || + "0.0" end def match? - ua =~ /FBAV/ + ua =~ /FBAV|FBAN/ end end end diff -Nru ruby-browser-2.5.3/lib/browser/firefox.rb ruby-browser-4.2.0/lib/browser/firefox.rb --- ruby-browser-2.5.3/lib/browser/firefox.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/firefox.rb 2020-06-19 05:24:10.000000000 +0000 @@ -11,7 +11,7 @@ end def full_version - ua[%r[(?:Firefox|FxiOS)/([\d.]+)], 1] || "0.0" + ua[%r{(?:Firefox|FxiOS)/([\d.]+)}, 1] || "0.0" end def match? diff -Nru ruby-browser-2.5.3/lib/browser/generic.rb ruby-browser-4.2.0/lib/browser/generic.rb --- ruby-browser-2.5.3/lib/browser/generic.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/generic.rb 2020-06-19 05:24:10.000000000 +0000 @@ -16,8 +16,8 @@ end def full_version - ua[%r[(?:QuickTime)/([\d.]+)], 1] || - ua[%r[CoreMedia v([\d.]+)], 1] || + ua[%r{(?:QuickTime)/([\d.]+)}, 1] || + ua[/CoreMedia v([\d.]+)/, 1] || "0.0" end @@ -25,9 +25,7 @@ true end - private - - def infer_name + private def infer_name (NAMES.find {|key, _| ua.include?(key) } || []).last end end diff -Nru ruby-browser-2.5.3/lib/browser/instagram.rb ruby-browser-4.2.0/lib/browser/instagram.rb --- ruby-browser-2.5.3/lib/browser/instagram.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/instagram.rb 2020-06-19 05:24:10.000000000 +0000 @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Browser + class Instagram < Base + def id + :instagram + end + + def name + "Instagram" + end + + def full_version + ua[%r{Instagram[ /]([\d.]+)}, 1] || "0.0" + end + + def match? + ua =~ /Instagram/ + end + end +end diff -Nru ruby-browser-2.5.3/lib/browser/internet_explorer.rb ruby-browser-4.2.0/lib/browser/internet_explorer.rb --- ruby-browser-2.5.3/lib/browser/internet_explorer.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/internet_explorer.rb 2020-06-19 05:24:10.000000000 +0000 @@ -24,7 +24,8 @@ end def msie_full_version - (ua.match(%r{MSIE ([\d.]+)|Trident/.*?; rv:([\d.]+)}) && ($1 || $2)) || + (ua.match(%r{MSIE ([\d.]+)|Trident/.*?; rv:([\d.]+)}) && + (Regexp.last_match(1) || Regexp.last_match(2))) || "0.0" end @@ -41,23 +42,21 @@ trident_version && msie_version.to_i < (trident_version.to_i + 4) end - private - - def ie_version + private def ie_version TRIDENT_MAPPING[trident_version] || msie_version end # Return the trident version. - def trident_version - ua.match(%r[Trident/([0-9.]+)]) && $1 + private def trident_version + ua.match(%r{Trident/([0-9.]+)}) && Regexp.last_match(1) end - def msie? + private def msie? ua =~ /MSIE/ && ua !~ /Opera/ end - def modern_ie? - ua =~ %r[Trident/.*?; rv:(.*?)] + private def modern_ie? + ua =~ %r{Trident/.*?; rv:(.*?)} end end end diff -Nru ruby-browser-2.5.3/lib/browser/meta/base.rb ruby-browser-4.2.0/lib/browser/meta/base.rb --- ruby-browser-2.5.3/lib/browser/meta/base.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/meta/base.rb 2020-06-19 05:24:10.000000000 +0000 @@ -10,7 +10,6 @@ IE, IOS, Mobile, - Modern, Platform, Proxy, Safari, diff -Nru ruby-browser-2.5.3/lib/browser/meta/generic_browser.rb ruby-browser-4.2.0/lib/browser/meta/generic_browser.rb --- ruby-browser-2.5.3/lib/browser/meta/generic_browser.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/meta/generic_browser.rb 2020-06-19 05:24:10.000000000 +0000 @@ -7,9 +7,7 @@ "#{browser.id} #{browser.id}#{browser.version}" if generic? end - private - - def generic? + private def generic? !browser.safari? && !browser.chrome? end end diff -Nru ruby-browser-2.5.3/lib/browser/meta/modern.rb ruby-browser-4.2.0/lib/browser/meta/modern.rb --- ruby-browser-2.5.3/lib/browser/meta/modern.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/meta/modern.rb 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -module Browser - module Meta - class Modern < Base - def meta - "modern" if browser.modern? - end - end - end -end diff -Nru ruby-browser-2.5.3/lib/browser/meta.rb ruby-browser-4.2.0/lib/browser/meta.rb --- ruby-browser-2.5.3/lib/browser/meta.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/meta.rb 2020-06-19 05:24:10.000000000 +0000 @@ -1,15 +1,14 @@ # frozen_string_literal: true -require "browser/meta/base" -require "browser/meta/generic_browser" -require "browser/meta/id" -require "browser/meta/ie" -require "browser/meta/ios" -require "browser/meta/mobile" -require "browser/meta/modern" -require "browser/meta/platform" -require "browser/meta/proxy" -require "browser/meta/safari" -require "browser/meta/webkit" -require "browser/meta/tablet" -require "browser/meta/device" +require_relative "meta/base" +require_relative "meta/generic_browser" +require_relative "meta/id" +require_relative "meta/ie" +require_relative "meta/ios" +require_relative "meta/mobile" +require_relative "meta/platform" +require_relative "meta/proxy" +require_relative "meta/safari" +require_relative "meta/webkit" +require_relative "meta/tablet" +require_relative "meta/device" diff -Nru ruby-browser-2.5.3/lib/browser/micro_messenger.rb ruby-browser-4.2.0/lib/browser/micro_messenger.rb --- ruby-browser-2.5.3/lib/browser/micro_messenger.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/micro_messenger.rb 2020-06-19 05:24:10.000000000 +0000 @@ -11,7 +11,7 @@ end def full_version - ua[%r[(?:MicroMessenger)/([\d.]+)]i, 1] || "0.0" + ua[%r{(?:MicroMessenger)/([\d.]+)}i, 1] || "0.0" end def match? diff -Nru ruby-browser-2.5.3/lib/browser/middleware/context/additions.rb ruby-browser-4.2.0/lib/browser/middleware/context/additions.rb --- ruby-browser-2.5.3/lib/browser/middleware/context/additions.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/middleware/context/additions.rb 2020-06-19 05:24:10.000000000 +0000 @@ -1,6 +1,6 @@ # frozen_string_literal: true -require "browser/middleware/context/url_methods" +require_relative "url_methods" module Browser class Middleware diff -Nru ruby-browser-2.5.3/lib/browser/middleware.rb ruby-browser-4.2.0/lib/browser/middleware.rb --- ruby-browser-2.5.3/lib/browser/middleware.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/middleware.rb 2020-06-19 05:24:10.000000000 +0000 @@ -1,15 +1,16 @@ # frozen_string_literal: true require "uri" -require "browser/middleware/context" +require_relative "middleware/context" module Browser class Middleware # Detect the most common assets. - ASSETS_REGEX = /\.(css|png|jpe?g|gif|js|svg|ico|flv|mov|m4v|ogg|swf)\z/i + ASSETS_REGEX = + /\.(css|png|jpe?g|gif|js|svg|ico|flv|mov|m4v|ogg|swf)\z/i.freeze # Detect the ACCEPT header. IE8 send */*. - ACCEPT_REGEX = %r[(text/html|\*/\*)] + ACCEPT_REGEX = %r{(text/html|\*/\*)}.freeze def initialize(app, &block) raise ArgumentError, "Browser::Middleware requires a block" unless block diff -Nru ruby-browser-2.5.3/lib/browser/nokia.rb ruby-browser-4.2.0/lib/browser/nokia.rb --- ruby-browser-2.5.3/lib/browser/nokia.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/nokia.rb 2020-06-19 05:24:10.000000000 +0000 @@ -11,7 +11,7 @@ end def full_version - ua[%r[S40OviBrowser/([\d.]+)], 1] || "0.0" + ua[%r{S40OviBrowser/([\d.]+)}, 1] || "0.0" end def match? diff -Nru ruby-browser-2.5.3/lib/browser/opera.rb ruby-browser-4.2.0/lib/browser/opera.rb --- ruby-browser-2.5.3/lib/browser/opera.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/opera.rb 2020-06-19 05:24:10.000000000 +0000 @@ -11,11 +11,11 @@ end def full_version - ua[%r[OPR/([\d.]+)], 1] || ua[%r[Version/([\d.]+)], 1] || "0.0" + ua[%r{OPR/([\d.]+)}, 1] || ua[%r{Version/([\d.]+)}, 1] || "0.0" end def match? - ua =~ /(Opera|OPR\/)/ + ua =~ %r{(Opera|OPR/)} end end end diff -Nru ruby-browser-2.5.3/lib/browser/otter.rb ruby-browser-4.2.0/lib/browser/otter.rb --- ruby-browser-2.5.3/lib/browser/otter.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/otter.rb 2020-06-19 05:24:10.000000000 +0000 @@ -11,7 +11,7 @@ end def full_version - ua[%r[Otter/([\d.]+)], 1] || "0.0" + ua[%r{Otter/([\d.]+)}, 1] || "0.0" end def match? diff -Nru ruby-browser-2.5.3/lib/browser/phantom_js.rb ruby-browser-4.2.0/lib/browser/phantom_js.rb --- ruby-browser-2.5.3/lib/browser/phantom_js.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/phantom_js.rb 2020-06-19 05:24:10.000000000 +0000 @@ -11,7 +11,7 @@ end def full_version - ua[%r[PhantomJS/([\d.]+)], 1] || "0.0" + ua[%r{PhantomJS/([\d.]+)}, 1] || "0.0" end def match? diff -Nru ruby-browser-2.5.3/lib/browser/platform/adobe_air.rb ruby-browser-4.2.0/lib/browser/platform/adobe_air.rb --- ruby-browser-2.5.3/lib/browser/platform/adobe_air.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/platform/adobe_air.rb 2020-06-19 05:24:10.000000000 +0000 @@ -8,7 +8,7 @@ end def version - ua[%r[AdobeAIR/([\d.]+)], 1] + ua[%r{AdobeAIR/([\d.]+)}, 1] end def name diff -Nru ruby-browser-2.5.3/lib/browser/platform/base.rb ruby-browser-4.2.0/lib/browser/platform/base.rb --- ruby-browser-2.5.3/lib/browser/platform/base.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/platform/base.rb 2020-06-19 05:24:10.000000000 +0000 @@ -3,10 +3,11 @@ module Browser class Platform class Base - attr_reader :ua + attr_reader :ua, :platform - def initialize(ua) + def initialize(ua, platform = nil) @ua = ua + @platform = platform end def match? diff -Nru ruby-browser-2.5.3/lib/browser/platform/blackberry.rb ruby-browser-4.2.0/lib/browser/platform/blackberry.rb --- ruby-browser-2.5.3/lib/browser/platform/blackberry.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/platform/blackberry.rb 2020-06-19 05:24:10.000000000 +0000 @@ -16,7 +16,7 @@ end def version - ua[%r[(?:Version|BlackBerry[\da-z]+)/([\d.]+)], 1] + ua[%r{(?:Version|BlackBerry[\da-z]+)/([\d.]+)}, 1] end end end diff -Nru ruby-browser-2.5.3/lib/browser/platform/ios.rb ruby-browser-4.2.0/lib/browser/platform/ios.rb --- ruby-browser-2.5.3/lib/browser/platform/ios.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/platform/ios.rb 2020-06-19 05:24:10.000000000 +0000 @@ -3,11 +3,24 @@ module Browser class Platform class IOS < Base - MATCHER = /(iPhone|iPad|iPod)/ - VERSION_MATCHER = /OS ([\d.]+)/ + MATCHER = /(iPhone|iPad|iPod)/.freeze + VERSION_MATCHER = + /OS ((?\d+)_(?\d+)_?(?\d+)?)/.freeze def version - ua[VERSION_MATCHER, 1] || "0" + matches = VERSION_MATCHER.match(ua) + + return "0" unless matches + + versions = [matches[:major]] + + if matches[:patch] + versions.push(matches[:minor], matches[:patch]) + else + versions.push(matches[:minor]) unless matches[:minor] == "0" + end + + versions.join(".") end def name diff -Nru ruby-browser-2.5.3/lib/browser/platform/mac.rb ruby-browser-4.2.0/lib/browser/platform/mac.rb --- ruby-browser-2.5.3/lib/browser/platform/mac.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/platform/mac.rb 2020-06-19 05:24:10.000000000 +0000 @@ -8,7 +8,9 @@ end def name - "Macintosh" + return "macOS" if platform.mac?(">= 10.12") + + "Mac OS X" end def id diff -Nru ruby-browser-2.5.3/lib/browser/platform.rb ruby-browser-4.2.0/lib/browser/platform.rb --- ruby-browser-2.5.3/lib/browser/platform.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/platform.rb 2020-06-19 05:24:10.000000000 +0000 @@ -1,18 +1,18 @@ # frozen_string_literal: true -require "browser/platform/base" -require "browser/platform/ios" -require "browser/platform/linux" -require "browser/platform/windows" -require "browser/platform/mac" -require "browser/platform/windows_phone" -require "browser/platform/windows_mobile" -require "browser/platform/firefox_os" -require "browser/platform/blackberry" -require "browser/platform/android" -require "browser/platform/other" -require "browser/platform/chrome_os" -require "browser/platform/adobe_air" +require_relative "platform/base" +require_relative "platform/ios" +require_relative "platform/linux" +require_relative "platform/windows" +require_relative "platform/mac" +require_relative "platform/windows_phone" +require_relative "platform/windows_mobile" +require_relative "platform/firefox_os" +require_relative "platform/blackberry" +require_relative "platform/android" +require_relative "platform/other" +require_relative "platform/chrome_os" +require_relative "platform/adobe_air" module Browser class Platform @@ -45,7 +45,7 @@ def subject @subject ||= self.class.matchers - .map {|matcher| matcher.new(ua) } + .map {|matcher| matcher.new(ua, self) } .find(&:match?) end @@ -179,5 +179,8 @@ def windows_touchscreen_desktop? windows? && ua =~ /Touch/ end + + private :subject + private :ua end end diff -Nru ruby-browser-2.5.3/lib/browser/qq.rb ruby-browser-4.2.0/lib/browser/qq.rb --- ruby-browser-2.5.3/lib/browser/qq.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/qq.rb 2020-06-19 05:24:10.000000000 +0000 @@ -11,15 +11,15 @@ end def full_version - ua[%r[(?:Mobile MQQBrowser)/([\d.]+)]i, 1] || - ua[%r[(?:QQBrowserLite)/([\d.]+)]i, 1] || - ua[%r[(?:QQBrowser)/([\d.]+)]i, 1] || - ua[%r[(?:QQ)/([\d.]+)]i, 1] || + ua[%r{(?:Mobile MQQBrowser)/([\d.]+)}i, 1] || + ua[%r{(?:QQBrowserLite)/([\d.]+)}i, 1] || + ua[%r{(?:QQBrowser)/([\d.]+)}i, 1] || + ua[%r{(?:QQ)/([\d.]+)}i, 1] || "0.0" end def match? - ua =~ /QQ/i + ua =~ %r{QQ/|QQBrowser}i end end end diff -Nru ruby-browser-2.5.3/lib/browser/rails.rb ruby-browser-4.2.0/lib/browser/rails.rb --- ruby-browser-2.5.3/lib/browser/rails.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/rails.rb 2020-06-19 05:24:10.000000000 +0000 @@ -1,8 +1,8 @@ # frozen_string_literal: true require "rails/railtie" -require "browser/action_controller" -require "browser/middleware/context/additions" +require_relative "action_controller" +require_relative "middleware/context/additions" module Browser class Railtie < Rails::Railtie @@ -10,9 +10,11 @@ initializer "browser" do ActiveSupport.on_load(:action_controller) do - ::ActionController::Base.send :include, Browser::ActionController - Browser::Middleware::Context.send( - :include, + ::ActionController::Base.include(Browser::ActionController) + + ::ActionController::Metal.include(Browser::ActionController) if defined?(::ActionController::Metal) # rubocop:disable Layout/LineLength + + Browser::Middleware::Context.include( Browser::Middleware::Context::Additions ) end diff -Nru ruby-browser-2.5.3/lib/browser/safari.rb ruby-browser-4.2.0/lib/browser/safari.rb --- ruby-browser-2.5.3/lib/browser/safari.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/safari.rb 2020-06-19 05:24:10.000000000 +0000 @@ -11,14 +11,21 @@ end def full_version - ua[%r[Version/([\d.]+)], 1] || - ua[%r[Safari/([\d.]+)], 1] || - ua[%r[AppleWebKit/([\d.]+)], 1] || + ua[%r{Version/([\d.]+)}, 1] || + ua[%r{Safari/([\d.]+)}, 1] || + ua[%r{AppleWebKit/([\d.]+)}, 1] || "0.0" end def match? - ua =~ /Safari/ && ua !~ /Chrome|CriOS|PhantomJS|FxiOS/ + ua =~ /Safari/ && + ua !~ /PhantomJS|FxiOS/ && + !edge? && + !chrome? && + !samsung_browser? && + !duck_duck_go? && + !yandex? && + !sputnik? end end end diff -Nru ruby-browser-2.5.3/lib/browser/samsung_browser.rb ruby-browser-4.2.0/lib/browser/samsung_browser.rb --- ruby-browser-2.5.3/lib/browser/samsung_browser.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/samsung_browser.rb 2020-06-19 05:24:10.000000000 +0000 @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Browser + class SamsungBrowser < Chrome + def id + :samsung_browser + end + + def name + "Samsung Browser" + end + + def full_version + ua[%r{SamsungBrowser/([\d.]+)}, 1] || super + end + + def match? + ua =~ /SamsungBrowser/ + end + end +end diff -Nru ruby-browser-2.5.3/lib/browser/snapchat.rb ruby-browser-4.2.0/lib/browser/snapchat.rb --- ruby-browser-2.5.3/lib/browser/snapchat.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/snapchat.rb 2020-06-19 05:24:10.000000000 +0000 @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Browser + class Snapchat < Base + def id + :snapchat + end + + def name + "Snapchat" + end + + def full_version + ua[%r{Snapchat( ?|/)([\d.]+)}, 2] || "0.0" + end + + def match? + ua =~ /Snapchat/ + end + end +end diff -Nru ruby-browser-2.5.3/lib/browser/sputnik.rb ruby-browser-4.2.0/lib/browser/sputnik.rb --- ruby-browser-2.5.3/lib/browser/sputnik.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/sputnik.rb 2020-06-19 05:24:10.000000000 +0000 @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Browser + class Sputnik < Base + def id + :sputnik + end + + def name + "Sputnik" + end + + def full_version + ua[%r{SputnikBrowser/([\d.]+)}, 1] || "0.0" + end + + def match? + ua =~ /SputnikBrowser/ + end + end +end diff -Nru ruby-browser-2.5.3/lib/browser/uc_browser.rb ruby-browser-4.2.0/lib/browser/uc_browser.rb --- ruby-browser-2.5.3/lib/browser/uc_browser.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/uc_browser.rb 2020-06-19 05:24:10.000000000 +0000 @@ -11,7 +11,7 @@ end def full_version - ua[%r[UCBrowser/([\d.]+)], 1] || "0.0" + ua[%r{UCBrowser/([\d.]+)}, 1] || "0.0" end def match? diff -Nru ruby-browser-2.5.3/lib/browser/version.rb ruby-browser-4.2.0/lib/browser/version.rb --- ruby-browser-2.5.3/lib/browser/version.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/version.rb 2020-06-19 05:24:10.000000000 +0000 @@ -1,5 +1,5 @@ # frozen_string_literal: true module Browser - VERSION = "2.5.3".freeze + VERSION = "4.2.0" end diff -Nru ruby-browser-2.5.3/lib/browser/weibo.rb ruby-browser-4.2.0/lib/browser/weibo.rb --- ruby-browser-2.5.3/lib/browser/weibo.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/weibo.rb 2020-06-19 05:24:10.000000000 +0000 @@ -11,7 +11,7 @@ end def full_version - ua[%r[(?:__weibo__)([\d.]+)]i, 1] || "0.0" + ua[/(?:__weibo__)([\d.]+)/i, 1] || "0.0" end def match? diff -Nru ruby-browser-2.5.3/lib/browser/yandex.rb ruby-browser-4.2.0/lib/browser/yandex.rb --- ruby-browser-2.5.3/lib/browser/yandex.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser/yandex.rb 2020-06-19 05:24:10.000000000 +0000 @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Browser + class Yandex < Base + def id + :yandex + end + + def name + "Yandex" + end + + def full_version + ua[%r{YaBrowser/([\d.]+)}, 1] || "0.0" + end + + def match? + ua =~ /YaBrowser/ + end + end +end diff -Nru ruby-browser-2.5.3/lib/browser.rb ruby-browser-4.2.0/lib/browser.rb --- ruby-browser-2.5.3/lib/browser.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/lib/browser.rb 2020-06-19 05:24:10.000000000 +0000 @@ -1,4 +1,4 @@ # frozen_string_literal: true -require "browser/browser" -require "browser/rails" if defined?(::Rails) +require_relative "browser/browser" +require_relative "browser/rails" if defined?(::Rails) diff -Nru ruby-browser-2.5.3/.prettierignore ruby-browser-4.2.0/.prettierignore --- ruby-browser-2.5.3/.prettierignore 1970-01-01 00:00:00.000000000 +0000 +++ ruby-browser-4.2.0/.prettierignore 2020-06-19 05:24:10.000000000 +0000 @@ -0,0 +1 @@ +*.yml diff -Nru ruby-browser-2.5.3/Rakefile ruby-browser-4.2.0/Rakefile --- ruby-browser-2.5.3/Rakefile 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/Rakefile 2020-06-19 05:24:10.000000000 +0000 @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "bundler" require "bundler/setup" Bundler::GemHelper.install_tasks @@ -14,7 +16,14 @@ require "rubocop/rake_task" desc "Run rubocop" task :rubocop do - RuboCop::RakeTask.new + RuboCop::RakeTask.new do |t| + t.options += %w[ + --display-style-guide + --display-cop-names + --extra-details + --auto-correct + ] + end end desc "Run specs against all gemfiles" @@ -28,4 +37,4 @@ end end -task default: [:test, :rubocop] +task default: %i[test rubocop] diff -Nru ruby-browser-2.5.3/README.md ruby-browser-4.2.0/README.md --- ruby-browser-2.5.3/README.md 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/README.md 2020-06-19 05:24:10.000000000 +0000 @@ -1,6 +1,6 @@ # Browser -[![Travis-CI](https://travis-ci.org/fnando/browser.png)](https://travis-ci.org/fnando/browser) +[![Travis-CI](https://travis-ci.org/fnando/browser.svg)](https://travis-ci.org/fnando/browser) [![Code Climate](https://codeclimate.com/github/fnando/browser/badges/gpa.svg)](https://codeclimate.com/github/fnando/browser) [![Test Coverage](https://codeclimate.com/github/fnando/browser/badges/coverage.svg)](https://codeclimate.com/github/fnando/browser/coverage) [![Gem](https://img.shields.io/gem/v/browser.svg)](https://rubygems.org/gems/browser) @@ -25,6 +25,7 @@ browser.bot? browser.chrome? browser.core_media? +browser.duck_duck_go? browser.edge? # Newest MS browser browser.electron? # Electron Framework browser.firefox? @@ -34,7 +35,6 @@ browser.ie?([">8", "<10"]) # detect specific IE (IE9). browser.known? # has the browser been successfully detected? browser.meta # an array with several attributes -browser.modern? # Webkit, Firefox 17+, IE 9+ and Opera 12+ browser.name # readable browser name browser.nokia? browser.opera? @@ -43,19 +43,24 @@ browser.quicktime? browser.safari? browser.safari_webapp_mode? +browser.samsung_browser? browser.to_s # the meta info joined by space browser.uc_browser? browser.version # major version number browser.webkit? browser.webkit_full_version browser.yandex? -browser.wechat? # detect the MicroMessenger(WeChat) -browser.weibo? # detect Weibo embedded browser (Sina Weibo) +browser.wechat? +browser.weibo? +browser.yandex? +browser.sputnik? # Get bot info browser.bot.name browser.bot.search_engine? browser.bot? +browser.bot.why? # shows which matcher detected this user agent as a bot. +Browser::Bot.why?(ua) # Get device info browser.device @@ -81,6 +86,7 @@ browser.device.vita? browser.device.wii? browser.device.wiiu? +browser.device.switch? browser.device.xbox? browser.device.xbox_360? browser.device.xbox_one? @@ -140,23 +146,26 @@ - For a list of device detections, check [lib/browser/device.rb](https://github.com/fnando/browser/blob/master/lib/browser/device.rb) - For a list of bot detections, check [bots.yml](https://github.com/fnando/browser/blob/master/bots.yml) -### What defines a modern browser? - -The current rules that define a modern browser are pretty loose: +### Detecting modern browsers -* Webkit -* IE9+ -* Microsoft Edge -* Firefox 17+ -* Firefox Tablet 14+ -* Opera 12+ - -You can define your own rules. A rule must be a proc/lambda or any object that implements the method === and accepts the browser object. To redefine all rules, clear the existing rules before adding your own. +To detect whether a browser can be considered as modern or not, create a method that abstracts your versioning constraints. The following example will consider any of the following browsers as a modern: ```ruby -# Only Chrome Canary is considered modern. -Browser.modern_rules.clear -Browser.modern_rules << -> b { b.chrome? && b.version.to_i >= 37 } +# Expects an Browser instance, +# like in `Browser.new(user_agent, accept_language: language)`. +def modern_browser?(browser) + [ + browser.chrome?(">= 65"), + browser.safari?(">= 10"), + browser.firefox?(">= 52"), + browser.ie?(">= 11") && !browser.compatibility_view?, + browser.edge?(">= 15"), + browser.opera?(">= 50"), + browser.facebook? + && browser.safari_webapp_mode? + && browser.webkit_full_version.to_i >= 602 + ].any? +end ``` ### Rails integration @@ -209,7 +218,7 @@ #=> "English/United States" ``` -Result is always sorted in quality order from highest -> lowest. As per the HTTP spec: +Result is always sorted in quality order from highest to lowest. As per the HTTP spec: - omitting the quality value implies 1.0. - quality value equal to zero means that is not accepted by the client. @@ -235,16 +244,13 @@ browser.compatibility_view? #=> true - -browser.modern? -#=> false ``` This behavior changed in `v1.0.0`; previously there wasn't a way of getting the real browser version. ### Safari -iOS webviews and web apps aren't detect as Safari anymore, so be aware of that if that's your case. You can use a combination of platform and webkit detection to do whatever you want. +iOS webviews and web apps aren't detected as Safari anymore, so be aware of that if that's your case. You can use a combination of platform and webkit detection to do whatever you want. ```ruby # iPad's Safari running as web app mode. @@ -262,37 +268,46 @@ ### Bots -Browser used to detect empty user agents as bots, but this behavior has changed. If you want to bring this detection back, you can activate it through the following call: +The bot detection is quite aggressive. Anything that matches at least one of the following requirements will be considered a bot. + +- Empty user agent string +- User agent that matches `/crawl|fetch|search|monitoring|spider|bot/` +- Any known bot listed under [bots.yml](https://github.com/fnando/browser/blob/master/bots.yml) + +To add custom matchers, you can add a callable object to `Browser::Bot.matchers`. The following example matches everything that has a `externalhit` substring on it. The bot name will always be `General Bot`. ```ruby -Browser::Bot.detect_empty_ua! +Browser::Bot.matchers << ->(ua, _browser) { ua =~ /externalhit/i } ``` -### Middleware +To clear all matchers, including the ones that are bundled, use `Browser::Bot.matchers.clear`. You can re-add built-in matchers by doing the following: -You can use the `Browser::Middleware` to redirect user agents. +```ruby +Browser::Bot.matchers += Browser::Bot.default_matchers +``` + +To restore v2's bot detection, remove the following matchers: ```ruby -use Browser::Middleware do - redirect_to "/upgrade" unless browser.modern? -end +Browser::Bot.matchers.delete(Browser::Bot::KeywordMatcher) +Browser::Bot.matchers.delete(Browser::Bot::EmptyUserAgentMatcher) ``` -If you're using Rails, you can use the route helper methods. Just add something like the following to a initializer file (`config/initializers/browser.rb`). +### Middleware + +You can use the `Browser::Middleware` to redirect user agents. ```ruby -Rails.configuration.middleware.use Browser::Middleware do - redirect_to upgrade_path unless browser.modern? +use Browser::Middleware do + redirect_to "/upgrade" if browser.ie? end ``` -Notice that you can have multiple conditionals. +If you're using Rails, you can use the route helper methods. Just add something like the following to a initializer file (`config/initializers/browser.rb`). ```ruby Rails.configuration.middleware.use Browser::Middleware do - next if browser.bot.search_engine? - redirect_to upgrade_path(browser: "oldie") if browser.ie? && !browser.modern? - redirect_to upgrade_path(browser: "oldfx") if browser.firefox? && !browser.modern? + redirect_to upgrade_path if browser.ie? end ``` @@ -300,25 +315,10 @@ ```ruby Rails.configuration.middleware.use Browser::Middleware do - redirect_to upgrade_path unless browser.modern? || request.env["PATH_INFO"] == "/exclude_me" + redirect_to upgrade_path if browser.ie? && request.env["PATH_INFO"] != "/exclude_me" end ``` -### Migrating to v2 - -#### Troubleshooting - -##### `TypeError: no implicit conversion of Hash into String` - -The class constructor now has a different signature. Change the instantiation from `Browser.new(options)` to `Browser.new(ua, options)`, where: - -- `ua`: must be a string representing the user agent. -- `options`: must be a hash (for now it only accepts the `accept_language` option). - -##### `NoMethodError: undefined method 'user_agent'` - -`.ua` can now be used to retrieve the full User Agent string. - ## Development ### Versioning diff -Nru ruby-browser-2.5.3/.rubocop.yml ruby-browser-4.2.0/.rubocop.yml --- ruby-browser-2.5.3/.rubocop.yml 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/.rubocop.yml 2020-06-19 05:24:10.000000000 +0000 @@ -1,126 +1,38 @@ +--- +inherit_gem: + rubocop-fnando: .rubocop.yml + AllCops: + TargetRubyVersion: 2.5 Exclude: - - "bin/**/*" - - "gemfiles/**/*" - - "vendor/**/*" - - "Gemfile" - - "Rakefile" + - bin/**/* + - gemfiles/**/* + - vendor/**/* + - Gemfile + - Rakefile - "*.gemspec" - - "config.ru" - -Style/Alias: - EnforcedStyle: prefer_alias_method - -Style/FrozenStringLiteralComment: - EnforcedStyle: always - -Style/ClassCheck: - EnforcedStyle: kind_of? - -Metrics/LineLength: - Max: 80 - -Style/BlockDelimiters: - Enabled: false - -Style/RegexpLiteral: - Enabled: false - -Metrics/AbcSize: - Enabled: false - -Style/PerlBackrefs: - Enabled: false - -ClassLength: - Enabled: false - -CyclomaticComplexity: - Enabled: false - -Documentation: - Enabled: false - -Encoding: - Enabled: false + - config.ru -FileName: +Metrics/ClassLength: Enabled: false -IfUnlessModifier: - Enabled: false - -MethodLength: - Enabled: false - -ModuleFunction: - Enabled: false - -OneLineConditional: - Enabled: false - -ParameterLists: - Enabled: false - -Proc: - Enabled: false +Layout/LineLength: + Max: 80 -SingleLineBlockParams: +Metrics/MethodLength: Enabled: false -VariableInterpolation: - Enabled: false +Style/Alias: + EnforcedStyle: prefer_alias_method -Style/TrailingCommaInLiteral: +Lint/RedundantCopDisableDirective: Enabled: false -WhileUntilModifier: +Metrics/AbcSize: Enabled: false -PredicateName: - NamePrefixBlacklist: - - is_ - -StringLiterals: - EnforcedStyle: double_quotes - SupportedStyles: - - single_quotes - - double_quotes - -DotPosition: - EnforcedStyle: leading - -SpaceBeforeBlockBraces: - EnforcedStyle: space - -SpaceInsideBlockBraces: - EnforcedStyle: no_space - -DoubleNegation: +Metrics/CyclomaticComplexity: Enabled: false -SpaceInsideBlockBraces: - SpaceBeforeBlockParameters: false - -SpaceInsideHashLiteralBraces: +Metrics/PerceivedComplexity: Enabled: false - -PercentLiteralDelimiters: - PreferredDelimiters: - '%': '[]' - '%i': '[]' - '%q': '[]' - '%Q': '[]' - '%r': '[]' - '%s': '[]' - '%w': '[]' - '%W': '[]' - '%x': '[]' - -Style/CollectionMethods: - PreferredMethods: - collect: 'map' - collect!: 'map!' - inject: 'reduce' - detect: 'find' - find_all: 'select' diff -Nru ruby-browser-2.5.3/search_engines.yml ruby-browser-4.2.0/search_engines.yml --- ruby-browser-2.5.3/search_engines.yml 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/search_engines.yml 2020-06-19 05:24:10.000000000 +0000 @@ -1,6 +1,6 @@ +ask jeeves: "Ask Jeeves" baidu: "Chinese search engine" bingbot: "Microsoft bing bot" +duckduckbot: "Duck Duck Go" googlebot: "Google spider" slurp: "Yahoo spider" -duckduckbot: "Duck Duck Go" -ask jeeves: "Ask Jeeves" diff -Nru ruby-browser-2.5.3/test/browser_test.rb ruby-browser-4.2.0/test/browser_test.rb --- ruby-browser-2.5.3/test/browser_test.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/test/browser_test.rb 2020-06-19 05:24:10.000000000 +0000 @@ -39,7 +39,6 @@ assert browser.platform.android? assert browser.safari? assert browser.webkit? - assert browser.modern? assert_equal "3.1.2", browser.full_version assert_equal "3", browser.version end @@ -51,7 +50,6 @@ assert browser.platform.android? assert browser.safari? assert browser.webkit? - assert browser.modern? assert_equal "4.0", browser.full_version assert_equal "4", browser.version end @@ -62,7 +60,6 @@ assert_equal "Internet Explorer", browser.name assert browser.device.surface? assert browser.ie? - assert browser.modern? assert_equal "10.0", browser.full_version assert_equal "10", browser.version end @@ -93,7 +90,6 @@ assert_equal "PhantomJS", browser.name assert_equal :phantom_js, browser.id assert browser.phantom_js? - assert browser.modern? assert_equal "1.9.0", browser.full_version assert_equal "1", browser.version assert browser.phantom_js?(%w[>=1 <2]) @@ -105,6 +101,11 @@ assert_equal "0", browser.version end + test "ignores malformed strings when comparing versions" do + browser = Browser.new("Chrome/65.0.3325.99.FreeBrowser.3.0.5") + refute browser.chrome?(">=65") + end + test "detects unknown id" do browser = Browser.new("Unknown") assert_equal :generic, browser.id @@ -132,7 +133,7 @@ browser = Browser.new("", accept_language: accept_language) languages = browser.accept_language.map(&:full) - assert_equal ["en-US", "en", "pt-BR", "pt"], languages + assert_equal %w[en-US en pt-BR pt], languages end test "removes duplicate items" do diff -Nru ruby-browser-2.5.3/test/rails_test.rb ruby-browser-4.2.0/test/rails_test.rb --- ruby-browser-2.5.3/test/rails_test.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/test/rails_test.rb 2020-06-19 05:24:10.000000000 +0000 @@ -19,4 +19,14 @@ assert_equal 200, last_response.status assert_equal "Chrome:en-US", last_response.body end + + test "renders json" do + get "/api/pages", {}, "HTTP_USER_AGENT" => Browser["COMMONCRAWL"], + "HTTP_ACCEPT" => "application/json", + "HTTP_ACCEPT_LANGUAGE" => "en-US;q=0.8" + + assert_equal 200, last_response.status + assert_equal true, JSON.parse(last_response.body)["isBot"] + assert_equal "en-US", JSON.parse(last_response.body)["acceptLanguages"][0] + end end diff -Nru ruby-browser-2.5.3/test/sample_app.rb ruby-browser-4.2.0/test/sample_app.rb --- ruby-browser-2.5.3/test/sample_app.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/test/sample_app.rb 2020-06-19 05:24:10.000000000 +0000 @@ -9,12 +9,24 @@ end end +class PotsController < ActionController::API + def index + render json: { + isBot: browser.bot?, + acceptLanguages: browser.accept_language.map(&:full) + } + end +end + class SampleApp < Rails::Application config.secret_token = "99f19f08db7a37bdcb9d6701f54dca" config.secret_key_base = "99f19f08db7a37bdcb9d6701f54dca" config.eager_load = true config.active_support.deprecation = :log + # Introduced by Rails 6. + config.hosts << "example.org" if config.respond_to?(:hosts) + routes.append do default_headers = {"Content-Type" => "text/html"} @@ -29,6 +41,8 @@ } get "/home", to: "pages#home" + + get "/api/pages", to: "pots#index" end config.middleware.use Browser::Middleware do diff -Nru ruby-browser-2.5.3/test/test_helper.rb ruby-browser-4.2.0/test/test_helper.rb --- ruby-browser-2.5.3/test/test_helper.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/test/test_helper.rb 2020-06-19 05:24:10.000000000 +0000 @@ -3,7 +3,7 @@ require "simplecov" SimpleCov.start -ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", __FILE__) +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) require "bundler/setup" require "minitest/autorun" require "minitest/utils" @@ -24,3 +24,11 @@ end end end + +# Override Browser::Base#warn, so we don't output deprecation messages. +module Browser + class Base + def warn(*) + end + end +end diff -Nru ruby-browser-2.5.3/test/ua_bots.yml ruby-browser-4.2.0/test/ua_bots.yml --- ruby-browser-2.5.3/test/ua_bots.yml 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/test/ua_bots.yml 2020-06-19 05:24:10.000000000 +0000 @@ -1,68 +1,104 @@ -ADLXBOT: 'Mozilla/5.0 (compatible; adidxbot/2.0; +http://www.bing.com/bingbot.htm)' -ANDERSPINK: 'Mozilla/5.0 (compatible; AndersPinkBot/1.0; +http://anderspink.com/bot.html)' -APIS_GOOGLE: 'APIs-Google; (+https://developers.google.com/webmasters/APIs-Google.html)' -APPLE_BOT: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/600.2.5 (KHTML, like Gecko) Version/8.0.2 Safari/600.2.5 (Applebot/0.1)' -ASK: 'Mozilla/2.0 (compatible; Ask Jeeves/Teoma; +http://sp.ask.com/docs/about/tech_crawling.html)' +--- +ADLXBOT: "Mozilla/5.0 (compatible; adidxbot/2.0; +http://www.bing.com/bingbot.htm)" +ADS_TXT_CRAWLER: "AdsTxtCrawler/1.0" +ANDERSPINK: "Mozilla/5.0 (compatible; AndersPinkBot/1.0; +http://anderspink.com/bot.html)" +APIS_GOOGLE: "APIs-Google; (+https://developers.google.com/webmasters/APIs-Google.html)" +APPLE_BOT: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/600.2.5 (KHTML, like Gecko) Version/8.0.2 Safari/600.2.5 (Applebot/0.1)" +ARCHIVEBOT: "ArchiveTeam ArchiveBot/20190617.01 (wpull 2.0.3) and not Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36" +ASK: "Mozilla/2.0 (compatible; Ask Jeeves/Teoma; +http://sp.ask.com/docs/about/tech_crawling.html)" AWS_ELB: ELB-HealthChecker/1.0 -BAIDU: 'Baiduspider+(+http://www.baidu.com/search/spider.htm)' -BARKROWLER: 'Barkrowler/0.7 (+http://www.exensa.com/crawl)' -BINGBOT: 'Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)' -BINGPREVIEW: 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534+ (KHTML, like Gecko) BingPreview/1.0b' -BUBING: 'BUbiNG (+http://law.di.unimi.it/BUbiNG.html)' -BUZZBOT: 'Buzzbot/1.0 (Buzzbot; http://www.buzzstream.com; buzzbot@buzzstream.com)' -CIPACRAWLER: 'CipaCrawler/3.0 (info@domaincrawler.com; http://www.domaincrawler.com/www.example.com)' +BAIDU: "Baiduspider+(+http://www.baidu.com/search/spider.htm)" +BARKROWLER: "Barkrowler/0.7 (+http://www.exensa.com/crawl)" +BINGBOT: "Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)" +BINGPREVIEW: "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534+ (KHTML, like Gecko) BingPreview/1.0b" +BUBING: "BUbiNG (+http://law.di.unimi.it/BUbiNG.html)" +BUZZBOT: "Buzzbot/1.0 (Buzzbot; http://www.buzzstream.com; buzzbot@buzzstream.com)" +CHROME_LIGHTHOUSE: "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3694.0 Mobile Safari/537.36 Chrome-Lighthouse" +CIPACRAWLER: "CipaCrawler/3.0 (info@domaincrawler.com; http://www.domaincrawler.com/www.example.com)" CLOUDFLARE: "Mozilla/5.0 (compatible; CloudFlare-AlwaysOnline/1.0; +http://www.cloudflare.com/always-online) AppleWebKit/534.34" -COMMONCRAWL: 'CCBot/2.0 (http://commoncrawl.org/faq/)' -COMODO_SSL_CHECKER: 'COMODO SSL Checker' -COPYPANTS: 'Mozilla/5.0 (compatible; BotPants/1.0; Linux; +info@copypants.com) KHTML/3.5.5 (like Gecko)' -DAUMOA: Mozilla/5.0 (compatible; MSIE or Firefox mutant; not on Windows server;) Daumoa 4.0 -DOMAINAREANIMATOR: 'Domain Re-Animator Bot (http://domainreanimator.com) - support@domainreanimator.com' -DOT_BOT: 'Mozilla/5.0 (compatible; DotBot/1.1; http://www.opensiteexplorer.org/dotbot, help@moz.com)' -DUCKDUCKGO: 'DuckDuckBot/1.0; (+http://duckduckgo.com/duckduckbot.html)' -FACEBOOK_BOT: 'facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)' -GOOGLE_BOT: 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)' -GOOGLE_PAGE_SPEED_INSIGHTS: 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.4 (KHTML, like Gecko; Google Page Speed Insights) Chrome/22.0.1229 Safari/537.4' +COMMONCRAWL: "CCBot/2.0 (http://commoncrawl.org/faq/)" +COMODO_SSL_CHECKER: "COMODO SSL Checker" +COPYPANTS: "Mozilla/5.0 (compatible; BotPants/1.0; Linux; +info@copypants.com) KHTML/3.5.5 (like Gecko)" +DATAFEEDWATCH: "Datafeedwatch/2.1.x" +DATANYZE: "Mozilla/5.0 (X11; Datanyze; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36" +DAUMOA: "Mozilla/5.0 (compatible; MSIE or Firefox mutant; not on Windows server;) Daumoa 4.0" +DOMAINAREANIMATOR: "Domain Re-Animator Bot (http://domainreanimator.com) - support@domainreanimator.com" +DOT_BOT: "Mozilla/5.0 (compatible; DotBot/1.1; http://www.opensiteexplorer.org/dotbot, help@moz.com)" +DUCKDUCKGO: "DuckDuckBot/1.0; (+http://duckduckgo.com/duckduckbot.html)" +EZPUBLISH: "eZ Publish Link Validator" +FACEBOOK_BOT: "facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)" +FYREBOT: "Fyrebot/1.0" +GARLIK: "GarlikCrawler/1.2 (http://garlik.com/, crawler@garlik.com)" +GERMCRAWLER: "GermCrawler" +GO_1.1_PACKAGE_HTTP: "Go 1.1 package http" +GO_HTTP_CLIENT: "Go-http-client" +GOOGLE_BOT: "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" +GOOGLE_IMAGE_PROXY: "Mozilla/5.0 (Windows NT 5.1; rv:11.0) Gecko Firefox/11.0 (via ggpht.com GoogleImageProxy)" +GOOGLE_PAGE_SPEED_INSIGHTS: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.4 (KHTML, like Gecko; Google Page Speed Insights) Chrome/22.0.1229 Safari/537.4" +GOOGLE_SHOPPING: "google-xrawler" GOOGLE_SITE_VERIFICATION: Mozilla/5.0 (compatible; Google-Site-Verification/1.0) -GOOGLE_STACKDRIVER_UPTIME_CHECKS: 'GoogleStackdriverMonitoring-UptimeChecks' -GOOGLE_STRUCTURED_DATA_TESTING_TOOL2: 'Mozilla/5.0 (compatible; Google-Structured-Data-Testing-Tool +http://developers.google.com/structured-data/testing-tool/)' -GOOGLE_STRUCTURED_DATA_TESTING_TOOL: 'Mozilla/5.0 (compatible; X11; Linux x86_64; Google-StructuredDataTestingTool; +http://www.google.com/webmasters/tools/richsnippets)' -GRAPESHOT: 'Mozilla/5.0 (compatible; GrapeshotCrawler/2.0; +http://www.grapeshot.co.uk/crawler.php)' -JOBSEEKER: 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/538.1 (KHTML, like Gecko) JobBot/5.0 (compatible; +http://www.jobseeker.com.au/bot.html) Safari/538.1' -LINKDEXBOT: 'Mozilla/5.0 (compatible; linkdexbot/2.0; +http://www.linkdex.com/bots/)' -LOAD_TIME_BOT: 'Mozilla/5.0 (compatible; LoadTimeBot/0.9; +http://www.loadtime.net/bot.html)' -LTX71: 'ltx71 - (http://ltx71.com/)' -MAIL_RU: 'Mozilla/5.0 (compatible; Linux x86_64; Mail.RU_Bot/2.0; +http://go.mail.ru/help/robots)' -MAPPYDATA: 'Mozilla/5.0 (compatible; Mappy/1.0; +http://mappydata.net/bot/)' -MEGAINDEX_RU: 'Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)' -MRCHROME: 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.107 Amigo/45.0.2454.107 MRCHROME SOC Safari/537.36' -MSNBOT: 'msnbot/2.0b (+http://search.msn.com/msnbot.htm)' -MSNBOT_MEDIA: 'msnbot-media/1.1 (+http://search.msn.com/msnbot.htm)' +GOOGLE_STACKDRIVER_UPTIME_CHECKS: "GoogleStackdriverMonitoring-UptimeChecks" +GOOGLE_STRUCTURED_DATA_TESTING_TOOL2: "Mozilla/5.0 (compatible; Google-Structured-Data-Testing-Tool +http://developers.google.com/structured-data/testing-tool/)" +GOOGLE_STRUCTURED_DATA_TESTING_TOOL: "Mozilla/5.0 (compatible; X11; Linux x86_64; Google-StructuredDataTestingTool; +http://www.google.com/webmasters/tools/richsnippets)" +GRAPESHOT: "Mozilla/5.0 (compatible; GrapeshotCrawler/2.0; +http://www.grapeshot.co.uk/crawler.php)" +HTTRACK: "Mozilla/4.5 (compatible; HTTrack 3.0x; Windows 98)" +IMPLISENSEBOT: "ImplisenseBot 1.0" +JAUNT: "Jaunt/1.5" +JOBSEEKER: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/538.1 (KHTML, like Gecko) JobBot/5.0 (compatible; +http://www.jobseeker.com.au/bot.html) Safari/538.1" +JOOBLE: "Mozilla/5.0 (compatible; Jooblebot/2.0; Windows NT 6.1; WOW64; +http://jooble.org/jooble-bot) Mobile" +KNOWLEDGE_AI: "The Knowledge AI" +LINKDEXBOT: "Mozilla/5.0 (compatible; linkdexbot/2.0; +http://www.linkdex.com/bots/)" +LINKEDIN: "LinkedInBot/1.0 (compatible; Mozilla/5.0; Jakarta Commons-HttpClient/3.1 +http://www.linkedin.com)" +LOAD_TIME_BOT: "Mozilla/5.0 (compatible; LoadTimeBot/0.9; +http://www.loadtime.net/bot.html)" +LTX71: "ltx71 - (http://ltx71.com/)" +MAIL_RU: "Mozilla/5.0 (compatible; Linux x86_64; Mail.RU_Bot/2.0; +http://go.mail.ru/help/robots)" +MAPPYDATA: "Mozilla/5.0 (compatible; Mappy/1.0; +http://mappydata.net/bot/)" +MASTODONBOT: "http.rb/3.0.0 (Mastodon/2.2.0; +https://mstdn.io/)" +MAUIBOT: "MauiBot (crawler.feedback+wc@gmail.com)" +MEGAINDEX_RU: "Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +https://www.megaindex.ru/?tab=linkAnalyze)" +MSNBOT: "msnbot/2.0b (+http://search.msn.com/msnbot.htm)" +MSNBOT_MEDIA: "msnbot-media/1.1 (+http://search.msn.com/msnbot.htm)" NETCRAFT2: Netcraft SSL Server Survey - contact info@netcraft.com NETCRAFT: Mozilla/5.0 (compatible; NetcraftSurveyAgent/1.0; +info@netcraft.com) NEWRELICPINGER: NewRelicPinger/1.0 (12345) PAESSLER: Mozilla/5.0 (compatible; PRTG Network Monitor (www.paessler.com); Windows) -PRIVACYAWAREBOT: 'Mozilla/5.0 (compatible; PrivacyAwareBot/1.1; +http://www.privacyaware.org)' -PROXIMIC: 'Mozilla/5.0 (compatible; proximic; +http://www.proximic.com/info/spider.php)' -QUERYSEEKER: 'QuerySeekerSpider ( http://queryseeker.com/bot.html )' -SCRAPY: 'Scrapy/0.18.4 (+http://scrapy.org)' -SEMANTICBOT: 'Mozilla/5.0 (compatible; Semanticbot/1.0; +http://sempi.tech/bot.html)' -SEO_AUDIT: 'Mozilla/5.0 (compatible; seo-audit-check-bot/1.0)' -SEODIVER: 'Mozilla/5.0 (compatible; SEOdiver/1.0; +http://www.seodiver.com/bot)' -SEOKICKS: 'Mozilla/5.0 (compatible; SEOkicks-Robot; +http://www.seokicks.de/robot.html)' -SISTRIX: 'Mozilla/5.0 (compatible; SISTRIX Crawler; http://crawler.sistrix.net/)' +PR-CY_RU: Mozilla/5.0 (compatible; PR-CY.RU; + https://a.pr-cy.ru) +PRIVACYAWAREBOT: "Mozilla/5.0 (compatible; PrivacyAwareBot/1.1; +http://www.privacyaware.org)" +PROXIMIC: "Mozilla/5.0 (compatible; proximic; +http://www.proximic.com/info/spider.php)" +PUINCRAWLER: "Pu_iN Crawler (+http://semanticjuice.com/)" +QUERYSEEKER: "QuerySeekerSpider ( http://queryseeker.com/bot.html )" +QUICKCRAWLER: "Quick-Crawler (+https://www.scrapinghub.com/)" +SCOUT_URL_MONITOR: ScoutURLMonitor/6.2.2 +SCRAPY: "Scrapy/0.18.4 (+http://scrapy.org)" +SEMANTICBOT: "Mozilla/5.0 (compatible; Semanticbot/1.0; +http://sempi.tech/bot.html)" +SEO_AUDIT: "Mozilla/5.0 (compatible; seo-audit-check-bot/1.0)" +SEOBILITYBOT: "SeobilityBot (SEO Tool; https://www.seobility.net/sites/bot.html)" +SEODIVER: "Mozilla/5.0 (compatible; SEOdiver/1.0; +http://www.seodiver.com/bot)" +SEOKICKS: "Mozilla/5.0 (compatible; SEOkicks-Robot; +http://www.seokicks.de/robot.html)" +SISTRIX: "Mozilla/5.0 (compatible; SISTRIX Crawler; http://crawler.sistrix.net/)" +SITECHECK: "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.0) SiteCheck-sitecrawl by Siteimprove.com" +SKYPE: "Mozilla/5.0 (Windows NT 6.1; WOW64) SkypeUriPreview Preview/0.5" SOCIALRANKIO: SocialRankIOBot; http://socialrank.io/about -SQUIDER: 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36 Squider/0.01' -STRIPE: 'Stripe/1.0 (+https://stripe.com/docs/webhooks)' -SWIFTYPE: 'Swiftbot' -TEERAID: 'Mozilla/5.0 (compatible; TeeRaidBot; +https://teeraid.com/bot/)' -TINEYE: 'TinEye-bot/0.51 (see http://www.tineye.com/crawler.html)' -TRAACKR: 'Traackr.com' -WATCHSUMO: 'Mozilla/5.0 (compatible) WatchSumo/1.0.0 (http://www.watchsumo.com)' -WEBCEO: 'Mozilla/5.0 (compatible; online-webceo-bot/1.0; +http://online.webceo.com)' -WHATSAPP: 'WhatsApp/2.17.38 Mozilla/5.0 (Linux; U; Android 6.1; en-us; DV Build/Donut) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36' -WORIOBOT: 'Mozilla/5.0 (compatible; woriobot +http://worio.com)' -YAHOO_AD_MONITORING: 'Mozilla/5.0 (compatible; Yahoo Ad monitoring; https://help.yahoo.com/kb/yahoo-ad-monitoring-SLN24857.html)' -YAHOO_SLURP: 'Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)' -YANDEX_DIRECT: 'Mozilla/5.0 (compatible; YandexDirect/3.0; +http://yandex.com/bots)' -YANDEX_METRIKA: 'Mozilla/5.0 (compatible; YandexMetrika/3.0; +http://yandex.com/bots)' -YANGA: 'Yanga WorldSearch Bot v1.1/beta (http://www.yanga.co.uk/)' +SQUIDER: "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36 Squider/0.01" +STRIPE: "Stripe/1.0 (+https://stripe.com/docs/webhooks)" +SWIFTYPE: "Swiftbot" +TANGIBLEEBOT: "TangibleeBot" +TEERAID: "Mozilla/5.0 (compatible; TeeRaidBot; +https://teeraid.com/bot/)" +TINEYE: "TinEye-bot/0.51 (see http://www.tineye.com/crawler.html)" +TRAACKR: "Traackr.com" +TRENDSMAP: "Mozilla/5.0 (compatible; TrendsmapResolver/0.1)" +UPDOWN_MONITOR: "updown.io daemon 2.2" +WATCHSUMO: "Mozilla/5.0 (compatible) WatchSumo/1.0.0 (http://www.watchsumo.com)" +WEBCEO: "Mozilla/5.0 (compatible; online-webceo-bot/1.0; +http://online.webceo.com)" +WHATSAPP: "WhatsApp/2.17.38 Mozilla/5.0 (Linux; U; Android 6.1; en-us; DV Build/Donut) AppleWebKit/537.36 (KHTML, like Gecko) Safari/537.36" +WIKIDO: "WikiDo/1.1 (http://wikido.com; crawler@wikido.com)" +WOORANK: "Mozilla/5.0 (compatible; woorankreview/2.0; +https://www.woorank.com/)" +WORIOBOT: "Mozilla/5.0 (compatible; woriobot +http://worio.com)" +YAHOO_AD_MONITORING: "Mozilla/5.0 (compatible; Yahoo Ad monitoring; https://help.yahoo.com/kb/yahoo-ad-monitoring-SLN24857.html)" +YAHOO_SLURP: "Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)" +YANDEX_DIRECT: "Mozilla/5.0 (compatible; YandexDirect/3.0; +http://yandex.com/bots)" +YANDEX_METRIKA: "Mozilla/5.0 (compatible; YandexMetrika/3.0; +http://yandex.com/bots)" +YANGA: "Yanga WorldSearch Bot v1.1/beta (http://www.yanga.co.uk/)" +ZABBIX: "Zabbix" +ZOOMBOT: "ZoomBot (Linkbot 1.0 http://suite.seozoom.it/bot.html)" +ZOOMINFOBOT: "ZoominfoBot (zoominfobot at zoominfo dot com)" diff -Nru ruby-browser-2.5.3/test/ua_search_engines.yml ruby-browser-4.2.0/test/ua_search_engines.yml --- ruby-browser-2.5.3/test/ua_search_engines.yml 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/test/ua_search_engines.yml 2020-06-19 05:24:10.000000000 +0000 @@ -1,6 +1,7 @@ -ASK: 'Mozilla/2.0 (compatible; Ask Jeeves/Teoma; +http://sp.ask.com/docs/about/tech_crawling.html)' -BAIDU: 'Baiduspider+(+http://www.baidu.com/search/spider.htm)' -BINGBOT: 'Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)' -DUCKDUCKGO: 'DuckDuckBot/1.0; (+http://duckduckgo.com/duckduckbot.html)' -GOOGLE_BOT: 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)' -YAHOO_SLURP: 'Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)' +--- +ASK: "Mozilla/2.0 (compatible; Ask Jeeves/Teoma; +http://sp.ask.com/docs/about/tech_crawling.html)" +BAIDU: "Baiduspider+(+http://www.baidu.com/search/spider.htm)" +BINGBOT: "Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)" +DUCKDUCKGO: "DuckDuckBot/1.0; (+http://duckduckgo.com/duckduckbot.html)" +GOOGLE_BOT: "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" +YAHOO_SLURP: "Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)" diff -Nru ruby-browser-2.5.3/test/ua.yml ruby-browser-4.2.0/test/ua.yml --- ruby-browser-2.5.3/test/ua.yml 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/test/ua.yml 2020-06-19 05:24:10.000000000 +0000 @@ -1,7 +1,8 @@ -ADOBE_AIR: 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X; de) AppleWebKit/533.19.4 (KHTML, like Gecko) AdobeAIR/13.0' +--- +ADOBE_AIR: "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; de) AppleWebKit/533.19.4 (KHTML, like Gecko) AdobeAIR/13.0" ALIPAY_ANDROID: "Mozilla/5.0 (Linux; U; Android 4.2.1; zh-cn; HUAWEI G610-T00 Build/HuaweiG610-T00) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30 AlipayDefined(nt:WIFI,ws:360|640|1.5) AliApp(AP/9.0.1.073001) AlipayClient/9.0.1.073001 GCanvas/1.4.2.15" ALIPAY_IOS: "Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53 AliApp(AP/2.3.4) AlipayClient/2.3.4" -ANDROID: 'Android SDK 1.5r3: Mozilla/5.0 (Linux; U; Android 1.5; de-; sdk Build/CUPCAKE) AppleWebkit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1' +ANDROID: "Android SDK 1.5r3: Mozilla/5.0 (Linux; U; Android 1.5; de-; sdk Build/CUPCAKE) AppleWebkit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1" ANDROID_CUPCAKE: Mozilla/5.0 (Linux; U; Android 1.5; en-gb; T-Mobile G1 Build/CRC1) AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1 ANDROID_DONUT: Mozilla/5.0 (Linux; U; Android 1.6; ar-us; SonyEricssonX10i Build/R2BA026) AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1 ANDROID_ECLAIR_21: Mozilla/5.0 (Linux; U; Android 2.1; en-us; Nexus One Build/ERD62) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17 @@ -17,120 +18,143 @@ ANDROID_LOLLIPOP_51: Mozilla/5.0 (Linux; Android 5.1; Nexus 5 Build/LMY47I) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/40.0.0.0 Mobile Safari/537.36; DailymotionEmbedSDK 1.0 ANDROID_NEXUS_PLAYER: Mozilla/5.0 (Linux; Android 5.0; Nexus Player Build/LRX21V) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.0 ANDROID_OREO: Mozilla/5.0 (Linux; Android 8.0.0; Pixel Build/OPR6.170623.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.03112.107 Mobile Safari/537.36 +ANDROID_Q: Mozilla/5.0 (Linux; Android 10; Pixel 2 Build/QQ1A.191205.008; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Mobile Safari/537.36 ANDROID_TV: Mozilla/5.0 (Linux; Android 5.0; ADT-1 Build/LRW87K) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/37.0.0.0 Mobile Safari/537.36 ANDROID_WEBVIEW: Mozilla/5.0 (Linux; Android 5.1.1; Nexus 5 Build/LMY48B; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/43.0.2357.65 Mobile Safari/537.36 -ANDROID_WITH_SAFARI: 'Mozilla/5.0 (Linux; U; Android 4.3; en-us; SCH-I535 Build/JSS15J) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30' -BLACKBERRY10: 'Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.0.9.1675 Mobile Safari/537.10+' -BLACKBERRY4: 'BlackBerry8100/4.2.1 Profile/MIDP-2.0 Configuration/CLDC-1.1 VendorID/103' -BLACKBERRY5: 'BlackBerry9000/5.0.0.93 Profile/MIDP-2.0 Configuration/CLDC-1.1 VendorID/179' -BLACKBERRY6: 'Mozilla/5.0 (BlackBerry; U; BlackBerry AAAA; en-US) AppleWebKit/534.11+ (KHTML, like Gecko) Version/6.0.0.141 Mobile Safari/534.11+' -BLACKBERRY7: 'Mozilla/5.0 (BlackBerry; U; BlackBerry AAAA; en-US) AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.0.0.1 Mobile Safari/534.11+' -BLACKBERRY: 'BlackBerry7100i/4.1.0 Profile/MIDP-2.0 Configuration/CLDC-1.1 VendorID/103' -CHROME: 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-US) AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.99 Safari/533.4' -CHROME_OS: 'Mozilla/5.0 (X11; CrOS x86_64 3701.81.0) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.57 Safari/537.31.' -COREMEDIA: 'Apple Mac OS X v10.6.4 CoreMedia v1.0.0.10F569' +ANDROID_WITH_SAFARI: "Mozilla/5.0 (Linux; U; Android 4.3; en-us; SCH-I535 Build/JSS15J) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30" +BLACKBERRY10: "Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.0.9.1675 Mobile Safari/537.10+" +BLACKBERRY4: "BlackBerry8100/4.2.1 Profile/MIDP-2.0 Configuration/CLDC-1.1 VendorID/103" +BLACKBERRY5: "BlackBerry9000/5.0.0.93 Profile/MIDP-2.0 Configuration/CLDC-1.1 VendorID/179" +BLACKBERRY6: "Mozilla/5.0 (BlackBerry; U; BlackBerry AAAA; en-US) AppleWebKit/534.11+ (KHTML, like Gecko) Version/6.0.0.141 Mobile Safari/534.11+" +BLACKBERRY7: "Mozilla/5.0 (BlackBerry; U; BlackBerry AAAA; en-US) AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.0.0.1 Mobile Safari/534.11+" +BLACKBERRY: "BlackBerry7100i/4.1.0 Profile/MIDP-2.0 Configuration/CLDC-1.1 VendorID/103" +CHROME: "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-US) AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.99 Safari/533.4" +CHROME_OS: "Mozilla/5.0 (X11; CrOS x86_64 3701.81.0) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.57 Safari/537.31." +COREMEDIA: "Apple Mac OS X v10.6.4 CoreMedia v1.0.0.10F569" CUSTOM_APP: "Our App 0.0.1 (Linux; Android 4.0.3; HTC Ruby Build/IML74K; en_CA)" +DUCKDUCKGO_BROWSER_IOS: "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 DuckDuckGo/7" +DUCKDUCKGO_BROWSER_ANDROID: Mozilla/5.0 (Linux; Android 10) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.96 Mobile Safari/537.36 DuckDuckGo/5" ELECTRON: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Electron/1.4.12 Safari/537.36" FACEBOOK: Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, like Gecko) Mobile/14G60 [FBAN/FBIOS;FBAV/135.0.0.45.90;FBBV/66877072;FBDV/iPhone9,3;FBMD/iPhone;FBSN/iOS;FBSV/10.3.3;FBSS/2;FBCR/AT&T;FBID/phone;FBLC/en_US;FBOP/5;FBRV/0] -FIREFOX: 'Mozilla/5.0 (X11; U; Linux i686; pl-PL; rv:1.9.0.2) Gecko/20121223 Ubuntu/9.25 (jaunty) Firefox/3.8' -FIREFOX_ANDROID: 'Mozilla/5.0 (Android; Mobile; rv:40.0) Gecko/40.0 Firefox/40.0' -FIREFOX_IOS: 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_2 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) FxiOS/1.2 Mobile/13C75 Safari/601.1.46' -FIREFOX_MODERN: 'Mozilla/5.0 (X11; Ubuntu; Linux armv7l; rv:17.0) Gecko/20100101 Firefox/17.0' -FIREFOX_OS: 'Mozilla/5.0 (Mobile; rv:18.0) Gecko/18.0 Firefox/18.0' -FIREFOX_TABLET: 'Mozilla/5.0 (Android; Tablet; rv:14.0) Gecko/14.0 Firefox/14.0' -IE10: 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0; EIE10;ENUSMSN)' -IE10_COMPAT: 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/6.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; EIE10;ENUSMSN)' -IE10_X64_WINX64: 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Win64; x64; Trident/6.0)' -IE11: 'Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko' -IE11_COMPAT: 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.3; WOW64; Trident/7.0; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729)' -IE11_TOUCH_SCREEN: 'Mozilla/5.0 (Windows NT 6.3; Win64; x64; Trident/7.0; Touch; rv:11.0) like Gecko' -IE6: 'Mozilla/5.0 (Windows; U; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)' -IE7: 'Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 6.0; en-US)' -IE8: 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.2; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)' -IE8_COMPAT: 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Trident/4.0; SLCC1; Media Center PC 5.0; .NET CLR 3.5.21022)' -IE9: 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)' -IE9_CHROME_FRAME: 'Mozilla/5.0 (Windows NT 6.1; WOW64; chromeframe/26.0.1410.43) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.43 Safari/537.31' -IE9_COMPAT: 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Trident/5.0)' +FACEBOOK_ANDROID: "Mozilla/5.0 (Linux; Android 9; ONEPLUS A6003 Build/PKQ1.180716.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/73.0.3683.90 Mobile Safari/537.36 [FB_IAB/FB4A;FBAV/214.0.0.43.83;]" +FACEBOOK_IOS: "Mozilla/5.0 (iPhone; CPU iPhone OS 12_1_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/16D57 [FBAN/FBIOS;FBDV/iPhone11,2;FBMD/iPhone;FBSN/iOS;FBSV/12.1.4;FBSS/3;FBCR/KPN NL;FBID/phone;FBLC/en_GB;FBOP/5]" +FIREFOX: "Mozilla/5.0 (X11; U; Linux i686; pl-PL; rv:1.9.0.2) Gecko/20121223 Ubuntu/9.25 (jaunty) Firefox/3.8" +FIREFOX_ANDROID: "Mozilla/5.0 (Android; Mobile; rv:40.0) Gecko/40.0 Firefox/40.0" +FIREFOX_IOS: "Mozilla/5.0 (iPhone; CPU iPhone OS 9_2 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) FxiOS/1.2 Mobile/13C75 Safari/601.1.46" +FIREFOX_MODERN: "Mozilla/5.0 (X11; Ubuntu; Linux armv7l; rv:17.0) Gecko/20100101 Firefox/17.0" +FIREFOX_OS: "Mozilla/5.0 (Mobile; rv:18.0) Gecko/18.0 Firefox/18.0" +FIREFOX_TABLET: "Mozilla/5.0 (Android; Tablet; rv:14.0) Gecko/14.0 Firefox/14.0" +IE10: "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0; EIE10;ENUSMSN)" +IE10_COMPAT: "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/6.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; EIE10;ENUSMSN)" +IE10_X64_WINX64: "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Win64; x64; Trident/6.0)" +IE11: "Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko" +IE11_COMPAT: "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.3; WOW64; Trident/7.0; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729)" +IE11_TOUCH_SCREEN: "Mozilla/5.0 (Windows NT 6.3; Win64; x64; Trident/7.0; Touch; rv:11.0) like Gecko" +IE6: "Mozilla/5.0 (Windows; U; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)" +IE7: "Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 6.0; en-US)" +IE8: "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.2; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)" +IE8_COMPAT: "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Trident/4.0; SLCC1; Media Center PC 5.0; .NET CLR 3.5.21022)" +IE9: "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)" +IE9_CHROME_FRAME: "Mozilla/5.0 (Windows NT 6.1; WOW64; chromeframe/26.0.1410.43) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.43 Safari/537.31" +IE9_COMPAT: "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Trident/5.0)" IE_WITHOUT_TRIDENT: Mozilla/4.0 (compatible; MSIE8.0; Windows NT 6.0) .NET CLR 2.0.50727) -IOS3: 'Mozilla/5.0 (iPad; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B314 Safari/531.21.10' -IOS4: 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7' -IOS5: 'Mozilla/5.0 (iPhone; CPU iPhone OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3' -IOS6: 'Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25' -IOS7: 'Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53' -IOS8: 'Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12A365 Safari/600.1.4' -IOS9: 'Mozilla/5.0 (iPad; CPU OS 9_0 like Mac OS X) AppleWebKit/601.1.17 (KHTML, like Gecko) Version/8.0 Mobile/13A175 Safari/600.1.4' +INSTAGRAM: "Mozilla/5.0 (iPhone; CPU iPhone OS 11_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E216 Instagram 41.0.0.14.90 (iPhone9,3; iOS 11_3; pl_PL; pl-PL; scale=2.00; gamut=wide; 750x1334)" +INSTAGRAM_OTHER: "Instagram/182257141 CFNetwork/1107.1 Darwin/19.0.0" +IOS12: "Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1" +IOS3: "Mozilla/5.0 (iPad; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B314 Safari/531.21.10" +IOS4: "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7" +IOS5: "Mozilla/5.0 (iPhone; CPU iPhone OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3" +IOS6: "Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25" +IOS7: "Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53" +IOS8: "Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12A365 Safari/600.1.4" +IOS8_1_2: 'Mozilla/5.0 (iPhone; CPU iPhone OS 8_1_2 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12B440 Safari/600.1.4' +IOS8_3: 'Mozilla/5.0 (iPhone; CPU iPhone OS 8_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12F70 Safari/600.1.4' +IOS9: "Mozilla/5.0 (iPad; CPU OS 9_0 like Mac OS X) AppleWebKit/601.1.17 (KHTML, like Gecko) Version/8.0 Mobile/13A175 Safari/600.1.4" IOS_WEBVIEW: Mozilla/5.0 (iPhone; CPU iPhone OS 8_4 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/12H141 -IPAD: 'Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B367 Safari/531.21.10' -IPHONE: 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/1A542a Safari/419.3' -IPOD: 'Mozilla/5.0 (iPod; U; CPU like Mac OS X; en) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/3A100a Safari/419.3' -KINDLE: 'Mozilla/5.0 (Linux; U; en-US) AppleWebKit/528.5+ (KHTML, like Gecko, Safari/528.5+) Version/4.0 Kindle/3.0 (screen 600×800; rotate)' -KINDLE_FIRE: 'Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; Kindle Fire Build/GINGERBREAD) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1' -KINDLE_FIRE_HD: 'Mozilla/5.0 (Linux; U; en-us; KFTT Build/IML74K) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.4 Safari/535.19 Silk-Accelerated=true' -KINDLE_FIRE_HD_MOBILE: 'Mozilla/5.0 (Linux; U; Android 4.0.3; en-us; KFTT Build/IML74K) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.4 Mobile Safari/535.19 Silk-Accelerated=true' -LUMIA800: 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; XBLWP7; ZuneWP7' -MICRO_MESSENGER: 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Mobile/13E238 MicroMessenger/6.3.15 NetType/3G+ Language/zh_CN' +IPAD: "Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B367 Safari/531.21.10" +IPHONE: "Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/1A542a Safari/419.3" +IPOD: "Mozilla/5.0 (iPod; U; CPU like Mac OS X; en) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/3A100a Safari/419.3" +KINDLE: "Mozilla/5.0 (Linux; U; en-US) AppleWebKit/528.5+ (KHTML, like Gecko, Safari/528.5+) Version/4.0 Kindle/3.0 (screen 600×800; rotate)" +KINDLE_FIRE: "Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; Kindle Fire Build/GINGERBREAD) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1" +KINDLE_FIRE_HD: "Mozilla/5.0 (Linux; U; en-us; KFTT Build/IML74K) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.4 Safari/535.19 Silk-Accelerated=true" +KINDLE_FIRE_HD_MOBILE: "Mozilla/5.0 (Linux; U; Android 4.0.3; en-us; KFTT Build/IML74K) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.4 Mobile Safari/535.19 Silk-Accelerated=true" +LUMIA800: "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; XBLWP7; ZuneWP7" +MAC_OS: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.5 Safari/605.1.15" +MAC_OSX: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/601.3.9 (KHTML, like Gecko) Version/9.0.2 Safari/601.3.9" +MICRO_MESSENGER_IOS: "Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/7.0.10(0x17000a21) NetType/4G Language/zh_CN" +MICRO_MESSENGER_ANDROID: "Mozilla/5.0 (Linux; Android 7.1.2; Redmi 4X Build/N2G47H; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 MQQBrowser/6.2 TBS/045131 Mobile Safari/537.36 MMWEBID/9286 MicroMessenger/7.0.13.1640(0x27000D37) Process/tools NetType/WIFI Language/zh_CN ABI/arm64 WeChat/arm64" MIDP: MIDP-2.0 -MOBILE_CHROME: 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_1_1 like Mac OS X; en) AppleWebKit/534.46.0 (KHTML, like Gecko) CriOS/19.0.1084.60 Mobile/9B206 Safari/7534.48.3' -MS_EDGE: 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36 Edge/12.0' -MS_EDGE_COMPAT: 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; WOW64; Trident/8.0; .NET4.0C; .NET4.0E; Tablet PC 2.0; Microsoft Outlook 15.0.4433; ms-office; MSOffice 15)' -MS_EDGE_MOBILE: 'Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; DEVICE INFO) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Mobile Safari/537.36 Edge/12.0' -NEXUS7: 'Mozilla/5.0 (Linux; Android 4.3; Nexus 7 Build/JWR66Y) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.72 Safari/537.36' -NEXUS_TABLET: 'Mozilla/5.0 (Linux; Android 4.1.1; Nexus 7 Build/JRO03D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19' -NINTENDO_WII: 'Opera/9.00 (Nintendo Wii; U; ; 1309-9; en)' -NINTENDO_WIIU: 'Mozilla/5.0 (Nintendo WiiU) AppleWebKit/534.52 (KHTML, like Gecko) NX/2.1.0.8.23 NintendoBrowser/1.1.0.7579.EU' -NOKIA: 'Mozilla/5.0 (Series40; NokiaX3-02/le6.32; Profile/MIDP-2.1 Configuration/CLDC-1.1) Gecko/20100401 S40OviBrowser/2.0.2.62.10' -NOOK: 'Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; NOOK BNTV250A Build/GINGERBREAD 1.4.3) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Safari/533.1' -OPERA: 'Opera/9.80 (Macintosh; Intel Mac OS X 10.7.4; U; en) Presto/2.10.229 Version/11.64' -OPERA_ANDROID: 'Mozill/5.0 (Linux; Android 4.4.2; A1-810 Build/KOT49H) Apple/WebKit/537.36 (KHTML, like Gecko) Chrome/48.0.25 64.99 Safari/537.36 OPR/35.0.2070.100283' -OPERA_MINI: 'Opera/9.80 (Android; Opera Mini/7.029952/28.2359;u; fr) Presto/2.8.119 Version/11.10' -OPERA_MOBI: 'Opera/9.8 (Android 2.3.5; Linux; Opera Mobi/ADR-1205181138; U; en) Presto/2.10.254 Version/12.00' -OPERA_NEXT: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.37 Safari/537.36 OPR/15.0.1147.44 (Edition Next)' +MOBILE_CHROME: "Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_1_1 like Mac OS X; en) AppleWebKit/534.46.0 (KHTML, like Gecko) CriOS/19.0.1084.60 Mobile/9B206 Safari/7534.48.3" +MS_EDGE: "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36 Edge/12.0" +MS_EDGE_CHROME: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.29 Safari/537.36 Edg/79.0.309.18" +MS_EDGE_COMPAT: "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.2; WOW64; Trident/8.0; .NET4.0C; .NET4.0E; Tablet PC 2.0; Microsoft Outlook 15.0.4433; ms-office; MSOffice 15)" +MS_EDGE_MOBILE: "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; DEVICE INFO) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Mobile Safari/537.36 Edge/12.0" +MS_EDGE_IOS: "Mozilla/5.0 (iPhone; CPU iPhone OS 12_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.1.1 EdgiOS/44.5.0.10 Mobile/15E148 Safari/604.1" +MS_EDGE_ANDROID: "Mozilla/5.0 (Linux; Android 7.1.2; Redmi 4X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.0 Mobile Safari/537.36 EdgA/44.11.2.4122" +NEXUS7: "Mozilla/5.0 (Linux; Android 4.3; Nexus 7 Build/JWR66Y) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.72 Safari/537.36" +NEXUS_TABLET: "Mozilla/5.0 (Linux; Android 4.1.1; Nexus 7 Build/JRO03D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19" +NINTENDO_SWITCH: "Mozilla/5.0 (Nintendo Switch; WifiWebAuthApplet) AppleWebKit/601.6 (KHTML, like Gecko) NF/4.0.0.7.9 NintendoBrowser/5.1.0.15785" +NINTENDO_WII: "Opera/9.00 (Nintendo Wii; U; ; 1309-9; en)" +NINTENDO_WIIU: "Mozilla/5.0 (Nintendo WiiU) AppleWebKit/534.52 (KHTML, like Gecko) NX/2.1.0.8.23 NintendoBrowser/1.1.0.7579.EU" +NOKIA: "Mozilla/5.0 (Series40; NokiaX3-02/le6.32; Profile/MIDP-2.1 Configuration/CLDC-1.1) Gecko/20100401 S40OviBrowser/2.0.2.62.10" +NOOK: "Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; NOOK BNTV250A Build/GINGERBREAD 1.4.3) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Safari/533.1" +OPERA: "Opera/9.80 (Macintosh; Intel Mac OS X 10.7.4; U; en) Presto/2.10.229 Version/11.64" +OPERA_ANDROID: "Mozill/5.0 (Linux; Android 4.4.2; A1-810 Build/KOT49H) Apple/WebKit/537.36 (KHTML, like Gecko) Chrome/48.0.25 64.99 Safari/537.36 OPR/35.0.2070.100283" +OPERA_MINI: "Opera/9.80 (Android; Opera Mini/7.029952/28.2359;u; fr) Presto/2.8.119 Version/11.10" +OPERA_MOBI: "Opera/9.8 (Android 2.3.5; Linux; Opera Mobi/ADR-1205181138; U; en) Presto/2.10.254 Version/12.00" +OPERA_NEXT: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.37 Safari/537.36 OPR/15.0.1147.44 (Edition Next)" OTTER: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/602.1 (KHTML, like Gecko) Otter/0.9.91 -PHANTOM_JS: 'Mozilla/5.0 (Macintosh; Intel Mac OS X) AppleWebKit/534.34 (KHTML, like Gecko) PhantomJS/1.9.0 Safari/534.34' -PLAYBOOK: 'Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML, like Gecko) Version/7.2.1.0 Safari/536.2+' -PLAYSTATION3: 'Mozilla/5.0 (PLAYSTATION 3; 3.55)' -PLAYSTATION4: 'Mozilla/5.0 (PlayStation 4 1.020) AppleWebKit/536.26 (KHTML, like Gecko)' -PSP: 'Mozilla/4.0 (PSP (PlayStation Portable); 2.00)' -PSP_VITA: 'Mozilla/5.0 (Playstation Vita 1.61) AppleWebKit/531.22.8 (KHTML, like Gecko) Silk/3.2' -QQ_BROWSER_ANDROID: 'Mozilla/5.0 (Linux; Android 5.1.1; SM-N9108V Build/LMY47X) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/37.0.0.0 Mobile MQQBrowser/6.2 TBS/036222 Safari/537.36 V1_AND_SQ_6.2.0_320_YYB_D QQ/6.2.0.2655 NetType/WIFI WebP/0.3.0 Pixel/1440' -QQ_BROWSER_IOS: 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Mobile/13E238 QQ/6.3.3.432 V1_IPH_SQ_6.3.3_1_APP_A Pixel/640 Core/UIWebView NetType/WIFI Mem/47' -QQ_BROWSER_MAC: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.98 Safari/537.36 QQBrowser/4.2.4753.400' -QQ_BROWSER_MAC_LITE: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/602.2.14 (KHTML, like Gecko) Version/10.0.1 Safari/602.2.14 QQBrowserLite/1.0.4' -QUICKTIME: 'QuickTime/7.6.8 (qtver=7.6.8;os=Windows NT 5.1Service Pack 3)' -SAFARI3: 'Mozilla/5.0 (Windows; U; Windows NT 6.0; en) AppleWebKit/522.15.5 (KHTML, like Gecko) Version/3.0.3 Safari/522.15.5' -SAFARI4: 'Mozilla/5.0 (Windows; U; Windows NT 6.0; fr-ch) AppleWebKit/531.9 (KHTML, like Gecko) Version/4.0.3 Safari/531.9' -SAFARI5: 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; fr-ch) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4' -SAFARI6: 'Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.25' -SAFARI7: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9) AppleWebKit/537.71 (KHTML, like Gecko) Version/7.0 Safari/537.71' -SAFARI8: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_90) AppleWebKit/600.1.25 (KHTML, like Gecko) Version/8.0 Safari/600.1.25' -SAFARI9: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/601.3.9 (KHTML, like Gecko) Version/9.0.2 Safari/601.3.9' -SAFARI: 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-us) AppleWebKit/533.17.8 (KHTML, like Gecko) Version/5.0.1 Safari/533.17.8' -SAFARI_IPAD_WEBAPP_MODE: 'Mozilla/5.0 (iPad; U; CPU OS 3_2_1 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Mobile/7B405' -SAFARI_IPHONE_WEBAPP_MODE: 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.20 (KHTML, like Gecko) Mobile/7B298g' -SAMSUNG: 'Mozilla/5.0 (Linux; U; Android 4.0.4; en-us; SAMSUNG-SGH-I497 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30' -SAMSUNG_CHROME: 'Mozilla/5.0 (Linux; Android 4.4.2; en-gb; SAMSUNG GT-I9195/I9195XXUCNEA Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/1.5 Chrome/28.0.1500.94 Mobile Safari/537.36' -SMART_TV: 'Mozilla/5.0 (SmartHub; SMART-TV; U; Linux/SmartTV) AppleWebKit/531.2+ (KHTML, like Gecko) WebBrowser/1.0 SmartTV Safari/531.2+' -SURFACE: 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; ARM; Trident/6.0; Touch)' -SYMBIAN: 'Nokia5250/10.0.011 (SymbianOS/9.4; U; Series60/5.0 Mozilla/5.0; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/525 (KHTML, like Gecko) Safari/525 3gpp-gba' -TABLOID: 'Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13' -UC_BROWSER: 'Mozilla/5.0 (Linux; U; Android 4.4.2; en-US; GT-I9500 Build/KOT49H) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 UCBrowser/9.9.4.484 U3/0.8.0 Mobile Safari/533.1' -WEIBO_ANDROID: 'Mozilla/5.0 (Linux; Android 5.0.2; vivo X5M Build/LRX22G) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/37.0.0.0 Mobile Safari/537.36 Weibo (vivo-vivo X5M__weibo__5.7.1__android__android5.0.2)' -WEIBO_IOS: 'Mozilla/5.0 (iPhone; CPU iPhone OS 8_4 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/12H143 Weibo (iPhone7,2__weibo__5.7.1__iphone__os8.4)' -WINDOWS10: 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 10.0; Trident/6.0)' -WINDOWS7: 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0) chromeframe/10.0.648.205' -WINDOWS81: 'Mozilla/5.0 (IE 11.0; Windows NT 6.3; Trident/7.0; .NET4.0E; .NET4.0C; rv:11.0) like Gecko' -WINDOWS8: 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)' -WINDOWS_2000: 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 5.0; Trident/6.0)' -WINDOWS_2000_SP1: 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 5.01; Trident/6.0)' -WINDOWS_MOBILE: 'Mozilla/4.0 (compatible; MSIE 6.0; Windows CE; IEMobile 6.12)' -WINDOWS_PHONE8: 'Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 920)' -WINDOWS_PHONE: 'Mozilla/4.0 (compatible; MSIE 7.0; Windows Phone OS 7.0; Trident/3.1; IEMobile/7.0; DELL; Venue Pro)' -WINDOWS_PHONE_81: 'Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 929) like iPhone OS 7_0_3 Mac OS X AppleWebKit/537 (KHTML, like Gecko) Mobile Safari/537' -WINDOWS_VISTA: 'Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)' +PHANTOM_JS: "Mozilla/5.0 (Macintosh; Intel Mac OS X) AppleWebKit/534.34 (KHTML, like Gecko) PhantomJS/1.9.0 Safari/534.34" +PLAYBOOK: "Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML, like Gecko) Version/7.2.1.0 Safari/536.2+" +PLAYSTATION3: "Mozilla/5.0 (PLAYSTATION 3; 3.55)" +PLAYSTATION4: "Mozilla/5.0 (PlayStation 4 1.020) AppleWebKit/536.26 (KHTML, like Gecko)" +PSP: "Mozilla/4.0 (PSP (PlayStation Portable); 2.00)" +PSP_VITA: "Mozilla/5.0 (Playstation Vita 1.61) AppleWebKit/531.22.8 (KHTML, like Gecko) Silk/3.2" +QQ_BROWSER_ANDROID: "Mozilla/5.0 (Linux; Android 5.1.1; SM-N9108V Build/LMY47X) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/37.0.0.0 Mobile MQQBrowser/6.2 TBS/036222 Safari/537.36 V1_AND_SQ_6.2.0_320_YYB_D QQ/6.2.0.2655 NetType/WIFI WebP/0.3.0 Pixel/1440" +QQ_BROWSER_IOS: "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Mobile/13E238 QQ/6.3.3.432 V1_IPH_SQ_6.3.3_1_APP_A Pixel/640 Core/UIWebView NetType/WIFI Mem/47" +QQ_BROWSER_MAC: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.98 Safari/537.36 QQBrowser/4.2.4753.400" +QQ_BROWSER_MAC_LITE: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/602.2.14 (KHTML, like Gecko) Version/10.0.1 Safari/602.2.14 QQBrowserLite/1.0.4" +QUICKTIME: "QuickTime/7.6.8 (qtver=7.6.8;os=Windows NT 5.1Service Pack 3)" +SAFARI3: "Mozilla/5.0 (Windows; U; Windows NT 6.0; en) AppleWebKit/522.15.5 (KHTML, like Gecko) Version/3.0.3 Safari/522.15.5" +SAFARI4: "Mozilla/5.0 (Windows; U; Windows NT 6.0; fr-ch) AppleWebKit/531.9 (KHTML, like Gecko) Version/4.0.3 Safari/531.9" +SAFARI5: "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; fr-ch) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4" +SAFARI6: "Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.25" +SAFARI7: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9) AppleWebKit/537.71 (KHTML, like Gecko) Version/7.0 Safari/537.71" +SAFARI8: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_90) AppleWebKit/600.1.25 (KHTML, like Gecko) Version/8.0 Safari/600.1.25" +SAFARI9: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/601.3.9 (KHTML, like Gecko) Version/9.0.2 Safari/601.3.9" +SAFARI: "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-us) AppleWebKit/533.17.8 (KHTML, like Gecko) Version/5.0.1 Safari/533.17.8" +SAFARI_IPAD_WEBAPP_MODE: "Mozilla/5.0 (iPad; U; CPU OS 3_2_1 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Mobile/7B405" +SAFARI_IPHONE_WEBAPP_MODE: "Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.20 (KHTML, like Gecko) Mobile/7B298g" +SAMSUNG: "Mozilla/5.0 (Linux; U; Android 4.0.4; en-us; SAMSUNG-SGH-I497 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30" +SAMSUNG_BROWSER: "Mozilla/5.0 (Linux; Android 10; SAMSUNG SM-N960U) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/11.1 Chrome/75.0.3770.143 Mobile Safari/537.36" +SAMSUNG_CHROME: "Mozilla/5.0 (Linux; Android 4.4.2; en-gb; SAMSUNG GT-I9195/I9195XXUCNEA Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/1.5 Chrome/28.0.1500.94 Mobile Safari/537.36" +SMART_TV: "Mozilla/5.0 (SmartHub; SMART-TV; U; Linux/SmartTV) AppleWebKit/531.2+ (KHTML, like Gecko) WebBrowser/1.0 SmartTV Safari/531.2+" +SNAPCHAT: Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Snapchat/10.69.5.72 (iPhone10,3; iOS 13.2.2; gzip) +SNAPCHAT_EMPTY_STRING_VERSION: "Mozilla/5.0 (Linux; Android 9; SM-N960U Build/PPR1.180610.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.96 Mobile Safari/537.36Snapchat10.70.0.0 (SM-N960U; Android 9#N960USQS3CSJ2#28; gzip)" +SNAPCHAT_SPACE_VERSION: "Mozilla/5.0 (Linux; Android 9; SM-N960U Build/PPR1.180610.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.96 Mobile Safari/537.36Snapchat 10.70.0.0 (SM-N960U; Android 9#N960USQS3CSJ2#28; gzip)" +SPUTNIK: "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 SputnikBrowser/4.1.2801.0 Safari/537.36" +SURFACE: "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; ARM; Trident/6.0; Touch)" +SYMBIAN: "Nokia5250/10.0.011 (SymbianOS/9.4; U; Series60/5.0 Mozilla/5.0; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/525 (KHTML, like Gecko) Safari/525 3gpp-gba" +TABLOID: "Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13" +UC_BROWSER: "Mozilla/5.0 (Linux; U; Android 4.4.2; en-US; GT-I9500 Build/KOT49H) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 UCBrowser/9.9.4.484 U3/0.8.0 Mobile Safari/533.1" +WEIBO_ANDROID: "Mozilla/5.0 (Linux; Android 5.0.2; vivo X5M Build/LRX22G) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/37.0.0.0 Mobile Safari/537.36 Weibo (vivo-vivo X5M__weibo__5.7.1__android__android5.0.2)" +WEIBO_IOS: "Mozilla/5.0 (iPhone; CPU iPhone OS 8_4 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/12H143 Weibo (iPhone7,2__weibo__5.7.1__iphone__os8.4)" +WINDOWS10: "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 10.0; Trident/6.0)" +WINDOWS7: "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0) chromeframe/10.0.648.205" +WINDOWS81: "Mozilla/5.0 (IE 11.0; Windows NT 6.3; Trident/7.0; .NET4.0E; .NET4.0C; rv:11.0) like Gecko" +WINDOWS8: "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)" +WINDOWS_2000: "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 5.0; Trident/6.0)" +WINDOWS_2000_SP1: "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 5.01; Trident/6.0)" +WINDOWS_MOBILE: "Mozilla/4.0 (compatible; MSIE 6.0; Windows CE; IEMobile 6.12)" +WINDOWS_PHONE8: "Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 920)" +WINDOWS_PHONE: "Mozilla/4.0 (compatible; MSIE 7.0; Windows Phone OS 7.0; Trident/3.1; IEMobile/7.0; DELL; Venue Pro)" +WINDOWS_PHONE_81: "Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 929) like iPhone OS 7_0_3 Mac OS X AppleWebKit/537 (KHTML, like Gecko) Mobile Safari/537" +WINDOWS_VISTA: "Mozilla/5.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET CLR 1.0.3705; .NET CLR 1.1.4322)" WINDOWS_WOW64: "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; Touch; rv:11.0) like Gecko" -WINDOWS_XP: 'Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.1; FDM; .NET CLR 1.1.4322)' -WINDOWS_XP_64: 'Mozilla/4.0 (Compatible; MSIE 8.0; Windows NT 5.2; Trident/6.0)' -XBOX360: 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; Xbox), or Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0; Xbox)' -XBOXONE: 'Mozilla/5.0 (Compatible; MSIE 10.0; Windows NT 6.2; Trident /6.0; Xbox; Xbox One)' -XOOM: 'Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13' -YANDEX_BROWSER: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 YaBrowser/15.4.2272.3909 (beta) Yowser/2.0 Safari/537.36' +WINDOWS_XP: "Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 5.1; FDM; .NET CLR 1.1.4322)" +WINDOWS_XP_64: "Mozilla/4.0 (Compatible; MSIE 8.0; Windows NT 5.2; Trident/6.0)" +XBOX360: "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; Xbox), or Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0; Xbox)" +XBOXONE: "Mozilla/5.0 (Compatible; MSIE 10.0; Windows NT 6.2; Trident /6.0; Xbox; Xbox One)" +XOOM: "Mozilla/5.0 (Linux; U; Android 3.0; en-us; Xoom Build/HRI39) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13" +YANDEX_BROWSER_DESKTOP: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 YaBrowser/19.6.0.1583 Yowser/2.5 Safari/537.36" +YANDEX_BROWSER_IOS: "Mozilla/5.0 (iPhone; CPU iPhone OS 12_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 YaBrowser/19.6.1.157.10 Mobile/15E148 Safari/605.1" diff -Nru ruby-browser-2.5.3/test/unit/accept_language_test.rb ruby-browser-4.2.0/test/unit/accept_language_test.rb --- ruby-browser-2.5.3/test/unit/accept_language_test.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/test/unit/accept_language_test.rb 2020-06-19 05:24:10.000000000 +0000 @@ -131,6 +131,16 @@ assert_language result[4], code: "fr", region: nil, quality: 0.2 end + test "sorts the same quality in a descending priority" do + accept_language = "fr-CA,fr;q=0.2,en-US;q=0.2,en" + result = Browser::AcceptLanguage.parse(accept_language) + + assert_language result[0], code: "fr", region: "CA", quality: 1.0 + assert_language result[1], code: "en", region: nil, quality: 1.0 + assert_language result[2], code: "fr", region: nil, quality: 0.2 + assert_language result[3], code: "en", region: "US", quality: 0.2 + end + test "rejects quality values equals to zero (#241)" do result = Browser::AcceptLanguage.parse("de-DE,ru;q=0.9,de;q=0.8,en;q=0.") @@ -147,4 +157,10 @@ assert_equal 5, result.size assert_language result[3], code: "de", region: nil, quality: 0.7 end + + test "sets default quality value for invalid strings" do + result = Browser::AcceptLanguage.parse(";q=0.0.0.0") + + assert_equal 0.1, result[0].quality + end end diff -Nru ruby-browser-2.5.3/test/unit/blackberry_test.rb ruby-browser-4.2.0/test/unit/blackberry_test.rb --- ruby-browser-2.5.3/test/unit/blackberry_test.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/test/unit/blackberry_test.rb 2020-06-19 05:24:10.000000000 +0000 @@ -9,7 +9,6 @@ assert_equal "BlackBerry", browser.name refute browser.device.tablet? assert browser.device.mobile? - refute browser.modern? assert_equal "4.1.0", browser.full_version assert_equal "4", browser.version end @@ -18,7 +17,6 @@ browser = Browser.new(Browser["BLACKBERRY4"]) assert_equal "BlackBerry", browser.name - refute browser.modern? assert_equal "4.2.1", browser.full_version assert_equal "4", browser.version end @@ -29,7 +27,6 @@ assert_equal "BlackBerry", browser.name refute browser.device.tablet? assert browser.device.mobile? - refute browser.modern? assert_equal "5.0.0.93", browser.full_version assert_equal "5", browser.version end @@ -40,7 +37,6 @@ assert_equal "BlackBerry", browser.name refute browser.device.tablet? assert browser.device.mobile? - assert browser.modern? assert_equal "6.0.0.141", browser.full_version assert_equal "6", browser.version end @@ -51,7 +47,6 @@ assert_equal "BlackBerry", browser.name refute browser.device.tablet? assert browser.device.mobile? - assert browser.modern? assert_equal "7.0.0.1", browser.full_version assert_equal "7", browser.version end @@ -62,7 +57,6 @@ assert_equal "BlackBerry", browser.name refute browser.device.tablet? assert browser.device.mobile? - assert browser.modern? assert_equal "10.0.9.1675", browser.full_version assert_equal "10", browser.version end diff -Nru ruby-browser-2.5.3/test/unit/bots_test.rb ruby-browser-4.2.0/test/unit/bots_test.rb --- ruby-browser-2.5.3/test/unit/bots_test.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/test/unit/bots_test.rb 2020-06-19 05:24:10.000000000 +0000 @@ -15,34 +15,6 @@ refute browser.bot? end - test "doesn't consider empty UA as bot" do - browser = Browser.new("") - refute browser.bot? - end - - test "allows setting empty string as bots" do - Browser::Bot.detect_empty_ua! - browser = Browser.new("") - - assert browser.bot? - end - - test "allows setting nil as user agent for bots" do - browser = Browser.new(nil) - refute browser.bot? - - Browser::Bot.detect_empty_ua! - browser = Browser.new(nil) - assert browser.bot? - end - - test "doesn't detect mozilla as a bot when considering empty UA" do - Browser::Bot.detect_empty_ua! - browser = Browser.new("Mozilla") - - refute browser.bot? - end - test "returns bot name" do browser = Browser.new(Browser["GOOGLE_BOT"]) assert_equal "Google Bot", browser.bot.name @@ -51,13 +23,6 @@ assert_equal "Facebook Bot", browser.bot.name end - test "returns bot name (empty string ua detection enabled)" do - Browser::Bot.detect_empty_ua! - browser = Browser.new("") - - assert_equal browser.bot.name, "Generic Bot" - end - test "returns nil for non-bots" do browser = Browser.new(Browser["CHROME"]) assert_nil browser.bot.name @@ -84,7 +49,6 @@ refute browser.platform.windows10? refute browser.platform.windows_phone? refute browser.edge? - refute browser.modern? refute browser.device.mobile? refute browser.webkit? refute browser.chrome? @@ -107,4 +71,41 @@ Browser::Bot.bots.delete("faraday") end + + test "detects recognized bots using common libs" do + browser = Browser.new(Browser.bot_user_agents["LINKEDIN"]) + + assert browser.bot? + assert_equal "LinkedIn", browser.bot.name + end + + test "tells why user agent is considered a bot" do + matcher = Browser::Bot.why?(Browser.bot_user_agents["LINKEDIN"]) + + assert_equal Browser::Bot::KnownBotsMatcher, matcher + end + + test "adds custom bot matcher" do + Browser::Bot.matchers << ->(ua, _) { ua =~ /some-script/ } + browser = Browser.new("some-script") + + assert browser.bot? + assert_equal "Generic Bot", browser.bot.name + end + + %w[ + content-fetcher + content-crawler + some-search-engine + monitoring-service + content-spider + some-bot + ].each do |ua| + test "detects user agents based on keywords (#{ua})" do + browser = Browser.new(ua) + + assert browser.bot? + assert_equal Browser::Bot::KeywordMatcher, browser.bot.why? + end + end end diff -Nru ruby-browser-2.5.3/test/unit/chrome_test.rb ruby-browser-4.2.0/test/unit/chrome_test.rb --- ruby-browser-2.5.3/test/unit/chrome_test.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/test/unit/chrome_test.rb 2020-06-19 05:24:10.000000000 +0000 @@ -10,7 +10,6 @@ assert browser.chrome? refute browser.safari? assert browser.webkit? - assert browser.modern? assert_equal "5.0.375.99", browser.full_version assert_equal "5", browser.version end @@ -22,7 +21,6 @@ assert browser.chrome? refute browser.safari? assert browser.webkit? - assert browser.modern? assert_equal "19.0.1084.60", browser.full_version assert_equal "19", browser.version end @@ -35,7 +33,6 @@ assert browser.platform.android? refute browser.safari? assert browser.webkit? - assert browser.modern? assert_equal "28.0.1500.94", browser.full_version assert_equal "28", browser.version end @@ -45,22 +42,6 @@ assert browser.platform.chrome_os? end - test "detects yandex browser" do - browser = Browser.new(Browser["YANDEX_BROWSER"]) - - assert browser.yandex? - assert browser.chrome? - refute browser.safari? - assert browser.webkit? - assert_equal "41.0.2272.118", browser.full_version - assert_equal "41", browser.version - end - - test "detects yandex version by range" do - browser = Browser.new(Browser["YANDEX_BROWSER"]) - assert browser.yandex?(%w[>=41 <42]) - end - test "detects chrome frame" do browser = Browser.new(Browser["IE9_CHROME_FRAME"]) @@ -77,6 +58,14 @@ assert browser.chrome? end + test "detects chrome on android 10" do + browser = Browser.new(Browser["ANDROID_Q"]) + + assert browser.chrome? + assert_equal "Chrome", browser.name + assert_equal "78", browser.version + end + test "detects version by range" do browser = Browser.new(Browser["CHROME"]) assert browser.chrome?(%w[>=5 <6]) diff -Nru ruby-browser-2.5.3/test/unit/device_test.rb ruby-browser-4.2.0/test/unit/device_test.rb --- ruby-browser-2.5.3/test/unit/device_test.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/test/unit/device_test.rb 2020-06-19 05:24:10.000000000 +0000 @@ -157,6 +157,16 @@ assert_equal "Nintendo WiiU", device.name end + test "detect switch" do + device = Browser::Device.new(Browser["NINTENDO_SWITCH"]) + assert device.nintendo_switch? + assert device.switch? + assert device.console? + assert device.nintendo? + assert_equal :switch, device.id + assert_equal "Nintendo Switch", device.name + end + test "detect blackberry playbook" do device = Browser::Device.new(Browser["PLAYBOOK"]) assert device.playbook? @@ -228,4 +238,24 @@ refute device.mobile? end end + + { + "ANDROID_CUPCAKE" => "T-Mobile G1", + "ANDROID_DONUT" => "SonyEricssonX10i", + "ANDROID_ECLAIR_21" => "Nexus One", + "ANDROID_FROYO" => "HTC_DesireHD_A9191", + "ANDROID_GINGERBREAD" => "Sensation_4G", + "ANDROID_HONEYCOMB_30" => "Xoom", + "ANDROID_ICECREAM" => "sdk", + "ANDROID_JELLYBEAN_41" => "Nexus S", + "ANDROID_JELLYBEAN_42" => "Nexus 10", + "ANDROID_JELLYBEAN_43" => "Nexus 7", + "CUSTOM_APP" => "HTC Ruby", + "NOOK" => "NOOK BNTV250A" + }.each do |key, name| + test "detect device name of #{key} as #{name}" do + device = Browser::Device.new(Browser[key]) + assert_equal name, device.name + end + end end diff -Nru ruby-browser-2.5.3/test/unit/duck_duck_go_test.rb ruby-browser-4.2.0/test/unit/duck_duck_go_test.rb --- ruby-browser-2.5.3/test/unit/duck_duck_go_test.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-browser-4.2.0/test/unit/duck_duck_go_test.rb 2020-06-19 05:24:10.000000000 +0000 @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require "test_helper" + +class DuckDuckGoTest < Minitest::Test + test "detects DuckDuckGo on iOS device" do + browser = Browser.new(Browser["DUCKDUCKGO_BROWSER_IOS"]) + assert browser.duck_duck_go? + refute browser.safari? + refute browser.chrome? + assert browser.webkit? + assert_equal "DuckDuckGo", browser.name + assert_equal :duckduckgo, browser.id + end + + test "detects DuckDuckGo on Android device" do + browser = Browser.new(Browser["DUCKDUCKGO_BROWSER_ANDROID"]) + assert browser.duck_duck_go? + refute browser.safari? + refute browser.chrome? + assert_equal "DuckDuckGo", browser.name + assert_equal :duckduckgo, browser.id + end + + test "detects correct version" do + browser = Browser.new(Browser["DUCKDUCKGO_BROWSER_IOS"]) + assert_equal "7", browser.full_version + assert_equal "7", browser.version + end + + test "detects version by range" do + browser = Browser.new(Browser["DUCKDUCKGO_BROWSER_IOS"]) + assert browser.duck_duck_go?(%w[>=7 <8]) + end +end diff -Nru ruby-browser-2.5.3/test/unit/edge_test.rb ruby-browser-4.2.0/test/unit/edge_test.rb --- ruby-browser-2.5.3/test/unit/edge_test.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/test/unit/edge_test.rb 2020-06-19 05:24:10.000000000 +0000 @@ -12,7 +12,6 @@ assert_equal "12", browser.version assert browser.platform.windows10? assert browser.edge? - assert browser.modern? refute browser.webkit? refute browser.chrome? refute browser.safari? @@ -30,7 +29,6 @@ assert_equal "7", browser.msie_version assert browser.edge? assert browser.compatibility_view? - refute browser.modern? refute browser.webkit? refute browser.chrome? refute browser.safari? @@ -47,14 +45,60 @@ refute browser.platform.windows10? assert browser.platform.windows_phone? assert browser.edge? - assert browser.modern? + refute browser.webkit? + refute browser.chrome? + refute browser.safari? + end + + test "detects Microsoft Edge based on Chrome" do + browser = Browser.new(Browser["MS_EDGE_CHROME"]) + + assert_equal :edge, browser.id + assert_equal "Microsoft Edge", browser.name + assert_equal "79.0.309.18", browser.full_version + assert_equal "79", browser.version + assert browser.platform.mac? + refute browser.platform.windows? + assert browser.edge? + assert browser.webkit? + refute browser.chrome? + refute browser.safari? + end + + test "detects Microsoft Edge Mobile on iOS" do + browser = Browser.new(Browser["MS_EDGE_IOS"]) + + assert_equal :edge, browser.id + assert_equal "Microsoft Edge", browser.name + assert_equal "44.5.0.10", browser.full_version + assert_equal "44", browser.version + refute browser.platform.windows10? + refute browser.platform.windows_phone? + assert browser.platform.ios? + assert browser.edge? + refute browser.webkit? + refute browser.chrome? + refute browser.safari? + end + + test "detects Microsoft Edge Mobile on Android" do + browser = Browser.new(Browser["MS_EDGE_ANDROID"]) + + assert_equal :edge, browser.id + assert_equal "Microsoft Edge", browser.name + assert_equal "44.11.2.4122", browser.full_version + assert_equal "44", browser.version + refute browser.platform.windows10? + refute browser.platform.windows_phone? + assert browser.platform.android? + assert browser.edge? refute browser.webkit? refute browser.chrome? refute browser.safari? end test "detects version by range" do - browser = Browser.new(Browser["MS_EDGE"]) - assert browser.edge?(%w[>=12 <13]) + browser = Browser.new(Browser["MS_EDGE_IOS"]) + assert browser.edge?(%w[>=43 <45]) end end diff -Nru ruby-browser-2.5.3/test/unit/facebook_test.rb ruby-browser-4.2.0/test/unit/facebook_test.rb --- ruby-browser-2.5.3/test/unit/facebook_test.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/test/unit/facebook_test.rb 2020-06-19 05:24:10.000000000 +0000 @@ -13,6 +13,26 @@ assert_equal "135", browser.version end + test "detects new facebook on iOS" do + browser = Browser.new(Browser["FACEBOOK_IOS"]) + + assert_equal "Facebook", browser.name + assert browser.facebook? + assert :facebook, browser.id + assert_equal "AppleWebKit/605.1.15", browser.full_version + assert_equal "AppleWebKit/605", browser.version + end + + test "detects new facebook on Android" do + browser = Browser.new(Browser["FACEBOOK_ANDROID"]) + + assert_equal "Facebook", browser.name + assert browser.facebook? + assert :facebook, browser.id + assert_equal "214.0.0.43.83", browser.full_version + assert_equal "214", browser.version + end + test "detects version by range" do browser = Browser.new(Browser["FACEBOOK"]) assert browser.facebook?(%w[>=135]) diff -Nru ruby-browser-2.5.3/test/unit/firefox_test.rb ruby-browser-4.2.0/test/unit/firefox_test.rb --- ruby-browser-2.5.3/test/unit/firefox_test.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/test/unit/firefox_test.rb 2020-06-19 05:24:10.000000000 +0000 @@ -8,7 +8,6 @@ assert_equal "Firefox", browser.name assert browser.firefox? - refute browser.modern? assert_equal "3.8", browser.full_version assert_equal "3", browser.version end @@ -29,7 +28,6 @@ assert_equal :firefox, browser.id assert_equal "Firefox", browser.name assert browser.firefox? - assert browser.modern? assert_equal "17.0", browser.full_version assert_equal "17", browser.version end @@ -40,7 +38,6 @@ assert_equal :firefox, browser.id assert_equal "Firefox", browser.name assert browser.firefox? - assert browser.modern? assert browser.platform.android? assert_equal "14.0", browser.full_version assert_equal "14", browser.version diff -Nru ruby-browser-2.5.3/test/unit/instagram_test.rb ruby-browser-4.2.0/test/unit/instagram_test.rb --- ruby-browser-2.5.3/test/unit/instagram_test.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-browser-4.2.0/test/unit/instagram_test.rb 2020-06-19 05:24:10.000000000 +0000 @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +require "test_helper" + +class InstagramTest < Minitest::Test + test "detects instagram" do + browser = Browser.new(Browser["INSTAGRAM"]) + + assert_equal "Instagram", browser.name + assert browser.instagram? + assert :instagram, browser.id + assert_equal "41.0.0.14.90", browser.full_version + assert_equal "41", browser.version + end + + test "detects alternate instagram user agent" do + browser = Browser.new(Browser["INSTAGRAM_OTHER"]) + + assert_equal "Instagram", browser.name + assert browser.instagram? + assert :instagram, browser.id + assert_equal "182257141", browser.full_version + assert_equal "182257141", browser.version + end + + test "detects version by range" do + browser = Browser.new(Browser["INSTAGRAM"]) + assert browser.instagram?(%w[>=41]) + end +end diff -Nru ruby-browser-2.5.3/test/unit/internet_explorer_test.rb ruby-browser-4.2.0/test/unit/internet_explorer_test.rb --- ruby-browser-2.5.3/test/unit/internet_explorer_test.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/test/unit/internet_explorer_test.rb 2020-06-19 05:24:10.000000000 +0000 @@ -9,7 +9,6 @@ assert_equal "Internet Explorer", browser.name assert browser.ie? assert browser.ie?(6) - refute browser.modern? assert_equal "6.0", browser.full_version assert_equal "6", browser.version end @@ -20,7 +19,6 @@ assert_equal "Internet Explorer", browser.name assert browser.ie? assert browser.ie?(7) - refute browser.modern? assert_equal "7.0", browser.full_version assert_equal "7", browser.version end @@ -31,7 +29,6 @@ assert_equal "Internet Explorer", browser.name assert browser.ie? assert browser.ie?(8) - refute browser.modern? refute browser.compatibility_view? assert_equal "8.0", browser.full_version assert_equal "8", browser.version @@ -43,7 +40,6 @@ assert_equal "Internet Explorer", browser.name assert browser.ie? assert browser.ie?(8) - refute browser.modern? assert browser.compatibility_view? assert_equal "8.0", browser.full_version assert_equal "8", browser.version @@ -57,7 +53,6 @@ assert_equal "Internet Explorer", browser.name assert browser.ie? assert browser.ie?(9) - assert browser.modern? refute browser.compatibility_view? assert_equal "9.0", browser.full_version assert_equal "9", browser.version @@ -69,7 +64,6 @@ assert_equal "Internet Explorer", browser.name assert browser.ie? assert browser.ie?(9) - refute browser.modern? assert browser.compatibility_view? assert_equal "9.0", browser.full_version assert_equal "9", browser.version @@ -83,7 +77,6 @@ assert_equal "Internet Explorer", browser.name assert browser.ie? assert browser.ie?(10) - assert browser.modern? refute browser.compatibility_view? assert_equal "10.0", browser.full_version assert_equal "10", browser.version @@ -95,7 +88,6 @@ assert_equal "Internet Explorer", browser.name assert browser.ie? assert browser.ie?(10) - refute browser.modern? assert browser.compatibility_view? assert_equal "10.0", browser.full_version assert_equal "10", browser.version @@ -109,7 +101,6 @@ assert_equal "Internet Explorer", browser.name assert browser.ie? assert browser.ie?(11) - assert browser.modern? refute browser.compatibility_view? assert_equal "11.0", browser.full_version assert_equal "11", browser.version @@ -121,7 +112,6 @@ assert_equal "Internet Explorer", browser.name assert browser.ie? assert browser.ie?(11) - refute browser.modern? assert browser.compatibility_view? assert_equal "11.0", browser.full_version assert_equal "11", browser.version @@ -145,7 +135,6 @@ assert_equal "Internet Explorer", browser.name assert browser.ie? assert browser.ie?(11) - assert browser.modern? refute browser.compatibility_view? refute browser.platform.windows_rt? assert browser.platform.windows_touchscreen_desktop? @@ -166,7 +155,6 @@ refute browser.platform.windows10? refute browser.platform.windows_phone? refute browser.edge? - refute browser.modern? refute browser.device.mobile? refute browser.webkit? refute browser.chrome? diff -Nru ruby-browser-2.5.3/test/unit/ios_test.rb ruby-browser-4.2.0/test/unit/ios_test.rb --- ruby-browser-2.5.3/test/unit/ios_test.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/test/unit/ios_test.rb 2020-06-19 05:24:10.000000000 +0000 @@ -9,7 +9,6 @@ assert_equal "Safari", browser.name assert browser.safari? assert browser.webkit? - assert browser.modern? assert browser.platform.ios? refute browser.platform.mac? assert_equal "3.0", browser.full_version @@ -22,7 +21,6 @@ assert_equal "Safari", browser.name assert browser.safari? assert browser.webkit? - assert browser.modern? assert_equal "5.0.1", browser.full_version assert_equal "5", browser.version end @@ -56,7 +54,6 @@ assert_equal "Safari", browser.name assert browser.safari? assert browser.webkit? - assert browser.modern? assert browser.platform.ios? refute browser.platform.mac? assert_equal "4.0.4", browser.full_version @@ -105,6 +102,13 @@ refute browser.platform.mac? end + test "detects ios12" do + browser = Browser.new(Browser["IOS12"]) + assert browser.platform.ios? + assert browser.platform.ios?(12) + refute browser.platform.mac? + end + test "don't detect as two different versions" do browser = Browser.new(Browser["IOS8"]) assert browser.platform.ios?(8) @@ -119,7 +123,6 @@ assert meta.include?("ios") assert meta.include?("safari") assert meta.include?("safari3") - assert meta.include?("modern") assert meta.include?("mobile") refute meta.include?("tablet") end @@ -131,7 +134,6 @@ assert meta.include?("webkit") assert meta.include?("ios") assert meta.include?("safari") - assert meta.include?("modern") assert meta.include?("tablet") refute meta.include?("mobile") end diff -Nru ruby-browser-2.5.3/test/unit/kindle_test.rb ruby-browser-4.2.0/test/unit/kindle_test.rb --- ruby-browser-2.5.3/test/unit/kindle_test.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/test/unit/kindle_test.rb 2020-06-19 05:24:10.000000000 +0000 @@ -17,13 +17,11 @@ browser = Browser.new(Browser["KINDLE_FIRE_HD"]) assert browser.webkit? - assert browser.modern? end test "detects kindle fire hd mobile" do browser = Browser.new(Browser["KINDLE_FIRE_HD_MOBILE"]) assert browser.webkit? - assert browser.modern? end end diff -Nru ruby-browser-2.5.3/test/unit/meta_test.rb ruby-browser-4.2.0/test/unit/meta_test.rb --- ruby-browser-2.5.3/test/unit/meta_test.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/test/unit/meta_test.rb 2020-06-19 05:24:10.000000000 +0000 @@ -36,7 +36,6 @@ assert meta.include?("chrome") assert meta.include?("webkit") assert meta.include?("mac") - assert meta.include?("modern") end test "returns string representation for mobile" do diff -Nru ruby-browser-2.5.3/test/unit/micro_messenger_test.rb ruby-browser-4.2.0/test/unit/micro_messenger_test.rb --- ruby-browser-2.5.3/test/unit/micro_messenger_test.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/test/unit/micro_messenger_test.rb 2020-06-19 05:24:10.000000000 +0000 @@ -3,18 +3,33 @@ require "test_helper" class MicroMessengerTest < Minitest::Test - test "detects micro messenger 6.3.15" do - browser = Browser.new(Browser["MICRO_MESSENGER"]) + test "detects micro messenger 7.0.10 on iOS" do + browser = Browser.new(Browser["MICRO_MESSENGER_IOS"]) assert browser.micro_messenger? assert browser.wechat? - assert_equal "6.3.15", browser.full_version + assert_equal "7.0.10", browser.full_version assert_equal "MicroMessenger", browser.name assert_equal :micro_messenger, browser.id end - test "detects version by range" do - browser = Browser.new(Browser["MICRO_MESSENGER"]) - assert browser.wechat?(%w[>=6 <7]) + test "detects version by range on iOS" do + browser = Browser.new(Browser["MICRO_MESSENGER_IOS"]) + assert browser.wechat?(%w[>=7 <8]) + end + + test "detects micro messenger 7.0.13.1640 on Android" do + browser = Browser.new(Browser["MICRO_MESSENGER_ANDROID"]) + + assert browser.micro_messenger? + assert browser.wechat? + assert_equal "7.0.13.1640", browser.full_version + assert_equal "MicroMessenger", browser.name + assert_equal :micro_messenger, browser.id + end + + test "detects version by range on Android" do + browser = Browser.new(Browser["MICRO_MESSENGER_ANDROID"]) + assert browser.wechat?(%w[>=7 <8]) end end diff -Nru ruby-browser-2.5.3/test/unit/opera_test.rb ruby-browser-4.2.0/test/unit/opera_test.rb --- ruby-browser-2.5.3/test/unit/opera_test.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/test/unit/opera_test.rb 2020-06-19 05:24:10.000000000 +0000 @@ -8,7 +8,6 @@ assert_equal "Opera", browser.name assert browser.opera? - refute browser.modern? assert_equal "11.64", browser.full_version assert_equal "11", browser.version end @@ -20,7 +19,6 @@ assert_equal :opera, browser.id assert browser.opera? assert browser.webkit? - assert browser.modern? refute browser.chrome? assert_equal "15.0.1147.44", browser.full_version assert_equal "15", browser.version diff -Nru ruby-browser-2.5.3/test/unit/platform_test.rb ruby-browser-4.2.0/test/unit/platform_test.rb --- ruby-browser-2.5.3/test/unit/platform_test.rb 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/test/unit/platform_test.rb 2020-06-19 05:24:10.000000000 +0000 @@ -62,6 +62,27 @@ assert_equal "9", platform.version end + test "detect specific minor iOS (iPhone)" do + platform = Browser::Platform.new(Browser["IOS8_3"]) + + assert_equal "iOS (iPhone)", platform.name + assert_equal :ios, platform.id + assert platform.ios? + assert platform.ios?(8.3) + assert_equal "8.3", platform.version + end + + test "detect specific patch iOS (iPhone)" do + platform = Browser::Platform.new(Browser["IOS8_1_2"]) + + assert_equal "iOS (iPhone)", platform.name + assert_equal :ios, platform.id + assert platform.ios? + assert platform.ios?("8.1.2") + assert platform.ios?("<8.2") + assert_equal "8.1.2", platform.version + end + test "detect ios (iPod Touch)" do platform = Browser::Platform.new(Browser["IPOD"]) @@ -83,7 +104,7 @@ test "detect mac" do platform = Browser::Platform.new(Browser["SAFARI"]) - assert_equal "Macintosh", platform.name + assert_equal "Mac OS X", platform.name assert_equal :mac, platform.id assert platform.mac? assert_equal "10.6.4", platform.version @@ -95,6 +116,11 @@ assert_equal "0", platform.version end + test "detect mac names" do + assert_equal "Mac OS X", Browser::Platform.new(Browser["MAC_OSX"]).name + assert_equal "macOS", Browser::Platform.new(Browser["MAC_OS"]).name + end + test "detect firefox os" do platform = Browser::Platform.new(Browser["FIREFOX_OS"]) diff -Nru ruby-browser-2.5.3/test/unit/samsung_browser_test.rb ruby-browser-4.2.0/test/unit/samsung_browser_test.rb --- ruby-browser-2.5.3/test/unit/samsung_browser_test.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-browser-4.2.0/test/unit/samsung_browser_test.rb 2020-06-19 05:24:10.000000000 +0000 @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require "test_helper" + +class SamsungBrowserTest < Minitest::Test + test "detects samsung browser" do + browser = Browser.new(Browser["SAMSUNG_BROWSER"]) + + assert browser.webkit? + assert browser.samsung_browser? + assert_equal "11", browser.version + assert_equal :samsung_browser, browser.id + assert_equal "11.1", browser.full_version + assert_equal "Samsung Browser", browser.name + refute browser.chrome? + refute browser.safari? + end + + test "detects version by range" do + browser = Browser.new(Browser["SAMSUNG_BROWSER"]) + assert browser.samsung_browser?(%w[>=11 <12]) + end +end diff -Nru ruby-browser-2.5.3/test/unit/snapchat_test.rb ruby-browser-4.2.0/test/unit/snapchat_test.rb --- ruby-browser-2.5.3/test/unit/snapchat_test.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-browser-4.2.0/test/unit/snapchat_test.rb 2020-06-19 05:24:10.000000000 +0000 @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require "test_helper" + +class SnapchatTest < Minitest::Test + test "detects snapchat" do + browser = Browser.new(Browser["SNAPCHAT"]) + + assert_equal "Snapchat", browser.name + assert browser.snapchat? + assert :snapchat, browser.id + assert_equal "10.69.5.72", browser.full_version + assert_equal "10", browser.version + end + + test "detects snapchat for badly formatted user agent" do + browser = Browser.new(Browser["SNAPCHAT_EMPTY_STRING_VERSION"]) + + assert_equal "Snapchat", browser.name + assert browser.snapchat? + assert :snapchat, browser.id + assert_equal "10.70.0.0", browser.full_version + assert_equal "10", browser.version + end + + test "detects alternate snapchat user agent" do + browser = Browser.new(Browser["SNAPCHAT_SPACE_VERSION"]) + + assert_equal "Snapchat", browser.name + assert browser.snapchat? + assert :snapchat, browser.id + assert_equal "10.70.0.0", browser.full_version + assert_equal "10", browser.version + end + + test "detects version by range" do + browser = Browser.new(Browser["SNAPCHAT"]) + assert browser.snapchat?(%w[>=10]) + end +end diff -Nru ruby-browser-2.5.3/test/unit/sputnik_test.rb ruby-browser-4.2.0/test/unit/sputnik_test.rb --- ruby-browser-2.5.3/test/unit/sputnik_test.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-browser-4.2.0/test/unit/sputnik_test.rb 2020-06-19 05:24:10.000000000 +0000 @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +require "test_helper" + +class SputnikTest < Minitest::Test + test "detects sputnik" do + browser = Browser.new(Browser["SPUTNIK"]) + + assert_equal "Sputnik", browser.name + assert_equal :sputnik, browser.id + assert browser.sputnik? + refute browser.chrome? + refute browser.safari? + assert_equal "4.1.2801.0", browser.full_version + assert_equal "4", browser.version + end + + test "detects version by range" do + browser = Browser.new(Browser["SPUTNIK"]) + assert browser.sputnik?(%w[>=4 <5]) + end +end diff -Nru ruby-browser-2.5.3/test/unit/yandex_test.rb ruby-browser-4.2.0/test/unit/yandex_test.rb --- ruby-browser-2.5.3/test/unit/yandex_test.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-browser-4.2.0/test/unit/yandex_test.rb 2020-06-19 05:24:10.000000000 +0000 @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require "test_helper" + +class YandexTest < Minitest::Test + test "detects Yandex on iOS device" do + browser = Browser.new(Browser["YANDEX_BROWSER_IOS"]) + assert browser.yandex? + assert browser.yandex_browser? + refute browser.safari? + refute browser.chrome? + assert browser.webkit? + assert_equal "Yandex", browser.name + assert_equal :yandex, browser.id + end + + test "detects Yandex on non-iOS devices" do + browser = Browser.new(Browser["YANDEX_BROWSER_DESKTOP"]) + assert browser.yandex? + assert browser.yandex_browser? + refute browser.safari? + refute browser.chrome? + assert_equal "Yandex", browser.name + assert_equal :yandex, browser.id + end + + test "detects correct version" do + browser = Browser.new(Browser["YANDEX_BROWSER_DESKTOP"]) + assert_equal "19.6.0.1583", browser.full_version + assert_equal "19", browser.version + end + + test "detects version by range" do + browser = Browser.new(Browser["YANDEX_BROWSER_DESKTOP"]) + assert browser.yandex?(%w[>=18 <20]) + end +end diff -Nru ruby-browser-2.5.3/.travis.yml ruby-browser-4.2.0/.travis.yml --- ruby-browser-2.5.3/.travis.yml 2018-08-31 22:51:22.000000000 +0000 +++ ruby-browser-4.2.0/.travis.yml 2020-06-19 05:24:10.000000000 +0000 @@ -1,16 +1,23 @@ +--- language: ruby -sudo: false cache: bundler rvm: - - '2.4.2' - - '2.3.5' + - 2.7 + - 2.6 + - 2.5 gemfile: - Gemfile - - gemfiles/rails4.gemfile - gemfiles/rails5.gemfile + - gemfiles/rails6.gemfile script: bundle exec rake notifications: email: false +before_script: + - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter + - chmod +x ./cc-test-reporter + - "./cc-test-reporter before-build" +after_script: + - "./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT" env: global: - secure: egPPk/jMVzOoZGkk8jcf1f1N++oI4p4hqtk53T2kpHChxpmR8sP/oFlAhebvqMhM8svbQx+lWTvdxPDj9GBQGsC4ekqubV6S0MNJQS4/F41PSEU+DFUzNU1PHiDO+/0AbIheTj15UIt8IC4NVaM236HuSdMDWOjVI3ydBsgJ/GY= + secure: LrxynbbiJMX5vy/UVPfQsnT21oUpqpuHbUM9YOy0+ZYfDCjprvM/UGxFgjM+unRzyPI0mrNyU65ohpj8R1//tvdFW+xYau6QmFgSTU6OAQrckW/n+jqwQZV37a38wEGV0QvA6A0HW9pTrJfatUBmpaAeHAxcaBMk51tEgX/8poA=