Skip to content
Browse files

Adds python implementation

  • Loading branch information...
1 parent 7d3a2e7 commit 037f45f1662f21bd8f0face9e07f28973f713b92 Lindsey Simon committed Apr 4, 2012
View
3 .gitignore
@@ -1,2 +1 @@
-regexes.yaml
-node_modules
+node_modules
View
49 README.markdown
@@ -1,7 +1,7 @@
ua-parser
=========
-`ua-parser` is a port to [node.js][1] of [BrowserScope][2]'s [user agent string parser][3].
+`ua-parser` is a port to [node.js][1] and python of [BrowserScope][2]'s [user agent string parser][3].
The crux of the original parser--the data collected by [Steve Souders][4] over the years--has been extracted into a separate [JSON file][5] so as to be reusable _as is_ by implementations in other programming languages.
@@ -10,39 +10,44 @@ The crux of the original parser--the data collected by [Steve Souders][4] over t
Usage
-----
-```javascript
-var uaParser = require('ua-parser');
-var ua = uaParser.parse(navigator.userAgent);
+ var uaParser = require('ua-parser');
+ var ua = uaParser.parse(navigator.userAgent);
-console.log(ua.tostring());
-// -> "Safari 5.0.1"
+ console.log(ua.tostring());
+ // -> "Safari 5.0.1"
-console.log(ua.toVersionString());
-// -> "5.0.1"
+ console.log(ua.toVersionString());
+ // -> "5.0.1"
-console.log(ua.toFullString());
-// -> "Safari 5.0.1/Mac OS X"
+ console.log(ua.family);
+ // -> "Safari"
-console.log(ua.family);
-// -> "Safari"
+ console.log(ua.major);
+ // -> 5
-console.log(ua.major);
-// -> 5
+ console.log(ua.minor);
+ // -> 0
-console.log(ua.minor);
-// -> 0
+ console.log(ua.patch);
+ // -> 1
-console.log(ua.patch);
-// -> 1
-console.log(ua.os);
-// -> Mac OS X
-```
+Usage :: python
+---------------
+
+ # Python won't do with dashes in module names so you'll need to rename
+ # this directory. i.e. mv ua-parser ua_parser
+ from ua_parser.py import user_agent_parser
+
+ # On the server, let's say you have a WebOB request object.
+ user_agent_string = request.META.get('HTTP_USER_AGENT')
+ family, v1, v2, v3 = user_agent_parser.Parse(user_agent_string)
+
License
-------
-Your choice of [MIT or Apache, Version 2.0 licenses][6] for the JS code which is Copyright 2010 Tobie Langel.
+Your choice of [MIT][6] or [Apache License, Version 2.0][7] for the JS code which is Copyright 2010 Tobie Langel.
The data contained in `regexes.json` is Copyright 2009 Google Inc. and available under the [Apache License, Version 2.0][7].
View
0 py/__init__.py
No changes.
View
385 py/user_agent_parser.py
@@ -0,0 +1,385 @@
+#!/usr/bin/env python
+#
+# Copyright 2009 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the 'License')
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an 'AS IS' BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Python implementation of the UA parser."""
+
+__author__ = 'Lindsey Simon <elsigh@gmail.com>'
+
+import os
+import re
+import yaml
+
+
+ROOT_DIR = os.path.abspath(os.path.dirname(__file__))
+
+class UserAgentParser(object):
+ def __init__(self, pattern, family_replacement=None, v1_replacement=None):
+ """Initialize UserAgentParser.
+
+ Args:
+ pattern: a regular expression string
+ family_replacement: a string to override the matched family (optional)
+ v1_replacement: a string to override the matched v1 (optional)
+ """
+ self.pattern = pattern
+ self.user_agent_re = re.compile(self.pattern)
+ self.family_replacement = family_replacement
+ self.v1_replacement = v1_replacement
+
+ def MatchSpans(self, user_agent_string):
+ match_spans = []
+ match = self.user_agent_re.search(user_agent_string)
+ if match:
+ match_spans = [match.span(group_index)
+ for group_index in range(1, match.lastindex + 1)]
+ return match_spans
+
+ def Parse(self, user_agent_string):
+ family, v1, v2, v3 = None, None, None, None
+ match = self.user_agent_re.search(user_agent_string)
+ if match:
+ if self.family_replacement:
+ if re.search(r'\$1', self.family_replacement):
+ family = re.sub(r'\$1', match.group(1), self.family_replacement)
+ else:
+ family = self.family_replacement
+ else:
+ family = match.group(1)
+
+ if self.v1_replacement:
+ v1 = self.v1_replacement
+ elif match.lastindex >= 2:
+ v1 = match.group(2)
+
+ if match.lastindex >= 3:
+ v2 = match.group(3)
+ if match.lastindex >= 4:
+ v3 = match.group(4)
+ return family, v1, v2, v3
+
+class OSParser(object):
+ def __init__(self, pattern, os_replacement=None ):
+ """Initialize UserAgentParser.
+
+ Args:
+ pattern: a regular expression string
+ os_replacement: a string to override the matched os (optional)
+ """
+ self.pattern = pattern
+ self.user_agent_re = re.compile(self.pattern)
+ self.os_replacement = os_replacement
+
+ def MatchSpans(self, user_agent_string):
+ match_spans = []
+ match = self.user_agent_re.search(user_agent_string)
+ if match:
+ match_spans = [match.span(group_index)
+ for group_index in range(1, match.lastindex + 1)]
+ return match_spans
+
+ def Parse(self, user_agent_string):
+ os, os_v1, os_v2, os_v3, os_v4 = None, None, None, None, None
+ match = self.user_agent_re.search(user_agent_string)
+ if match:
+ if self.os_replacement:
+ os = self.os_replacement
+ else:
+ os = match.group(1)
+
+ if match.lastindex >= 2:
+ os_v1 = match.group(2)
+ if match.lastindex >= 3:
+ os_v2 = match.group(3)
+ if match.lastindex >= 4:
+ os_v3 = match.group(4)
+ if match.lastindex >= 5:
+ os_v4 = match.group(5)
+
+ return os, os_v1, os_v2, os_v3, os_v4
+
+class DeviceParser(object):
+ def __init__(self, pattern, device_replacement=None):
+ """Initialize UserAgentParser.
+
+ Args:
+ pattern: a regular expression string
+ device_replacement: a string to override the matched device (optional)
+ """
+ self.pattern = pattern
+ self.user_agent_re = re.compile(self.pattern)
+ self.device_replacement = device_replacement
+
+ def MatchSpans(self, user_agent_string):
+ match_spans = []
+ match = self.user_agent_re.search(user_agent_string)
+ if match:
+ match_spans = [match.span(group_index)
+ for group_index in range(1, match.lastindex + 1)]
+ return match_spans
+
+ def Parse(self, user_agent_string):
+ device = None
+ match = self.user_agent_re.search(user_agent_string)
+ if match:
+ if self.device_replacement:
+ if re.search(r'\$1', self.device_replacement):
+ device = re.sub(r'\$1', match.group(1), self.device_replacement)
+ else:
+ device = self.device_replacement
+ else:
+ device = match.group(1)
+
+ return device
+
+
+def ParseAll(user_agent_string, **jsParseBits):
+ """ Parse all the things
+ Args:
+ user_agent_string: the full user agent string
+ jsParseBits: javascript override bits
+ Returns:
+ flat dictionary containing all parsed bits
+ """
+ jsParseBits = jsParseBits or {}
+
+ resultUA = ParseUserAgent(user_agent_string, **jsParseBits)
+ resultOS = ParseOS(user_agent_string, **jsParseBits)
+
+ resultAll = {}
+ for result in (resultUA, resultOS):
+ resultAll.update(result)
+
+ return resultAll
+
+def ParseUserAgent(user_agent_string, **jsParseBits):
+ """ Parses the user-agent string for user agent (browser) info.
+ Args:
+ user_agent_string: The full user-agent string.
+ jsParseBits: javascript override bits
+ Returns:
+ flat dictionary containing parsed bits
+ """
+ if 'js_user_agent_family' in jsParseBits and jsParseBits['js_user_agent_family'] != '':
+ family = jsParseBits['js_user_agent_family']
+ if 'js_user_agent_v1' in jsParseBits:
+ v1 = jsParseBits['js_user_agent_v1'] or None
+ if 'js_user_agent_v2' in jsParseBits:
+ v2 = jsParseBits['js_user_agent_v2'] or None
+ if 'js_user_agent_v3' in jsParseBits:
+ v3 = jsParseBits['js_user_agent_v3'] or None
+ else:
+ for uaParser in USER_AGENT_PARSERS:
+ family, v1, v2, v3 = uaParser.Parse(user_agent_string)
+ if family:
+ break
+
+ # Override for Chrome Frame IFF Chrome is enabled.
+ if 'js_user_agent_string' in jsParseBits:
+ js_user_agent_string = jsParseBits['js_user_agent_string']
+ if (js_user_agent_string and js_user_agent_string.find('Chrome/') > -1 and
+ user_agent_string.find('chromeframe') > -1):
+ jsOverride = {}
+ jsOverride = ParseUserAgent(js_user_agent_string)
+ family = 'Chrome Frame (%s %s)' % (family, v1)
+ v1 = jsOverride['v1']
+ v2 = jsOverride['v2']
+ v3 = jsOverride['v3']
+
+ family = family or 'Other'
+ return {'family': family, 'v1': v1, 'v2': v2, 'v3': v3}
+
+def ParseOS(user_agent_string, **jsParseBits):
+ """ Parses the user-agent string for operating system info
+ Args:
+ user_agent_string: The full user-agent string.
+ jsParseBits: javascript override bits
+ Returns:
+ flat dictionary containing parsed bits
+ """
+ for osParser in OS_PARSERS:
+ os, os_v1, os_v2, os_v3, os_v4 = osParser.Parse(user_agent_string)
+ if os:
+ break
+ os = os or 'Other'
+ return { 'os': os, 'os_v1': os_v1, 'os_v2': os_v2, 'os_v3': os_v3, 'os_v4': os_v4 }
+
+def ParseDevice(user_agent_string, **jsParseBits):
+ """ incomplete! """
+ for deviceParser in DEVICE_PARSERS:
+ device = deviceParser.Parse(user_agent_string)
+ if device:
+ break
+
+ device = device or 'Other'
+ return {'device': device}
+
+def PrettyUserAgent(family, v1=None, v2=None, v3=None):
+ """Pretty user agent string."""
+ if v3:
+ if v3[0].isdigit():
+ return '%s %s.%s.%s' % (family, v1, v2, v3)
+ else:
+ return '%s %s.%s%s' % (family, v1, v2, v3)
+ elif v2:
+ return '%s %s.%s' % (family, v1, v2)
+ elif v1:
+ return '%s %s' % (family, v1)
+ return family
+
+def PrettyOS(os, os_v1=None, os_v2=None, os_v3=None, os_v4=None):
+ """Pretty os string."""
+ if os_v4:
+ return '%s %s.%s.%s.%s' % (os, os_v1, os_v2, os_v3, os_v4)
+ if os_v3:
+ if os_v3[0].isdigit():
+ return '%s %s.%s.%s' % (os, os_v1, os_v2, os_v3)
+ else:
+ return '%s %s.%s%s' % (os, os_v1, os_v2, os_v3)
+ elif os_v2:
+ return '%s %s.%s' % (os, os_v1, os_v2)
+ elif os_v1:
+ return '%s %s' % (os, os_v1)
+ return os
+
+def Parse(user_agent_string, js_user_agent_string=None,
+ js_user_agent_family=None,
+ js_user_agent_v1=None,
+ js_user_agent_v2=None,
+ js_user_agent_v3=None):
+ """ backwards compatible. use one of the other Parse methods instead! """
+
+ # Override via JS properties.
+ if js_user_agent_family is not None and js_user_agent_family != '':
+ family = js_user_agent_family
+ v1 = None
+ v2 = None
+ v3 = None
+ if js_user_agent_v1 is not None:
+ v1 = js_user_agent_v1
+ if js_user_agent_v2 is not None:
+ v2 = js_user_agent_v2
+ if js_user_agent_v3 is not None:
+ v3 = js_user_agent_v3
+ else:
+ for parser in USER_AGENT_PARSERS:
+ family, v1, v2, v3 = parser.Parse(user_agent_string)
+ if family:
+ break
+
+ # Override for Chrome Frame IFF Chrome is enabled.
+ if (js_user_agent_string and js_user_agent_string.find('Chrome/') > -1 and
+ user_agent_string.find('chromeframe') > -1):
+ family = 'Chrome Frame (%s %s)' % (family, v1)
+ cf_family, v1, v2, v3 = Parse(js_user_agent_string)
+
+ return family or 'Other', v1, v2, v3
+
+def Pretty(family, v1=None, v2=None, v3=None):
+ """ backwards compatible. use PrettyUserAgent instead! """
+ if v3:
+ if v3[0].isdigit():
+ return '%s %s.%s.%s' % (family, v1, v2, v3)
+ else:
+ return '%s %s.%s%s' % (family, v1, v2, v3)
+ elif v2:
+ return '%s %s.%s' % (family, v1, v2)
+ elif v1:
+ return '%s %s' % (family, v1)
+ return family
+
+
+def GetFilters(user_agent_string, js_user_agent_string=None,
+ js_user_agent_family=None,
+ js_user_agent_v1=None,
+ js_user_agent_v2=None,
+ js_user_agent_v3=None):
+ """Return the optional arguments that should be saved and used to query.
+
+ js_user_agent_string is always returned if it is present. We really only need
+ it for Chrome Frame. However, I added it in the generally case to find other
+ cases when it is different. When the recording of js_user_agent_string was
+ added, we created new records for all new user agents.
+
+ Since we only added js_document_mode for the IE 9 preview case, it did not
+ cause new user agent records the way js_user_agent_string did.
+
+ js_document_mode has since been removed in favor of individual property
+ overrides.
+
+ Args:
+ user_agent_string: The full user-agent string.
+ js_user_agent_string: JavaScript ua string from client-side
+ js_user_agent_family: This is an override for the family name to deal
+ with the fact that IE platform preview (for instance) cannot be
+ distinguished by user_agent_string, but only in javascript.
+ js_user_agent_v1: v1 override - see above.
+ js_user_agent_v2: v1 override - see above.
+ js_user_agent_v3: v1 override - see above.
+ Returns:
+ {js_user_agent_string: '[...]', js_family_name: '[...]', etc...}
+ """
+ filters = {}
+ filterdict = {
+ 'js_user_agent_string': js_user_agent_string,
+ 'js_user_agent_family': js_user_agent_family,
+ 'js_user_agent_v1': js_user_agent_v1,
+ 'js_user_agent_v2': js_user_agent_v2,
+ 'js_user_agent_v3': js_user_agent_v3
+ }
+ for key, value in filterdict.items():
+ if value is not None and value != '':
+ filters[key] = value
+ return filters
+
+
+# Build the list of user agent parsers from YAML
+yamlFile = open(os.path.join(ROOT_DIR, '../regexes.yaml'))
+yaml = yaml.load(yamlFile)
+yamlFile.close()
+
+USER_AGENT_PARSERS = []
+for parser in yaml['user_agent_parsers']:
+ regex = parser['regex']
+
+ family_replacement = None
+ if 'family_replacement' in parser:
+ family_replacement = parser['family_replacement']
+
+ v1_replacement = None
+ if 'v1_replacement' in parser:
+ v1_replacement = parser['v1_replacement']
+
+ USER_AGENT_PARSERS.append(UserAgentParser(regex, family_replacement, v1_replacement))
+
+OS_PARSERS = []
+for parser in yaml['os_parsers']:
+ regex = parser['regex']
+
+ os_replacement = None
+ if 'os_replacement' in parser:
+ os_replacement = parser['os_replacement']
+
+ OS_PARSERS.append(OSParser(regex, os_replacement))
+
+DEVICE_PARSERS = []
+for parser in yaml['device_parsers']:
+ regex = parser['regex']
+
+ device_replacement = None
+ if 'device_replacement' in parser:
+ device_replacement = parser['device_replacement']
+
+DEVICE_PARSERS.append(DeviceParser(regex, device_replacement))
View
BIN py/user_agent_parser.pyc
Binary file not shown.
View
200 py/user_agent_parser_test.py
@@ -0,0 +1,200 @@
+#!/usr/bin/python2.5
+#
+# Copyright 2008 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the 'License')
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an 'AS IS' BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""User Agent Parser Unit Tests.
+Run:
+# python -m test.test_user_agent_parser
+or like:
+# python -m test.test_user_agent_parser ParseTest.testBrowserscopeStrings
+"""
+
+__author__ = 'slamm@google.com (Stephen Lamm)'
+
+import os
+import sys
+import unittest
+import yaml
+
+import user_agent_parser
+
+TEST_RESOURCES_DIR = os.path.join(os.path.abspath(os.path.dirname(__file__)),
+ '../test_resources')
+
+
+class ParseTest(unittest.TestCase):
+ def testBrowserscopeStrings(self):
+ self.runUserAgentTestsFromYAML(os.path.join(
+ TEST_RESOURCES_DIR, 'test_user_agent_parser.yaml'))
+
+ def testBrowserscopeStringsOS(self):
+ self.runOSTestsFromYAML(os.path.join(
+ TEST_RESOURCES_DIR , 'test_user_agent_parser_os.yaml'))
+
+ def testStringsOS(self):
+ self.runOSTestsFromYAML(os.path.join(
+ TEST_RESOURCES_DIR, 'additional_os_tests.yaml'))
+
+ def testMozillaStrings(self):
+ self.runUserAgentTestsFromYAML(os.path.join(
+ TEST_RESOURCES_DIR, 'firefox_user_agent_strings.yaml'))
+
+ # NOTE: The YAML file used here is one output by makePGTSComparisonYAML()
+ # below, as opposed to the pgts_browser_list-orig.yaml file. The -orig
+ # file is by no means perfect, but identifies many browsers that we
+ # classify as "Other". This test itself is mostly useful to know when
+ # somthing in UA parsing changes. An effort should be made to try and
+ # reconcile the differences between the two YAML files.
+ def testPGTSStrings(self):
+ self.runUserAgentTestsFromYAML(os.path.join(
+ TEST_RESOURCES_DIR, 'pgts_browser_list.yaml'))
+
+ def testParseAll(self):
+ user_agent_string = 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.4; fr; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5,gzip(gfe),gzip(gfe)'
+ expected = {'os': 'Mac OS X',
+ 'os_v1': '10',
+ 'os_v2': '4',
+ 'os_v3': None,
+ 'os_v4': None,
+ 'family': 'Firefox',
+ 'v1': '3',
+ 'v2': '5',
+ 'v3': '5'}
+ result = user_agent_parser.ParseAll(user_agent_string)
+ self.assertEqual(result, expected,
+ u"UA: {0}\n expected<{1}> != actual<{2}>".format(user_agent_string, expected, result))
+
+ user_agent_string = 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; GTB6; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; OfficeLiveConnector.1.4; OfficeLivePatch.1.3; Media Center PC 6.0),gzip(gfe),gzip(gfe)'
+ expected = {'os': 'Windows 7',
+ 'os_v1': None,
+ 'os_v2': None,
+ 'os_v3': None,
+ 'os_v4': None,
+ 'family': 'IE',
+ 'v1': '8',
+ 'v2': '0',
+ 'v3': None}
+ result = user_agent_parser.ParseAll(user_agent_string)
+ self.assertEqual(result, expected,
+ u"UA: {0}\n expected<{1}> != actual<{2}>".format(user_agent_string, expected, result))
+
+ # Make a YAML file for manual comparsion with pgts_browser_list-orig.yaml
+ def makePGTSComparisonYAML(self):
+ import codecs
+ outfile = codecs.open('outfile.yaml', 'w', 'utf-8');
+ print >> outfile, "test_cases:"
+
+ yamlFile = open(os.path.join(TEST_RESOURCES_DIR,
+ 'pgts_browser_list.yaml'))
+ yamlContents = yaml.load(yamlFile)
+ yamlFile.close()
+
+ for test_case in yamlContents['test_cases']:
+ user_agent_string = test_case['user_agent_string']
+ kwds = {}
+ if 'js_ua' in test_case:
+ kwds = eval(test_case['js_ua'])
+
+ (family, v1, v2, v3) = user_agent_parser.ParseUserAgent(user_agent_string, **kwds)
+
+ # Escape any double-quotes in the UA string
+ user_agent_string = re.sub(r'"', '\\"', user_agent_string)
+ print >> outfile, ' - user_agent_string: "' + unicode(user_agent_string) + '"' + "\n" +\
+ ' family: "' + family + "\"\n" +\
+ " v1: " + ('' if (v1 is None) else "'" + v1 + "'") + "\n" +\
+ " v2: " + ('' if (v2 is None) else "'" + v2 + "'") + "\n" +\
+ " v3: " + ('' if (v3 is None) else "'" + v3 + "'")
+ outfile.close()
+
+ # Run a set of test cases from a YAML file
+ def runUserAgentTestsFromYAML(self, file_name):
+ yamlFile = open(os.path.join(TEST_RESOURCES_DIR, file_name))
+ yamlContents = yaml.load(yamlFile)
+ yamlFile.close()
+
+ for test_case in yamlContents['test_cases']:
+ # Inputs to Parse()
+ user_agent_string = test_case['user_agent_string']
+ kwds = {}
+ if 'js_ua' in test_case:
+ kwds = eval(test_case['js_ua'])
+
+ # The expected results
+ expected = {'family': test_case['family'],
+ 'v1': test_case['v1'],
+ 'v2': test_case['v2'],
+ 'v3': test_case['v3']}
+
+ result = {}
+ result = user_agent_parser.ParseUserAgent(user_agent_string, **kwds)
+ self.assertEqual(result, expected,
+ u"UA: {0}\n expected<{1}, {2}, {3}, {4}> != actual<{5}, {6}, {7}, {8}>".format(\
+ user_agent_string,
+ expected['family'], expected['v1'], expected['v2'], expected['v3'],
+ result['family'], result['v1'], result['v2'], result['v3']))
+
+ def runOSTestsFromYAML(self, file_name):
+ yamlFile = open(os.path.join(TEST_RESOURCES_DIR, file_name))
+ yamlContents = yaml.load(yamlFile)
+ yamlFile.close()
+
+ for test_case in yamlContents['test_cases']:
+ # Inputs to Parse()
+ user_agent_string = test_case['user_agent_string']
+ kwds = {}
+ if 'js_ua' in test_case:
+ kwds = eval(test_case['js_ua'])
+
+ # The expected results
+ expected = {'os': test_case['os'],
+ 'os_v1': test_case['os_v1'],
+ 'os_v2': test_case['os_v2'],
+ 'os_v3': test_case['os_v3'],
+ 'os_v4': test_case['os_v4']}
+
+ result = {}
+ result = user_agent_parser.ParseOS(user_agent_string, **kwds)
+ self.assertEqual(result, expected,
+ u"UA: {0}\n expected<{1} {2} {3} {4} {5}> != actual<{6} {7} {8} {9} {10}>".format(\
+ user_agent_string,
+ expected['os'], expected['os_v1'], expected['os_v2'], expected['os_v3'], expected['os_v4'],
+ result['os'], result['os_v1'], result['os_v2'], result['os_v3'], result['os_v4']))
+
+class GetFiltersTest(unittest.TestCase):
+ def testGetFiltersNoMatchesGiveEmptyDict(self):
+ user_agent_string = 'foo'
+ filters = user_agent_parser.GetFilters(
+ user_agent_string, js_user_agent_string=None)
+ self.assertEqual({}, filters)
+
+ def testGetFiltersJsUaPassedThrough(self):
+ user_agent_string = 'foo'
+ filters = user_agent_parser.GetFilters(
+ user_agent_string, js_user_agent_string='bar')
+ self.assertEqual({'js_user_agent_string': 'bar'}, filters)
+
+ def testGetFiltersJsUserAgentFamilyAndVersions(self):
+ user_agent_string = ('Mozilla/4.0 (compatible; MSIE 8.0; '
+ 'Windows NT 5.1; Trident/4.0; GTB6; .NET CLR 2.0.50727; '
+ '.NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)')
+ filters = user_agent_parser.GetFilters(
+ user_agent_string, js_user_agent_string='bar',
+ js_user_agent_family='foo')
+ self.assertEqual({'js_user_agent_string': 'bar',
+ 'js_user_agent_family': 'foo'}, filters)
+
+
+if __name__ == '__main__':
+ unittest.main()
View
457 regexes.yaml
@@ -0,0 +1,457 @@
+user_agent_parsers:
+ #### SPECIAL CASES TOP ####
+
+ # must go before Opera
+ - regex: '^(Opera)/(\d+)\.(\d+) \(Nintendo Wii'
+ family_replacement: 'Wii'
+
+ # must go before Firefox to catch SeaMonkey.
+ - regex: '(SeaMonkey|Fennec|Camino)/(\d+)\.(\d+)\.?([ab]?\d+[a-z]*)'
+
+ # must go before Firefox
+
+ # must go before Browser/major_version.minor_version - eg: Minefield/3.1a1pre
+ - regex: '(Namoroka|Shiretoko|Minefield)/(\d+)\.(\d+)\.(\d+(?:pre)?)'
+ family_replacement: 'Firefox ($1)'
+
+ - regex: '(Firefox)/(\d+)\.(\d+)([ab]\d+[a-z]*)'
+ family_replacement: 'Firefox Beta'
+
+ - regex: '(Firefox)-(?:\d+\.\d+)?/(\d+)\.(\d+)([ab]\d+[a-z]*)'
+ family_replacement: 'Firefox Beta'
+
+ - regex: '(Namoroka|Shiretoko|Minefield)/(\d+)\.(\d+)([ab]\d+[a-z]*)?'
+ family_replacement: 'Firefox ($1)'
+
+ - regex: '(Firefox).*Tablet browser (\d+)\.(\d+)\.(\d+)'
+ family_replacement: 'MicroB'
+
+ - regex: '(MozillaDeveloperPreview)/(\d+)\.(\d+)([ab]\d+[a-z]*)?'
+
+ # e.g.: Flock/2.0b2
+ - regex: '(Flock)/(\d+)\.(\d+)(b\d+?)'
+
+ # RockMelt
+ - regex: '(RockMelt)/(\d+)\.(\d+)\.(\d+)'
+
+ # e.g.: Fennec/0.9pre
+ - regex: '(Fennec)/(\d+)\.(\d+)(pre)'
+
+ - regex: '(Navigator)/(\d+)\.(\d+)\.(\d+)'
+ family_replacement: 'Netscape'
+
+ - regex: '(Navigator)/(\d+)\.(\d+)([ab]\d+)'
+ family_replacement: 'Netscape'
+
+ - regex: '(Netscape6)/(\d+)\.(\d+)\.(\d+)'
+ family_replacement: 'Netscape'
+
+ - regex: '(MyIBrow)/(\d+)\.(\d+)'
+ family_replacement: 'My Internet Browser'
+
+ # Opera will stop at 9.80 and hide the real version in the Version string.
+ # see: http://dev.opera.com/articles/view/opera-ua-string-changes/
+ - regex: '(Opera Tablet).*Version\/(\d+)\.(\d+)(?:\.(\d+))?'
+
+ - regex: '(Opera)/.+Opera Mobi.+Version/(\d+)\.(\d+)'
+ family_replacement: 'Opera Mobile'
+
+ - regex: '(Opera Mini)/(\d+)\.(\d+)'
+
+ - regex: '(Opera)/9.80.*Version\/(\d+)\.(\d+)(?:\.(\d+))?'
+
+ # Palm WebOS looks a lot like Safari.
+ - regex: '(webOS)/(\d+)\.(\d+)'
+ family_replacement: 'Palm webOS'
+
+ # LuaKit has no version info.
+ # http://luakit.org/projects/luakit/
+ - regex: '(luakit)'
+ family_replacement: 'LuaKit'
+
+ # Lightning (for Thunderbird)
+ # http://www.mozilla.org/projects/calendar/lightning/
+ - regex: '(Lightning)/(\d+)\.(\d+)([ab]?\d+[a-z]*)'
+
+ # Swiftfox
+ - regex: '(Firefox)/(\d+)\.(\d+)\.(\d+(?:pre)?) \(Swiftfox\)'
+ family_replacement: 'Swiftfox'
+ - regex: '(Firefox)/(\d+)\.(\d+)([ab]\d+[a-z]*)? \(Swiftfox\)'
+ family_replacement: 'Swiftfox'
+
+ # Rekonq
+ - regex: 'rekonq'
+ family_replacement: 'Rekonq'
+
+ # Conkeror lowercase/uppercase
+ # http://conkeror.org/
+ - regex: '(conkeror|Conkeror)/(\d+)\.(\d+)\.?(\d+)?'
+ family_replacement: 'Conkeror'
+
+ # catches lower case konqueror
+ - regex: '(konqueror)/(\d+)\.(\d+)\.(\d+)'
+ family_replacement: 'Konqueror'
+
+ - regex: '(PlayBook).+RIM Tablet OS (\d+)\.(\d+)\.(\d+)'
+
+ - regex: '(WeTab)-Browser'
+
+ - regex: '(wOSBrowser).+TouchPad/(\d+)\.(\d+)'
+ family_replacement: 'webOS TouchPad'
+
+ - regex: '(Comodo_Dragon)/(\d+)\.(\d+)\.(\d+)'
+ family_replacement: 'Comodo Dragon'
+
+ # YottaaMonitor bot
+ - regex: '(YottaaMonitor)'
+
+ # must go before NetFront below
+ - regex: '(Kindle)/(\d+)\.(\d+)'
+
+ # must go before Android below.
+ - regex: '(CrMo)/(\d+)\.(\d+)\.(\d+)'
+ family_replacement: 'Chrome Mobile'
+
+
+ #### END SPECIAL CASES TOP ####
+
+ #### MAIN CASES - this catches > 50% of all browsers ####
+
+ # Browser/major_version.minor_version.beta_version
+ - regex: '(AdobeAIR|Chromium|FireWeb|Jasmine|ANTGalio|Midori|Fresco|Lobo|PaleMoon|Maxthon|Lynx|OmniWeb|Dillo|Camino|Demeter|Fluid|Fennec|Shiira|Sunrise|Chrome|Flock|Netscape|Lunascape|Epiphany|WebPilot|Vodafone|NetFront|Konqueror|SeaMonkey|Kazehakase|Vienna|Iceape|Iceweasel|IceWeasel|Iron|K-Meleon|Sleipnir|Galeon|GranParadiso|Opera Mini|iCab|NetNewsWire|ThunderBrowse|Iron|Iris)/(\d+)\.(\d+)\.(\d+)'
+
+ # Browser/major_version.minor_version
+ - regex: '(Bolt|Jasmine|IceCat|Skyfire|Midori|Maxthon|Lynx|Arora|IBrowse|Dillo|Camino|Shiira|Fennec|Phoenix|Chrome|Flock|Netscape|Lunascape|Epiphany|WebPilot|Opera Mini|Opera|Vodafone|NetFront|Konqueror|Googlebot|SeaMonkey|Kazehakase|Vienna|Iceape|Iceweasel|IceWeasel|Iron|K-Meleon|Sleipnir|Galeon|GranParadiso|iCab|NetNewsWire|Iron|Space Bison|Stainless|Orca|Dolfin|BOLT)/(\d+)\.(\d+)'
+
+ # Browser major_version.minor_version.beta_version (space instead of slash)
+ - regex: '(iRider|Crazy Browser|SkipStone|iCab|Lunascape|Sleipnir|Maemo Browser) (\d+)\.(\d+)\.(\d+)'
+ # Browser major_version.minor_version (space instead of slash)
+ - regex: '(iCab|Lunascape|Opera|Android) (\d+)\.(\d+)\.?(\d+)?'
+
+ # IE Mobile
+ - regex: '(IEMobile)[ /](\d+)\.(\d+)'
+ family_replacement: 'IE Mobile'
+ # desktop mode
+ # http://www.anandtech.com/show/3982/windows-phone-7-review
+ - regex: '(MSIE) (\d+)\.(\d+).*XBLWP7'
+ family_replacement: 'IE Mobile'
+
+ # AFTER THE EDGE CASES ABOVE!
+ - regex: '(Firefox)/(\d+)\.(\d+)\.(\d+)'
+
+ - regex: '(Firefox)/(\d+)\.(\d+)(pre|[ab]\d+[a-z]*)?'
+ #### END MAIN CASES ####
+
+ #### SPECIAL CASES ####
+ - regex: '(Obigo|OBIGO)[^\d]*(\d+)(?:.(\d+))?'
+ family_replacement: 'Obigo'
+
+ - regex: '(MAXTHON|Maxthon) (\d+)\.(\d+)'
+ family_replacement: 'Maxthon'
+
+ - regex: '(Maxthon|MyIE2|Uzbl|Shiira)'
+ v1_replacement: '0'
+
+ - regex: '(PLAYSTATION) (\d+)'
+ family_replacement: 'PlayStation'
+
+ - regex: '(PlayStation Portable)[^\d]+(\d+).(\d+)'
+
+ - regex: '(BrowseX) \((\d+)\.(\d+)\.(\d+)'
+
+ - regex: '(POLARIS)/(\d+)\.(\d+)'
+ family_replacement: 'Polaris'
+
+ - regex: '(BonEcho)/(\d+)\.(\d+)\.(\d+)'
+ family_replacement: 'Bon Echo'
+
+ - regex: '(iPod).+Version/(\d+)\.(\d+)\.(\d+)'
+
+ - regex: '(iPhone) OS (\d+)_(\d+)(?:_(\d+))?'
+
+ - regex: '(iPad).+ OS (\d+)_(\d+)(?:_(\d+))?'
+
+ - regex: '(Avant)'
+ v1_replacement: '1'
+
+ - regex: '(Nokia)[EN]?(\d+)'
+
+ # BlackBerry devices
+ - regex: '(Black[bB]erry).+Version\/(\d+)\.(\d+)\.(\d+)'
+ family_replacement: 'Blackberry'
+
+ - regex: '(Black[bB]erry)\s?(\d+)'
+ family_replacement: 'Blackberry'
+
+ - regex: '(OmniWeb)/v(\d+)\.(\d+)'
+
+ - regex: '(Blazer)/(\d+)\.(\d+)'
+ family_replacement: 'Palm Blazer'
+
+ - regex: '(Pre)/(\d+)\.(\d+)'
+ family_replacement: 'Palm Pre'
+
+ - regex: '(Links) \((\d+)\.(\d+)'
+
+ - regex: '(QtWeb) Internet Browser/(\d+)\.(\d+)'
+
+ #- regex: '\(iPad;.+(Version)/(\d+)\.(\d+)(?:\.(\d+))?.*Safari/'
+ # family_replacement: 'iPad'
+
+ # Amazon Silk, should go before Safari
+ - regex: '(Silk)/(\d+)\.(\d+)(?:\.([0-9\-]+))?'
+
+ # Safari
+ - regex: '(Version)/(\d+)\.(\d+)(?:\.(\d+))?.*Safari/'
+ family_replacement: 'Safari'
+ # Safari didn't provide "Version/d.d.d" prior to 3.0
+ - regex: '(Safari)/\d+'
+
+ - regex: '(OLPC)/Update(\d+)\.(\d+)'
+
+ - regex: '(OLPC)/Update()\.(\d+)'
+ v1_replacement: '0'
+
+ - regex: '(SamsungSGHi560)'
+ family_replacement: 'Samsung SGHi560'
+
+ - regex: '^(SonyEricssonK800i)'
+ family_replacement: 'Sony Ericsson K800i'
+
+ - regex: '(Teleca Q7)'
+
+ - regex: '(MSIE) (\d+)\.(\d+)'
+ family_replacement: 'IE'
+
+
+os_parsers:
+ ##########
+ # Windows
+ # http://en.wikipedia.org/wiki/Windows_NT#Releases
+ # possibility of false positive when different marketing names share same NT kernel
+ # e.g. windows server 2003 and windows xp
+ # lots of ua strings have Windows NT 4.1 !?!?!?!? !?!? !? !????!?! !!! ??? !?!?! ?
+ # (very) roughly ordered in terms of frequency of occurence of regex (win xp currently most frequent, etc)
+ ##########
+ - regex: '(Windows (?:NT 5\.2|NT 5\.1))'
+ os_replacement: 'Windows XP'
+
+ # ie mobile des ktop mode
+ # spoofs nt 6.1. must come before windows 7
+ - regex: '(XBLWP7)'
+ os_replacement: 'Windows Phone OS'
+
+ - regex: '(Windows NT 6\.1)'
+ os_replacement: 'Windows 7'
+
+ - regex: '(Windows NT 6\.0)'
+ os_replacement: 'Windows Vista'
+
+ - regex: '(Windows 98|Windows XP|Windows ME|Windows 95|Windows CE|Windows 7|Windows NT 4\.0|Windows Vista|Windows 2000)'
+
+ # is this a spoof or is nt 6.2 out and about in some capacity?
+ - regex: '(Windows NT 6\.2)'
+ os_replacement: 'Windows 8'
+
+ - regex: '(Windows NT 5\.0)'
+ os_replacement: 'Windows 2000'
+
+ - regex: '(Windows Phone OS) (\d+)\.(\d+)'
+
+ - regex: '(Windows ?Mobile)'
+ os_replacement: 'Windows Mobile'
+
+ - regex: '(WinNT4.0)'
+ os_replacement: 'Windows NT 4.0'
+
+ - regex: '(Win98)'
+ os_replacement: 'Windows 98'
+
+ ##########
+ # Android
+ # can actually detect rooted android os. do we care?
+ ##########
+ - regex: '(Android) (\d+)\.(\d+)(?:[.\-]([a-z0-9]+))?'
+
+ - regex: '(Android) Donut'
+ os_v1_replacement: '1'
+ os_v2_replacement: '2'
+
+ - regex: '(Android) Eclair'
+ os_v1_replacement: '2'
+ os_v2_replacement: '1'
+
+ - regex: '(Android) Froyo'
+ os_v1_replacement: '2'
+ os_v2_replacement: '2'
+
+ - regex: '(Android) Gingerbread'
+ os_v1_replacement: '2'
+ os_v2_replacement: '3'
+
+ - regex: '(Android) Honeycomb'
+ os_v1_replacement: '3'
+
+ ##########
+ # Mac OS
+ # http://en.wikipedia.org/wiki/Mac_OS_X#Versions
+ ##########
+ - regex: '(Mac OS X) (\d+)[_.](\d+)(?:[_.](\d+))?'
+
+ # builds before tiger don't seem to specify version?
+
+ # ios devices spoof (mac os x), so including intel/ppc prefixes
+ - regex: '(?:PPC|Intel) (Mac OS X)'
+
+ ##########
+ # iOS
+ # http://en.wikipedia.org/wiki/IOS_version_history
+ ##########
+ - regex: '(CPU OS|iPhone OS) (\d+)_(\d+)(?:_(\d+))?'
+ os_replacement: 'iOS'
+
+ # remaining cases are mostly only opera uas, so catch opera as to not catch iphone spoofs
+ - regex: '(iPhone|iPad|iPod); Opera'
+ os_replacement: 'iOS'
+
+ # few more stragglers
+ - regex: '(iPhone|iPad|iPod).*Mac OS X'
+ os_replacement: 'iOS'
+
+ ##########
+ # Chrome OS
+ # if version 0.0.0, probably this stuff:
+ # http://code.google.com/p/chromium-os/issues/detail?id=11573
+ # http://code.google.com/p/chromium-os/issues/detail?id=13790
+ ##########
+ - regex: '(CrOS) [a-z0-9_]+ (\d+)\.(\d+)(?:\.(\d+))?'
+ os_replacement: 'Chrome OS'
+
+ ##########
+ # Linux distros
+ ##########
+ - regex: '(Debian)-(\d+)\.(\d+)\.(\d+)(?:\.(\d+))?'
+ - regex: '(Linux Mint)(?:/(\d+))?'
+ - regex: '(Mandriva)(?: Linux)?/(\d+)\.(\d+)\.(\d+)(?:\.(\d+))?'
+
+ ##########
+ # Symbian + Symbian OS
+ # http://en.wikipedia.org/wiki/History_of_Symbian
+ ##########
+ - regex: '(Symbian[Oo][Ss])/(\d+)\.(\d+)'
+ os_replacement: 'Symbian OS'
+ - regex: '(Symbian/3)'
+ os_replacement: 'Symbian^3'
+ - regex: '(Series 60|SymbOS|S60)'
+ os_replacement: 'Symbian OS'
+
+ ##########
+ # BlackBerry devices
+ ##########
+ - regex: '(Black[Bb]erry)[0-9a-z]+/(\d+)\.(\d+)\.(\d+)(?:\.(\d+))?'
+ os_replacement: 'BlackBerry OS'
+ - regex: '(Black[Bb]erry).+Version/(\d+)\.(\d+)\.(\d+)(?:\.(\d+))?'
+ os_replacement: 'BlackBerry OS'
+ - regex: '(RIM Tablet OS) (\d+)\.(\d+)\.(\d+)'
+ os_replacement: 'BlackBerry Tablet OS'
+ - regex: '(Play[Bb]ook)'
+ os_replacement: 'BlackBerry Tablet OS'
+ - regex: '(Black[Bb]erry)'
+ os_replacement: 'Blackberry OS'
+
+ ##########
+ # Misc mobile
+ ##########
+ - regex: '(webOS|hpwOS)/(\d+)\.(\d+)(?:\.(\d+))?'
+ os_replacement: 'webOS'
+
+ ##########
+ # Generic patterns
+ # since the majority of os cases are very specific, these go last
+ ##########
+ # first.second.third.fourth bits
+ - regex: '(SUSE|Fedora|Red Hat|PCLinuxOS)/(\d+)\.(\d+)\.(\d+)\.(\d+)'
+
+ # first.second.third bits
+ - regex: '(SUSE|Fedora|Red Hat|Puppy|PCLinuxOS|CentOS)/(\d+)\.(\d+)\.(\d+)'
+
+ # first.second bits
+ - regex: '(Ubuntu|Kindle|Bada|Lubuntu|BackTrack|Red Hat|Slackware)/(\d+)\.(\d+)'
+
+ # just os
+ - regex: '(Windows|OpenBSD|FreeBSD|NetBSD|Ubuntu|Kubuntu|Android|Arch Linux|CentOS|WeTab|Slackware)'
+ - regex: '(Linux|BSD)'
+
+device_parsers:
+ ##########
+ # incomplete!
+ # multiple replacement placeholds i.e. ($1) ($2) help solve problem of single device with multiple representations in ua
+ # e.g. HTC Dream S should parse to the same device as HTC_DreamS
+ ##########
+
+ ##########
+ # incomplete!
+ # HTC
+ # http://en.wikipedia.org/wiki/List_of_HTC_phones
+ # this is quickly getting unwieldy
+ ##########
+ # SPECIFIC CASES
+ - regex: '(HTC_VDA_V)'
+ device_replacement: 'HTC S710'
+ - regex: '(HTC-P4600)'
+ device_replacement: 'HTC Touch Pro'
+ - regex: '(HTCX06HT)'
+ device_replacement: 'HTC Desire'
+ - regex: '(HTC-A6366)'
+ device_replacement: 'HTC Aria'
+ - regex: 'HTC; (7 Mozart|T8697)'
+ device_replacement: 'HTC 7 Mozart'
+ - regex: '(HTC-ST7377)'
+ device_replacement: 'HTC Touch Pro2'
+ - regex: 'HTC; 7 Trophy'
+ device_replacement: 'HTC 7 Trophy'
+ - regex: 'HTC; HD7'
+ device_replacement: 'HTC HD7'
+
+ # example: Mozilla/5.0 (Linux; U; Android 2.3.2; fr-fr; HTC HD2 Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1
+ - regex: 'HTC ([A-Z][a-z0-9]+) Build'
+ device_replacement: 'HTC ($1)'
+ # example: Mozilla/5.0 (Linux; U; Android 2.1; es-es; HTC Legend 1.23.161.1 Build/ERD79) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17,gzip
+ - regex: 'HTC ([A-Z][a-z0-9 ]+) \d+\.\d+\.\d+\.\d+'
+ device_replacement: 'HTC ($1) ($2)'
+ # example: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; HTC_Touch_Diamond2_T5353; Windows Phone 6.5.3.5)
+ - regex: 'HTC_Touch_([A-Za-z0-9]+)'
+ device_replacement: 'HTC Touch ($1)'
+ # should come after HTC_Touch
+ - regex: 'HTC_([A-Za-z0-9]+)'
+ device: 'HTC ($1)'
+ - regex: '(HTC)'
+
+ ##########
+ # NOKIA
+ # nokia NokiaN8-00 comes before iphone. sometimes spoofs iphone
+ ##########
+ - regex: 'Nokia(?!Browser)([A-Za-z0-9\-])+'
+ device_replacement: 'Nokia ($1)'
+ - regex: 'Nokia ([A-Za-z0-9\-]+)'
+ device_replacement: 'Nokia ($1)'
+
+ ##########
+ # incomplete!
+ # PALM
+ ##########
+ # some palm devices must come before iphone. sometimes spoofs iphone in ua
+ - regex: '(Pre)/(\d+)\.(\d+)'
+ device_replacement: 'Palm Pre'
+ - regex: '(Pixi)/(\d+)\.(\d+)'
+ device_replacement: 'Palm Pixi'
+
+ ##########
+ # complete but probably catches spoofs
+ # iSTUFF
+ ##########
+ # ipad and ipod must be parsed before iphone
+ # cannot determine specific device type from ua string. (3g, 3gs, 4, etc)
+ - regex: '(iPad);'
+ - regex: '(iPod);'
+ - regex: '(iPhone);'
View
134 test_resources/additional_os_tests.yaml
@@ -0,0 +1,134 @@
+test_cases:
+
+ - user_agent_string: 'Mozilla/5.0 (Linux; U; Android 2.1-update1; en-us; Nexus One Build/ERE27) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17,gzip(gfe),gzip(gfe)'
+ os: 'Android'
+ os_v1: '2'
+ os_v2: '1'
+ os_v3: 'update1'
+ os_v4:
+
+ - user_agent_string: 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X Mach-O; en-en; rv:1.9.0.12) Gecko/2009070609 Firefox/3.0.12,gzip(gfe),gzip(gfe)'
+ os: 'Mac OS X'
+ os_v1:
+ os_v2:
+ os_v3:
+ os_v4:
+
+ - user_agent_string: 'Opera/9.80 (iPhone; Opera Mini/5.0.019802/21.572; U; en) Presto/2.5.25 Version/10.54'
+ os: 'iOS'
+ os_v1:
+ os_v2:
+ os_v3:
+ os_v4:
+
+ - user_agent_string: 'Mozilla/5.0 (SymbianOS/9.2; U; Series60/3.1 NokiaN95/12.0.013; Profile/MIDP-2.0 Configuration/CLDC-1.1 ) AppleWebKit/413 (KHTML, like Gecko) Safari/413'
+ os: 'Symbian OS'
+ os_v1: '9'
+ os_v2: '2'
+ os_v3:
+ os_v4:
+
+ - user_agent_string: 'Opera/9.80 (S60; SymbOS; Opera Mobi/499; U; de) Presto/2.4.18 Version/10.00,gzip(gfe),gzip(gfe)'
+ os: 'Symbian OS'
+ os_v1:
+ os_v2:
+ os_v3:
+ os_v4:
+
+ - user_agent_string: 'Mozilla/5.0 (Symbian/3; Series60/5.2 NokiaN8-00/010.022; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/525 (KHTML, like Gecko) Version/3.0 BrowserNG/7.2.6.3 3gpp-gba,gzip(gfe),gzip(gfe)'
+ os: 'Symbian^3'
+ os_v1:
+ os_v2:
+ os_v3:
+ os_v4:
+
+ - user_agent_string: 'BlackBerry9000/4.6.0.167 Profile/MIDP-2.0 Configuration/CLDC-1.1 VendorID/102'
+ os: 'BlackBerry OS'
+ os_v1: '4'
+ os_v2: '6'
+ os_v3: '0'
+ os_v4: '167'
+
+ - user_agent_string: 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.8) Gecko/20100723 Linux Mint/9 (Isadora) Firefox/3.6.8'
+ os: 'Linux Mint'
+ os_v1: '9'
+ os_v2:
+ os_v3:
+ os_v4:
+
+ - user_agent_string: 'Mozilla/5.0 (X11; CrOS i686 13.587.80) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.99 Safari/535.1'
+ os: 'Chrome OS'
+ os_v1: '13'
+ os_v2: '587'
+ os_v3: '80'
+ os_v4:
+
+ - user_agent_string: 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.1) Gecko/2008072310 Red Hat/3.0.1-3.el4 Firefox/3.0.1,gzip(gfe),gzip(gfe)'
+ os: 'Red Hat'
+ os_v1: '3'
+ os_v2: '0'
+ os_v3: '1'
+ os_v4:
+
+ - user_agent_string: 'Mozilla/5.0 ( U; Linux x86_32; en-US; rv:1.0) Gecko/20090723 Puppy/3.6.8-0.1.1 Firefox/3.6.7,gzip(gfe),gzip(gfe)'
+ os: 'Puppy'
+ os_v1: '3'
+ os_v2: '6'
+ os_v3: '8'
+ os_v4:
+
+ - user_agent_string: 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.14) Gecko/20110301 PCLinuxOS/1.9.2.14-1pclos2011 (2011) Firefox/3.6.14,gzip(gfe),gzip(gfe),gzip(gfe)'
+ os: 'PCLinuxOS'
+ os_v1: '1'
+ os_v2: '9'
+ os_v3: '2'
+ os_v4: '14'
+
+ - user_agent_string: 'Mozilla/5.0 (X11; U; Linux x86_64; cs-CZ; rv:1.9.0.4) Gecko/2008111217 Fedora/3.0.4-1.fc9 Firefox/3.0.4'
+ os: 'Fedora'
+ os_v1: '3'
+ os_v2: '0'
+ os_v3: '4'
+ os_v4:
+
+ - user_agent_string: 'Mozilla/5.0 (X11; 78; CentOS; US-en) AppleWebKit/527+ (KHTML, like Gecko) Bolt/0.862 Version/3.0 Safari/523.15'
+ os: 'CentOS'
+ os_v1:
+ os_v2:
+ os_v3:
+ os_v4:
+
+ - user_agent_string: 'Mozilla/5.0 (BlackBerry; U; BlackBerry 9780; en) AppleWebKit/534.8+ (KHTML, like Gecko) Version/6.0.0.526 Mobile Safari/534.8+,gzip(gfe),gzip(gfe),gzip(gfe)'
+ os: 'BlackBerry OS'
+ os_v1: '6'
+ os_v2: '0'
+ os_v3: '0'
+ os_v4: '526'
+
+ - user_agent_string: 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.2) Gecko/20090807 Mandriva Linux/1.9.1.2-1.1mud2009.1 (2009.1) Firefox/3.5.2 FirePHP/0.3,gzip(gfe),gzip(gfe)'
+ os: 'Mandriva'
+ os_v1: '1'
+ os_v2: '9'
+ os_v3: '1'
+ os_v4: '2'
+
+ - user_agent_string: 'Opera/9.80 (X11; Linux x86_64; U; Slackware; lt) Presto/2.8.131 Version/11.11'
+ os: 'Slackware'
+ os_v1:
+ os_v2:
+ os_v3:
+ os_v4:
+
+ - user_agent_string: 'Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0; SAMSUNG; SGH-i917)'
+ os: 'Windows Phone OS'
+ os_v1: '7'
+ os_v2: '5'
+ os_v3:
+ os_v4:
+
+ - user_agent_string: ''
+ os: 'Other'
+ os_v1:
+ os_v2:
+ os_v3:
+ os_v4:
View
349 test_resources/firefox_user_agent_strings.txt
@@ -0,0 +1,349 @@
+http://people.mozilla.com/~dwitte/ua.txt
+The following are some example User Agent strings for various versions of
+Firefox and other Gecko-based browsers. Many of these have been modified by
+extensions, external applications, distributions, and users. The version number
+for Firefox 5.0 (and the corresponding Gecko version) is tentative. See
+https://developer.mozilla.org/En/Gecko_User_Agent_String_Reference for more
+details. Credit to http://useragentstring.com/ for providing some of these
+strings.
+
+
+Firefox 4.0 (prerelease)
+
+ Mozilla/5.0 (Windows NT 6.0; rv:2.0b6pre) Gecko/20100907 Firefox/4.0b6pre
+ Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0b6pre) Gecko/20100903 Firefox/4.0b6pre
+ Mozilla/5.0 (Windows NT 6.1; rv:2.0b6pre) Gecko/20100903 Firefox/4.0b6pre Firefox/4.0b6pre
+ Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0b6pre) Gecko/20100907 Firefox/4.0b6pre
+ Mozilla/5.0 (X11; Linux i686; rv:2.0b6pre) Gecko/20100907 Firefox/4.0b6pre
+
+
+Firefox 4.0.1 (not yet released)
+
+ Mozilla/5.0 (Windows NT 5.2; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
+ Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
+ Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
+ Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
+ Mozilla/5.0 (WindowsCE 6.0; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
+ Mozilla/5.0 (Macintosh; Intel Mac OS X 10.5; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
+ Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
+ Mozilla/5.0 (X11; Linux i686; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
+ Mozilla/5.0 (X11; Linux x86_64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
+ Mozilla/5.0 (X11; Linux i686 on x86_64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
+ Mozilla/5.0 (X11; Linux armv7l; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
+
+
+Firefox 4.0 (prerelease)
+
+ Mozilla/5.0 (Windows NT 6.0; rv:2.0b6pre) Gecko/20100907 Firefox/4.0b6pre
+ Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0b6pre) Gecko/20100903 Firefox/4.0b6pre
+ Mozilla/5.0 (Windows NT 6.1; rv:2.0b6pre) Gecko/20100903 Firefox/4.0b6pre Firefox/4.0b6pre
+ Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0b6pre) Gecko/20100907 Firefox/4.0b6pre
+ Mozilla/5.0 (X11; Linux i686; rv:2.0b6pre) Gecko/20100907 Firefox/4.0b6pre
+
+
+Firefox 5.0 (version number tentative -- not yet released)
+
+ Mozilla/5.0 (Windows NT 5.2; rv:2.1.1) Gecko/ Firefox/5.0.1
+ Mozilla/5.0 (Windows NT 6.1; rv:2.1.1) Gecko/ Firefox/5.0.1
+ Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.1.1) Gecko/ Firefox/5.0.1
+ Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.1.1) Gecko/ Firefox/5.0.1
+ Mozilla/5.0 (WindowsCE 6.0; rv:2.1.1) Gecko/ Firefox/5.0.1
+ Mozilla/5.0 (Macintosh; Intel Mac OS X 10.5; rv:2.1.1) Gecko/ Firefox/5.0.1
+ Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.1.1) Gecko/ Firefox/5.0.1
+ Mozilla/5.0 (X11; Linux i686; rv:2.1.1) Gecko/ Firefox/5.0.1
+ Mozilla/5.0 (X11; Linux x86_64; rv:2.1.1) Gecko/ Firefox/5.0.1
+ Mozilla/5.0 (X11; Linux i686 on x86_64; rv:2.1.1) Gecko/ Firefox/5.0.1
+ Mozilla/5.0 (X11; Linux armv7l; rv:2.1.1) Gecko/ Firefox/5.0.1
+
+
+Firefox 3.6
+
+ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.8) Gecko/20100804 Gentoo Firefox/3.6.8
+ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.8) Gecko/20100723 SUSE/3.6.8-0.1.1 Firefox/3.6.8
+ Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.9.2.8) Gecko/20100722 Ubuntu/10.04 (lucid) Firefox/3.6.8
+ Mozilla/5.0 (X11; U; Linux i686; ru; rv:1.9.2.8) Gecko/20100723 Ubuntu/10.04 (lucid) Firefox/3.6.8
+ Mozilla/5.0 (X11; U; Linux i686; fi-FI; rv:1.9.2.8) Gecko/20100723 Ubuntu/10.04 (lucid) Firefox/3.6.8
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.8) Gecko/20100727 Firefox/3.6.8
+ Mozilla/5.0 (X11; U; Linux i686; de-DE; rv:1.9.2.8) Gecko/20100725 Gentoo Firefox/3.6.8
+ Mozilla/5.0 (X11; U; FreeBSD i386; de-CH; rv:1.9.2.8) Gecko/20100729 Firefox/3.6.8
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; pt-BR; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8 GTB7.1
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; he; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; fr; rv:1.9.2.8) Gecko/20100722 Firefox 3.6.8 GTB7.1
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8 ( .NET CLR 3.5.30729; .NET4.0C)
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.2.8) Gecko/20100722 Firefox 3.6.8
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.2.3) Gecko/20121221 Firefox/3.6.8
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2.8) Gecko/20100722 BTRS86393 Firefox/3.6.8 ( .NET CLR 3.5.30729; .NET4.0C)
+ Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-TW; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; tr; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8 ( .NET CLR 3.5.30729; .NET4.0E)
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; ro; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8
+ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en; rv:1.9.2.8) Gecko/20100805 Firefox/3.6.8
+ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.7) Gecko/20100723 Fedora/3.6.7-1.fc13 Firefox/3.6.7
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.7) Gecko/20100726 CentOS/3.6-3.el5.centos Firefox/3.6.7
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; hu; rv:1.9.2.7) Gecko/20100713 Firefox/3.6.7 GTB7.1
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; pt-PT; rv:1.9.2.7) Gecko/20100713 Firefox/3.6.7 (.NET CLR 3.5.30729)
+ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.6) Gecko/20100628 Ubuntu/10.04 (lucid) Firefox/3.6.6 GTB7.1
+ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.6) Gecko/20100628 Ubuntu/10.04 (lucid) Firefox/3.6.6 GTB7.0
+ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.6) Gecko/20100628 Ubuntu/10.04 (lucid) Firefox/3.6.6 (.NET CLR 3.5.30729)
+ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.6) Gecko/20100628 Ubuntu/10.04 (lucid) Firefox/3.6.6
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; pt-PT; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; it; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6 ( .NET CLR 3.5.30729)
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6 (.NET CLR 3.5.30729)
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; zh-CN; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6 GTB7.1
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; nl; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6 ( .NET CLR 3.5.30729; .NET4.0E)
+ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.4) Gecko/20100614 Ubuntu/10.04 (lucid) Firefox/3.6.4
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.4) Gecko/20100625 Gentoo Firefox/3.6.4
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.4) Gecko/20100513 Firefox/3.6.4
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; ja; rv:1.9.2.4) Gecko/20100611 Firefox/3.6.4 GTB7.1
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; cs; rv:1.9.2.4) Gecko/20100513 Firefox/3.6.4 (.NET CLR 3.5.30729)
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; zh-CN; rv:1.9.2.4) Gecko/20100513 Firefox/3.6.4
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; ja; rv:1.9.2.4) Gecko/20100513 Firefox/3.6.4 ( .NET CLR 3.5.30729)
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; fr; rv:1.9.2.4) Gecko/20100523 Firefox/3.6.4 ( .NET CLR 3.5.30729)
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2.4) Gecko/20100527 Firefox/3.6.4 (.NET CLR 3.5.30729)
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2.4) Gecko/20100527 Firefox/3.6.4
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2.4) Gecko/20100523 Firefox/3.6.4 ( .NET CLR 3.5.30729)
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2.4) Gecko/20100513 Firefox/3.6.4 (.NET CLR 3.5.30729)
+ Mozilla/5.0 (Windows; U; Windows NT 5.2; en-CA; rv:1.9.2.4) Gecko/20100523 Firefox/3.6.4
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW; rv:1.9.2.4) Gecko/20100611 Firefox/3.6.4 GTB7.0 ( .NET CLR 3.5.30729)
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.4) Gecko/20100513 Firefox/3.6.4 (.NET CLR 3.5.30729)
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.4) Gecko/20100503 Firefox/3.6.4 ( .NET CLR 3.5.30729)
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; nb-NO; rv:1.9.2.4) Gecko/20100611 Firefox/3.6.4 (.NET CLR 3.5.30729)
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; ko; rv:1.9.2.4) Gecko/20100523 Firefox/3.6.4
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; cs; rv:1.9.2.4) Gecko/20100611 Firefox/3.6.4
+ Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10.5; en-US; rv:1.9.2.4) Gecko/20100611 Firefox/3.6.4 GTB7.0
+ Mozilla/5.0 (X11; U; Linux x86_64; fr; rv:1.9.2.3) Gecko/20100403 Fedora/3.6.3-4.fc13 Firefox/3.6.3
+ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.3) Gecko/20100403 Firefox/3.6.3
+ Mozilla/5.0 (X11; U; Linux x86_64; de; rv:1.9.2.3) Gecko/20100401 SUSE/3.6.3-1.1 Firefox/3.6.3
+ Mozilla/5.0 (X11; U; Linux i686; ko-KR; rv:1.9.2.3) Gecko/20100423 Ubuntu/10.04 (lucid) Firefox/3.6.3
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.3) Gecko/20100404 Ubuntu/10.04 (lucid) Firefox/3.6.3
+ Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.2.3) Gecko/20100423 Ubuntu/10.04 (lucid) Firefox/3.6.3
+ Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10.5; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
+ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; es-ES; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
+ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 GTB7.0
+ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
+ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-GB; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
+ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; nl; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
+ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; fr; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729)
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; pl; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; it; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; hu; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 GTB7.1
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; es-ES; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 GTB7.1
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; es-ES; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 GTB7.0 ( .NET CLR 3.5.30729)
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; es-ES; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729)
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; cs; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 ( .NET CLR 3.5.30729)
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; ca; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729)
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; sv-SE; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729)
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; pl; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729)
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; nl; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729)
+ Mozilla/5.0 (X11; U; SunOS sun4u; en-US; rv:1.9.2.3) Gecko/20100403 Firefox/3.6.3
+ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.7; en-US; rv:1.9.2.2) Gecko/20100316 Firefox/3.6.2
+
+
+Firefox 3.5
+
+ Mozilla/5.0 (X11; U; Linux x86_64; it; rv:1.9.1.9) Gecko/20100402 Ubuntu/9.10 (karmic) Firefox/3.5.9 (.NET CLR 3.5.30729)
+ Mozilla/5.0 (X11; U; Linux x86_64; it; rv:1.9.1.9) Gecko/20100330 Fedora/3.5.9-2.fc12 Firefox/3.5.9
+ Mozilla/5.0 (X11; U; Linux x86_64; fr; rv:1.9.1.9) Gecko/20100317 SUSE/3.5.9-0.1.1 Firefox/3.5.9 GTB7.0
+ Mozilla/5.0 (X11; U; Linux x86_64; es-CL; rv:1.9.1.9) Gecko/20100402 Ubuntu/9.10 (karmic) Firefox/3.5.9
+ Mozilla/5.0 (X11; U; Linux x86_64; cs-CZ; rv:1.9.1.9) Gecko/20100317 SUSE/3.5.9-0.1.1 Firefox/3.5.9
+ Mozilla/5.0 (X11; U; Linux i686; nl; rv:1.9.1.9) Gecko/20100401 Ubuntu/9.10 (karmic) Firefox/3.5.9
+ Mozilla/5.0 (X11; U; Linux i686; hu-HU; rv:1.9.1.9) Gecko/20100330 Fedora/3.5.9-1.fc12 Firefox/3.5.9
+ Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.1.9) Gecko/20100317 SUSE/3.5.9-0.1 Firefox/3.5.9
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.9) Gecko/20100401 Ubuntu/9.10 (karmic) Firefox/3.5.9 GTB7.1
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.9) Gecko/20100315 Ubuntu/9.10 (karmic) Firefox/3.5.9
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.4) Gecko/20091028 Ubuntu/9.10 (karmic) Firefox/3.5.9
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; tr; rv:1.9.1.9) Gecko/20100315 Firefox/3.5.9 GTB7.1
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; hu; rv:1.9.1.9) Gecko/20100315 Firefox/3.5.9 (.NET CLR 3.5.30729)
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; fr; rv:1.9.1.9) Gecko/20100315 Firefox/3.5.9
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; et; rv:1.9.1.9) Gecko/20100315 Firefox/3.5.9
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.9) Gecko/20100315 Firefox/3.5.9
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; nl; rv:1.9.1.9) Gecko/20100315 Firefox/3.5.9 ( .NET CLR 3.5.30729)
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; es-ES; rv:1.9.1.9) Gecko/20100315 Firefox/3.5.9 GTB5 (.NET CLR 3.5.30729)
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.1.9) Gecko/20100315 Firefox/3.5.9 GTB7.0 (.NET CLR 3.0.30618)
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; ca; rv:1.9.1.9) Gecko/20100315 Firefox/3.5.9 GTB7.0 ( .NET CLR 3.5.30729)
+ Mozilla/5.0 (X11; U; Linux x86_64; ru; rv:1.9.1.8) Gecko/20100216 Fedora/3.5.8-1.fc12 Firefox/3.5.8
+ Mozilla/5.0 (X11; U; Linux x86_64; es-ES; rv:1.9.1.8) Gecko/20100216 Fedora/3.5.8-1.fc11 Firefox/3.5.8
+ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.8) Gecko/20100318 Gentoo Firefox/3.5.8
+ Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.9.1.8) Gecko/20100216 Fedora/3.5.8-1.fc12 Firefox/3.5.8
+ Mozilla/5.0 (X11; U; Linux i686; ja-JP; rv:1.9.1.8) Gecko/20100216 Fedora/3.5.8-1.fc12 Firefox/3.5.8
+ Mozilla/5.0 (X11; U; Linux i686; es-AR; rv:1.9.1.8) Gecko/20100214 Ubuntu/9.10 (karmic) Firefox/3.5.8
+ Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.1.8) Gecko/20100214 Ubuntu/9.10 (karmic) Firefox/3.5.8
+ Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8
+ Mozilla/5.0 (X11; U; FreeBSD i386; ja-JP; rv:1.9.1.8) Gecko/20100305 Firefox/3.5.8
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; sl; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8 (.NET CLR 3.5.30729) FirePHP/0.4
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8 GTB6
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.9.1.8) Gecko/20100202 Firefox/3.5.8 GTB7.0 (.NET CLR 3.5.30729)
+ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2) Gecko/20100305 Gentoo Firefox/3.5.7
+ Mozilla/5.0 (X11; U; Linux x86_64; cs-CZ; rv:1.9.1.7) Gecko/20100106 Ubuntu/9.10 (karmic) Firefox/3.5.7
+ Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.1.7) Gecko/20091222 SUSE/3.5.7-1.1.1 Firefox/3.5.7
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; ja; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 GTB6
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729)
+ Mozilla/5.0 (Windows; U; Windows NT 5.2; fr; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.0.04506.648)
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; fa; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20091221 MRA 5.5 (build 02842) Firefox/3.5.7 (.NET CLR 3.5.30729)
+ Mozilla/5.0 (X11; U; Linux x86_64; fr; rv:1.9.1.6) Gecko/20091215 Ubuntu/9.10 (karmic) Firefox/3.5.6
+ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.6) Gecko/20100117 Gentoo Firefox/3.5.6
+ Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.9.1.6) Gecko/20091216 Fedora/3.5.6-1.fc11 Firefox/3.5.6 GTB6
+ Mozilla/5.0 (X11; U; Linux i686; es-ES; rv:1.9.1.6) Gecko/20091201 SUSE/3.5.6-1.1.1 Firefox/3.5.6 GTB6
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.6) Gecko/20100118 Gentoo Firefox/3.5.6
+ Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:1.9.1.6) Gecko/20091215 Ubuntu/9.10 (karmic) Firefox/3.5.6 GTB6
+ Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.1.6) Gecko/20091215 Ubuntu/9.10 (karmic) Firefox/3.5.6 GTB7.0
+ Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.1.6) Gecko/20091215 Ubuntu/9.10 (karmic) Firefox/3.5.6
+ Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.1.6) Gecko/20091201 SUSE/3.5.6-1.1.1 Firefox/3.5.6
+ Mozilla/5.0 (X11; U; Linux i686; cs-CZ; rv:1.9.1.6) Gecko/20100107 Fedora/3.5.6-1.fc12 Firefox/3.5.6
+ Mozilla/5.0 (X11; U; Linux i686; ca; rv:1.9.1.6) Gecko/20091215 Ubuntu/9.10 (karmic) Firefox/3.5.6
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; it; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 ( .NET CLR 3.5.30729)
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; id; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 (.NET CLR 3.5.30729)
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.6) Gecko/20091201 MRA 5.4 (build 02647) Firefox/3.5.6 (.NET CLR 3.5.30729)
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; nl; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 (.NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.6) Gecko/20091201 MRA 5.5 (build 02842) Firefox/3.5.6 (.NET CLR 3.5.30729)
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.6) Gecko/20091201 MRA 5.5 (build 02842) Firefox/3.5.6
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 GTB6 (.NET CLR 3.5.30729) FBSMTWB
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 (.NET CLR 3.5.30729) FBSMTWB
+ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6 (.NET CLR 3.5.30729)
+ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; sv-SE; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3
+
+
+Firefox on the next Gecko major release (preliminary)
+
+ Mozilla/5.0 (Windows NT 5.2; rv:2.0.1) Gecko Firefox/5.0.1
+ Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko Firefox/5.0.1
+ Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0.1) Gecko Firefox/5.0.1
+ Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0.1) Gecko Firefox/5.0.1
+ Mozilla/5.0 (WindowsCE 6.0; rv:2.0.1) Gecko Firefox/5.0.1
+ Mozilla/5.0 (Macintosh; Intel Mac OS X 10.5; rv:2.0.1) Gecko Firefox/5.0.1
+ Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko Firefox/5.0.1
+ Mozilla/5.0 (X11; Linux i686; rv:2.0.1) Gecko Firefox/5.0.1
+ Mozilla/5.0 (X11; Linux x86_64; rv:2.0.1) Gecko Firefox/5.0.1
+ Mozilla/5.0 (X11; Linux i686 on x86_64; rv:2.0.1) Gecko Firefox/5.0.1
+ Mozilla/5.0 (X11; Linux armv7l; rv:2.0.1) Gecko Firefox/5.0.1
+
+
+Fennec 2.0.1 (not yet released)
+
+ Mozilla/5.0 (Android; Linux armv7l; rv:2.0.1) Gecko/20100101 Firefox/4.0.1 Fennec/2.0.1
+ Mozilla/5.0 (Maemo; Linux armv7l; rv:2.0.1) Gecko/20100101 Firefox/4.0.1 Fennec/2.0.1
+ Mozilla/5.0 (X11; Linux armv7l; rv:2.0.1) Gecko/20100101 Firefox/4.0.1 Fennec/2.0.1
+ Mozilla/5.0 (X11; Linux i686; rv:2.0.1) Gecko/20100101 Firefox/4.0.1 Fennec/2.0.1
+ Mozilla/5.0 (X11; Linux i686 on x86_64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1 Fennec/2.0.1
+
+
+Fennec 2.0 (prerelease)
+
+ Mozilla/5.0 (Android; Linux armv7l; rv:2.0b6pre) Gecko/20100907 Firefox/4.0b6pre Fennec/2.0b1pre
+ Mozilla/5.0 (X11; Linux i686; rv:2.0b6pre) Gecko/20100907 Firefox/4.0b6pre Fennec/2.0b1pre
+ Mozilla/5.0 (Windows NT 5.1; rv:2.0b6pre) Gecko/20100902 Firefox/4.0b6pre Fennec/2.0b1pre
+ Mozilla/5.0 (X11; Linux armv7l; rv:2.0b4pre) Gecko/20100818 Firefox/4.0b4pre Fennec/2.0a1pre
+ Mozilla/5.0 (X11; Linux armv7l; rv:2.0b4pre) Gecko/20100812 Firefox/4.0b4pre Fennec/2.0a1pre
+ Mozilla/5.0 (X11; Linux armv7l; rv:2.0b3pre) Gecko/20100730 Firefox/4.0b3pre Fennec/2.0a1pre
+
+
+Camino 2.2 (not yet released)
+
+ Mozilla/5.0 (Macintosh; Intel Mac OS X 10.4; rv:2.0.1) Gecko/20100101 Firefox/4.0.1 Camino/2.2.1
+ Mozilla/5.0 (Macintosh; Intel Mac OS X 10.5; rv:2.0.1) Gecko/20100101 Firefox/4.0.1 Camino/2.2.1
+ Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1 Camino/2.2.1
+ Mozilla/5.0 (Macintosh; PPC Mac OS X 10.4; rv:2.0.1) Gecko/20100101 Firefox/4.0.1 Camino/2.2.1
+ Mozilla/5.0 (Macintosh; PPC Mac OS X 10.5; rv:2.0.1) Gecko/20100101 Firefox/4.0.1 Camino/2.2.1
+
+
+Camino 2.0
+
+ Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10.4; en; rv:1.9.0.19) Gecko/2010051911 Camino/2.0.3 (like Firefox/3.0.19)
+ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; nl; rv:1.9.0.19) Gecko/2010051911 Camino/2.0.3 (MultiLang) (like Firefox/3.0.19)
+ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en; rv:1.9.0.18) Gecko/2010021619 Camino/2.0.2 (like Firefox/3.0.18)
+
+
+Camino 1.6
+
+ Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; it; rv:1.8.1.21) Gecko/20090327 Camino/1.6.7 (MultiLang) (like Firefox/2.0.0.21pre)
+ Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en; rv:1.8.1.21) Gecko/20090327 Camino/1.6.7 (like Firefox/2.0.0.21pre)
+
+
+Camino 1.5
+
+ Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en; rv:1.8.1.12) Gecko/20080206 Camino/1.5.5
+ Mozilla/5.0 (Macintosh; U; Intel Mac OS X Mach-O; en; rv:1.8.1.12) Gecko/20080206 Camino/1.5.5
+ Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en; rv:1.8.1.11) Gecko/20071128 Camino/1.5.4
+ Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en; rv:1.8.1.6) Gecko/20070809 Camino/1.5.1
+ Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en; rv:1.8.1.6) Gecko/20070809 Camino/1.5.1
+
+
+Thunderbird 3.1
+
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; sv-SE; rv:1.9.2.8) Gecko/20100802 Thunderbird/3.1.2 ThunderBrowse/3.3.2
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.2.8) Gecko/20100802 Thunderbird/3.1.2
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.7) Gecko/20100713 Lightning/1.0b2 Thunderbird/3.1.1 ThunderBrowse/3.3.1
+
+
+Thunderbird 3.0
+
+ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.10) Gecko/20100621 Fedora/3.0.5-1.fc13 Lightning/1.0b2pre Thunderbird/3.0.5
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.1.10) Gecko/20100512 Lightning/1.0b1 Thunderbird/3.0.5
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.9) Gecko/20100423 Thunderbird/3.0.4
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.1.9) Gecko/20100317 Lightning/1.0b1 Thunderbird/3.0.4
+ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.1.9) Gecko/20100317 Thunderbird/3.0.4
+ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; pl; rv:1.9.1.9) Gecko/20100317 Thunderbird/3.0.4
+ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1.9) Gecko/20100317 Thunderbird/3.0.4
+ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.8) Gecko/20100408 Thunderbird/3.0.3
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.9.1.7) Gecko/20100111 Thunderbird/3.0.1 ThunderBrowse/3.2.8.1
+ Mozilla/5.0 (Windows; U; Windows NT 5.0; fr-CA; rv:1.9.1.7) Gecko/20100111 Thunderbird/3.0.1 ThunderBrowse/3.2.8.1
+ Mozilla/5.0 (Windows; U; Windows NT 5.0; es-ES; rv:1.9.1.7) Gecko/20100111 Thunderbird/3.0.1 ThunderBrowse/3.2.8.1
+
+
+SeaMonkey 2.1.1 (not yet released)
+
+ Mozilla/5.0 (Windows NT 5.2; rv:2.0.1) Gecko/20100101 Firefox/4.0.1 SeaMonkey/2.1.1
+ Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1 SeaMonkey/2.1.1
+ Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1 SeaMonkey/2.1.1
+ Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1 SeaMonkey/2.1.1
+ Mozilla/5.0 (WindowsCE 6.0; rv:2.0.1) Gecko/20100101 Firefox/4.0.1 SeaMonkey/2.1.1
+ Mozilla/5.0 (Macintosh; Intel Mac OS X 10.5; rv:2.0.1) Gecko/20100101 Firefox/4.0.1 SeaMonkey/2.1.1
+ Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1 SeaMonkey/2.1.1
+ Mozilla/5.0 (X11; Linux i686; rv:2.0.1) Gecko/20100101 Firefox/4.0.1 SeaMonkey/2.1.1
+ Mozilla/5.0 (X11; Linux x86_64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1 SeaMonkey/2.1.1
+ Mozilla/5.0 (X11; Linux i686 on x86_64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1 SeaMonkey/2.1.1
+ Mozilla/5.0 (X11; Linux armv7l; rv:2.0.1) Gecko/20100101 Firefox/4.0.1 SeaMonkey/2.1.1
+
+
+SeaMonkey 2.1 (prerelease)
+
+ Mozilla/5.0 (Windows; Windows NT 5.2; rv:2.0b3pre) Gecko/20100803 SeaMonkey/2.1a3pre
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.3a4pre) Gecko/20100404 SeaMonkey/2.1a1pre
+ Mozilla/5.0 (Windows; U; Windows NT 5.2; en-CA; rv:1.9.3a3pre) Gecko/20100312 SeaMonkey/2.1a1pre
+
+
+SeaMonkey 2.0
+
+ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.11) Gecko/20100721 SeaMonkey/2.0.6
+ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.11) Gecko/20100714 SUSE/2.0.6-2.1 SeaMonkey/2.0.6
+ Mozilla/5.0 (X11; U; Linux ia64; de; rv:1.9.1.11) Gecko/20100820 Lightning/1.0b2pre SeaMonkey/2.0.6
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.11) Gecko/20100722 SeaMonkey/2.0.6
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.11) Gecko/20100701 SeaMonkey/2.0.6
+ Mozilla/5.0 (Windows; U; Windows NT 9.0; en-US; rv:1.9.1.11) Gecko/20100701 SeaMonkey/2.0.6
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.11) Gecko/20100701 SeaMonkey/2.0.6
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.11) Gecko/20100722 SeaMonkey/2.0.6
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.11) Gecko/20100701 SeaMonkey/2.0.6
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.1.11) Gecko/20100701 SeaMonkey/2.0.6
+ Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.9.1.11) Gecko/20100701 SeaMonkey/2.0.6
+ Mozilla/5.0 (Windows; U; Windows NT 5.2; en-CA; rv:1.9.1.11pre) Gecko/20100630 SeaMonkey/2.0.6pre
+ Mozilla/5.0 (Windows; U; Windows NT 5.2; en-CA; rv:1.9.1.11pre) Gecko/20100629 SeaMonkey/2.0.6pre
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.11pre) Gecko/20100515 SeaMonkey/2.0.6pre
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.11pre) Gecko/20100508 SeaMonkey/2.0.6pre
+ Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.1.10) Gecko/20100504 Lightning/1.0b1 Mnenhy/0.8.2 SeaMonkey/2.0.5
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.1.10) Gecko/20100504 Lightning/1.0b1 SeaMonkey/2.0.5
+ Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.9.1.10) Gecko/20100504 Lightning/1.0b1 SeaMonkey/2.0.5
+ Mozilla/5.0 (X11; U; Linux x86_64; fr; rv:1.9.1.9) Gecko/20100428 Lightning/1.0b1 SeaMonkey/2.0.4
+ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.9) Gecko/20100317 SUSE/2.0.4-3.2 Lightning/1.0b1 SeaMonkey/2.0.4
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.9) Gecko/20100317 Lightning/1.0b1 SeaMonkey/2.0.4
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.1.8) Gecko/20100205 SeaMonkey/2.0.3
+ Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.9.1.7) Gecko/20100104 SeaMonkey/2.0.2
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.1.7) Gecko/20100104 SeaMonkey/2.0.2
+
View
1,386 test_resources/firefox_user_agent_strings.yaml
@@ -0,0 +1,1386 @@
+# http://people.mozilla.com/~dwitte/ua.txt
+#
+# The following are some example User Agent strings for various versions of
+# Firefox and other Gecko-based browsers. Many of these have been modified by
+# extensions, external applications, distributions, and users. The version number
+# for Firefox 5.0 (and the corresponding Gecko version) is tentative. See
+# https://developer.mozilla.org/En/Gecko_User_Agent_String_Reference for more
+# details. Credit to http://useragentstring.com/ for providing some of these
+# strings.
+
+test_cases:
+ # Firefox 4.0 (prerelease)
+ - user_agent_string: Mozilla/5.0 (Windows NT 6.0; rv:2.0b6pre) Gecko/20100907 Firefox/4.0b6pre
+ family: 'Firefox Beta'
+ v1: '4'
+ v2: '0'
+ v3: b6pre
+ - user_agent_string: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0b6pre) Gecko/20100903 Firefox/4.0b6pre
+ family: 'Firefox Beta'
+ v1: '4'
+ v2: '0'
+ v3: b6pre
+ - user_agent_string: Mozilla/5.0 (Windows NT 6.1; rv:2.0b6pre) Gecko/20100903 Firefox/4.0b6pre Firefox/4.0b6pre
+ family: 'Firefox Beta'
+ v1: '4'
+ v2: '0'
+ v3: b6pre
+ - user_agent_string: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0b6pre) Gecko/20100907 Firefox/4.0b6pre
+ family: 'Firefox Beta'
+ v1: '4'
+ v2: '0'
+ v3: b6pre
+ - user_agent_string: Mozilla/5.0 (X11; Linux i686; rv:2.0b6pre) Gecko/20100907 Firefox/4.0b6pre
+ family: 'Firefox Beta'
+ v1: '4'
+ v2: '0'
+ v3: b6pre
+
+ # Firefox 4.0.1
+ - user_agent_string: Mozilla/5.0 (Windows NT 5.2; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
+ family: 'Firefox'
+ v1: '4'
+ v2: '0'
+ v3: '1'
+ - user_agent_string: Mozilla/5.0 (Windows NT 6.1; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
+ family: 'Firefox'
+ v1: '4'
+ v2: '0'
+ v3: '1'
+ - user_agent_string: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
+ family: 'Firefox'
+ v1: '4'
+ v2: '0'
+ v3: '1'
+ - user_agent_string: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
+ family: 'Firefox'
+ v1: '4'
+ v2: '0'
+ v3: '1'
+ - user_agent_string: Mozilla/5.0 (WindowsCE 6.0; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
+ family: 'Firefox'
+ v1: '4'
+ v2: '0'
+ v3: '1'
+ - user_agent_string: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.5; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
+ family: 'Firefox'
+ v1: '4'
+ v2: '0'
+ v3: '1'
+ - user_agent_string: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
+ family: 'Firefox'
+ v1: '4'
+ v2: '0'
+ v3: '1'
+ - user_agent_string: Mozilla/5.0 (X11; Linux i686; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
+ family: 'Firefox'
+ v1: '4'
+ v2: '0'
+ v3: '1'
+ - user_agent_string: Mozilla/5.0 (X11; Linux x86_64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
+ family: 'Firefox'
+ v1: '4'
+ v2: '0'
+ v3: '1'
+ - user_agent_string: Mozilla/5.0 (X11; Linux i686 on x86_64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
+ family: 'Firefox'
+ v1: '4'
+ v2: '0'
+ v3: '1'
+ - user_agent_string: Mozilla/5.0 (X11; Linux armv7l; rv:2.0.1) Gecko/20100101 Firefox/4.0.1
+ family: 'Firefox'
+ v1: '4'
+ v2: '0'
+ v3: '1'
+
+ # Firefox 4.0 (prerelease)
+ - user_agent_string: Mozilla/5.0 (Windows NT 6.0; rv:2.0b6pre) Gecko/20100907 Firefox/4.0b6pre
+ family: 'Firefox Beta'
+ v1: '4'
+ v2: '0'
+ v3: b6pre
+ - user_agent_string: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0b6pre) Gecko/20100903 Firefox/4.0b6pre
+ family: 'Firefox Beta'
+ v1: '4'
+ v2: '0'
+ v3: b6pre
+ - user_agent_string: Mozilla/5.0 (Windows NT 6.1; rv:2.0b6pre) Gecko/20100903 Firefox/4.0b6pre Firefox/4.0b6pre
+ family: 'Firefox Beta'
+ v1: '4'
+ v2: '0'
+ v3: b6pre
+ - user_agent_string: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0b6pre) Gecko/20100907 Firefox/4.0b6pre
+ family: 'Firefox Beta'
+ v1: '4'
+ v2: '0'
+ v3: b6pre
+ - user_agent_string: Mozilla/5.0 (X11; Linux i686; rv:2.0b6pre) Gecko/20100907 Firefox/4.0b6pre
+ family: 'Firefox Beta'
+ v1: '4'
+ v2: '0'
+ v3: b6pre
+
+ # Firefox 5.0 (version number tentative -- not yet released)
+ - user_agent_string: Mozilla/5.0 (Windows NT 5.2; rv:2.1.1) Gecko/ Firefox/5.0.1
+ family: 'Firefox'
+ v1: '5'
+ v2: '0'
+ v3: '1'
+ - user_agent_string: Mozilla/5.0 (Windows NT 6.1; rv:2.1.1) Gecko/ Firefox/5.0.1
+ family: 'Firefox'
+ v1: '5'
+ v2: '0'
+ v3: '1'
+ - user_agent_string: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:2.1.1) Gecko/ Firefox/5.0.1
+ family: 'Firefox'
+ v1: '5'
+ v2: '0'
+ v3: '1'
+ - user_agent_string: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.1.1) Gecko/ Firefox/5.0.1
+ family: 'Firefox'
+ v1: '5'
+ v2: '0'
+ v3: '1'
+ - user_agent_string: Mozilla/5.0 (WindowsCE 6.0; rv:2.1.1) Gecko/ Firefox/5.0.1
+ family: 'Firefox'
+ v1: '5'
+ v2: '0'
+ v3: '1'
+ - user_agent_string: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.5; rv:2.1.1) Gecko/ Firefox/5.0.1
+ family: 'Firefox'
+ v1: '5'
+ v2: '0'
+ v3: '1'
+ - user_agent_string: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.1.1) Gecko/ Firefox/5.0.1
+ family: 'Firefox'
+ v1: '5'
+ v2: '0'
+ v3: '1'
+ - user_agent_string: Mozilla/5.0 (X11; Linux i686; rv:2.1.1) Gecko/ Firefox/5.0.1
+ family: 'Firefox'
+ v1: '5'
+ v2: '0'
+ v3: '1'
+ - user_agent_string: Mozilla/5.0 (X11; Linux x86_64; rv:2.1.1) Gecko/ Firefox/5.0.1
+ family: 'Firefox'
+ v1: '5'
+ v2: '0'
+ v3: '1'
+ - user_agent_string: Mozilla/5.0 (X11; Linux i686 on x86_64; rv:2.1.1) Gecko/ Firefox/5.0.1
+ family: 'Firefox'
+ v1: '5'
+ v2: '0'
+ v3: '1'
+ - user_agent_string: Mozilla/5.0 (X11; Linux armv7l; rv:2.1.1) Gecko/ Firefox/5.0.1
+ family: 'Firefox'
+ v1: '5'
+ v2: '0'
+ v3: '1'
+
+ # Firefox 3.6
+ - user_agent_string: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.8) Gecko/20100804 Gentoo Firefox/3.6.8
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '8'
+ - user_agent_string: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.8) Gecko/20100723 SUSE/3.6.8-0.1.1 Firefox/3.6.8
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '8'
+ - user_agent_string: Mozilla/5.0 (X11; U; Linux i686; zh-CN; rv:1.9.2.8) Gecko/20100722 Ubuntu/10.04 (lucid) Firefox/3.6.8
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '8'
+ - user_agent_string: Mozilla/5.0 (X11; U; Linux i686; ru; rv:1.9.2.8) Gecko/20100723 Ubuntu/10.04 (lucid) Firefox/3.6.8
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '8'
+ - user_agent_string: Mozilla/5.0 (X11; U; Linux i686; fi-FI; rv:1.9.2.8) Gecko/20100723 Ubuntu/10.04 (lucid) Firefox/3.6.8
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '8'
+ - user_agent_string: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.8) Gecko/20100727 Firefox/3.6.8
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '8'
+ - user_agent_string: Mozilla/5.0 (X11; U; Linux i686; de-DE; rv:1.9.2.8) Gecko/20100725 Gentoo Firefox/3.6.8
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '8'
+ - user_agent_string: Mozilla/5.0 (X11; U; FreeBSD i386; de-CH; rv:1.9.2.8) Gecko/20100729 Firefox/3.6.8
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '8'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '8'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.1; pt-BR; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8 GTB7.1
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '8'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.1; he; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '8'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.1; fr; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8 GTB7.1
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '8'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8 ( .NET CLR 3.5.30729; .NET4.0C)
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '8'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '8'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.2.3) Gecko/20121221 Firefox/3.6.8
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '8'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2.8) Gecko/20100722 BTRS86393 Firefox/3.6.8 ( .NET CLR 3.5.30729; .NET4.0C)
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '8'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-TW; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '8'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '8'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 5.1; tr; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8 ( .NET CLR 3.5.30729; .NET4.0E)
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '8'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 5.1; ro; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '8'
+ - user_agent_string: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en; rv:1.9.2.8) Gecko/20100805 Firefox/3.6.8
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '8'
+ - user_agent_string: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.7) Gecko/20100723 Fedora/3.6.7-1.fc13 Firefox/3.6.7
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '7'
+ - user_agent_string: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.7) Gecko/20100726 CentOS/3.6-3.el5.centos Firefox/3.6.7
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '7'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.1; hu; rv:1.9.2.7) Gecko/20100713 Firefox/3.6.7 GTB7.1
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '7'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 5.1; pt-PT; rv:1.9.2.7) Gecko/20100713 Firefox/3.6.7 (.NET CLR 3.5.30729)
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '7'
+ - user_agent_string: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.6) Gecko/20100628 Ubuntu/10.04 (lucid) Firefox/3.6.6 GTB7.1
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '6'
+ - user_agent_string: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.6) Gecko/20100628 Ubuntu/10.04 (lucid) Firefox/3.6.6 GTB7.0
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '6'
+ - user_agent_string: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.6) Gecko/20100628 Ubuntu/10.04 (lucid) Firefox/3.6.6 (.NET CLR 3.5.30729)
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '6'
+ - user_agent_string: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.6) Gecko/20100628 Ubuntu/10.04 (lucid) Firefox/3.6.6
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '6'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.1; pt-PT; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '6'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.1; it; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6 ( .NET CLR 3.5.30729)
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '6'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6 (.NET CLR 3.5.30729)
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '6'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.0; zh-CN; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6 GTB7.1
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '6'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.0; nl; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '6'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6 ( .NET CLR 3.5.30729; .NET4.0E)
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '6'
+ - user_agent_string: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.4) Gecko/20100614 Ubuntu/10.04 (lucid) Firefox/3.6.4
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '4'
+ - user_agent_string: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.4) Gecko/20100625 Gentoo Firefox/3.6.4
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '4'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.4) Gecko/20100513 Firefox/3.6.4
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '4'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.1; ja; rv:1.9.2.4) Gecko/20100611 Firefox/3.6.4 GTB7.1
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '4'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.1; cs; rv:1.9.2.4) Gecko/20100513 Firefox/3.6.4 (.NET CLR 3.5.30729)
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '4'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.0; zh-CN; rv:1.9.2.4) Gecko/20100513 Firefox/3.6.4
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '4'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.0; ja; rv:1.9.2.4) Gecko/20100513 Firefox/3.6.4 ( .NET CLR 3.5.30729)
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '4'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.0; fr; rv:1.9.2.4) Gecko/20100523 Firefox/3.6.4 ( .NET CLR 3.5.30729)
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '4'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2.4) Gecko/20100527 Firefox/3.6.4 (.NET CLR 3.5.30729)
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '4'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2.4) Gecko/20100527 Firefox/3.6.4
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '4'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2.4) Gecko/20100523 Firefox/3.6.4 ( .NET CLR 3.5.30729)
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '4'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2.4) Gecko/20100513 Firefox/3.6.4 (.NET CLR 3.5.30729)
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '4'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 5.2; en-CA; rv:1.9.2.4) Gecko/20100523 Firefox/3.6.4
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '4'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW; rv:1.9.2.4) Gecko/20100611 Firefox/3.6.4 GTB7.0 ( .NET CLR 3.5.30729)
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '4'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.4) Gecko/20100513 Firefox/3.6.4 (.NET CLR 3.5.30729)
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '4'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.4) Gecko/20100503 Firefox/3.6.4 ( .NET CLR 3.5.30729)
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '4'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 5.1; nb-NO; rv:1.9.2.4) Gecko/20100611 Firefox/3.6.4 (.NET CLR 3.5.30729)
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '4'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 5.1; ko; rv:1.9.2.4) Gecko/20100523 Firefox/3.6.4
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '4'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 5.1; cs; rv:1.9.2.4) Gecko/20100611 Firefox/3.6.4
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '4'
+ - user_agent_string: Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10.5; en-US; rv:1.9.2.4) Gecko/20100611 Firefox/3.6.4 GTB7.0
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '4'
+ - user_agent_string: Mozilla/5.0 (X11; U; Linux x86_64; fr; rv:1.9.2.3) Gecko/20100403 Fedora/3.6.3-4.fc13 Firefox/3.6.3
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '3'
+ - user_agent_string: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.3) Gecko/20100403 Firefox/3.6.3
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '3'
+ - user_agent_string: Mozilla/5.0 (X11; U; Linux x86_64; de; rv:1.9.2.3) Gecko/20100401 SUSE/3.6.3-1.1 Firefox/3.6.3
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '3'
+ - user_agent_string: Mozilla/5.0 (X11; U; Linux i686; ko-KR; rv:1.9.2.3) Gecko/20100423 Ubuntu/10.04 (lucid) Firefox/3.6.3
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '3'
+ - user_agent_string: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.3) Gecko/20100404 Ubuntu/10.04 (lucid) Firefox/3.6.3
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '3'
+ - user_agent_string: Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.2.3) Gecko/20100423 Ubuntu/10.04 (lucid) Firefox/3.6.3
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '3'
+ - user_agent_string: Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10.5; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '3'
+ - user_agent_string: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; es-ES; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '3'
+ - user_agent_string: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 GTB7.0
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '3'
+ - user_agent_string: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '3'
+ - user_agent_string: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-GB; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '3'
+ - user_agent_string: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; nl; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '3'
+ - user_agent_string: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; fr; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '3'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729)
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '3'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '3'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.1; pl; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '3'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.1; it; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '3'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.1; hu; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 GTB7.1
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '3'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.1; es-ES; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 GTB7.1
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '3'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.1; es-ES; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 GTB7.0 ( .NET CLR 3.5.30729)
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '3'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.1; es-ES; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '3'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729)
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '3'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.1; cs; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 ( .NET CLR 3.5.30729)
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '3'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.1; ca; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729)
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '3'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.0; sv-SE; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729)
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '3'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.0; pl; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729)
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '3'
+ - user_agent_string: Mozilla/5.0 (Windows; U; Windows NT 6.0; nl; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729)
+ family: 'Firefox'
+ v1: '3'
+ v2: '6'
+ v3: '3'
+ -