We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Werkzeug useragent parsing is off for Motorola One Macro Android phone
I noticed this in a flask app but that uses werkzeug to parse useragent info and saw the same behavior in both the flask request object and standalone werkzeug useragent parser.

It looks like the presence of the substring "mac" in "macro" (the device model) is throwing it off. However, I feel like that should be overridden by the clear "Linux" and/or "Android 9".

```
>>> from werkzeug.useragents import UserAgent
>>> UserAgent("Mozilla/5.0 (Linux; Android 9; motorola one macro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.111 Mobile Safari/537.36").platform
'macos'
```

I would expect the `platform` for this useragent string to be "android".

Environment: Linux

- Python version: 3.7.3
- Werkzeug version: 1.01


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/werkzeug/useragents.py`
Content:
```
1 import re
2 import typing as t
3 
4 if t.TYPE_CHECKING:
5     from wsgiref.types import WSGIEnvironment
6 
7 
8 class UserAgentParser:
9     """A simple user agent parser.  Used by the `UserAgent`."""
10 
11     platform_rules: t.ClassVar[t.Iterable[t.Tuple[str, str]]] = (
12         (" cros ", "chromeos"),
13         ("iphone|ios", "iphone"),
14         ("ipad", "ipad"),
15         (r"darwin|mac|os\s*x", "macos"),
16         ("win", "windows"),
17         (r"android", "android"),
18         ("netbsd", "netbsd"),
19         ("openbsd", "openbsd"),
20         ("freebsd", "freebsd"),
21         ("dragonfly", "dragonflybsd"),
22         ("(sun|i86)os", "solaris"),
23         (r"x11|lin(\b|ux)?", "linux"),
24         (r"nintendo\s+wii", "wii"),
25         ("irix", "irix"),
26         ("hp-?ux", "hpux"),
27         ("aix", "aix"),
28         ("sco|unix_sv", "sco"),
29         ("bsd", "bsd"),
30         ("amiga", "amiga"),
31         ("blackberry|playbook", "blackberry"),
32         ("symbian", "symbian"),
33     )
34     browser_rules: t.ClassVar[t.Iterable[t.Tuple[str, str]]] = (
35         ("googlebot", "google"),
36         ("msnbot", "msn"),
37         ("yahoo", "yahoo"),
38         ("ask jeeves", "ask"),
39         (r"aol|america\s+online\s+browser", "aol"),
40         (r"opera|opr", "opera"),
41         ("edge|edg", "edge"),
42         ("chrome|crios", "chrome"),
43         ("seamonkey", "seamonkey"),
44         ("firefox|firebird|phoenix|iceweasel", "firefox"),
45         ("galeon", "galeon"),
46         ("safari|version", "safari"),
47         ("webkit", "webkit"),
48         ("camino", "camino"),
49         ("konqueror", "konqueror"),
50         ("k-meleon", "kmeleon"),
51         ("netscape", "netscape"),
52         (r"msie|microsoft\s+internet\s+explorer|trident/.+? rv:", "msie"),
53         ("lynx", "lynx"),
54         ("links", "links"),
55         ("Baiduspider", "baidu"),
56         ("bingbot", "bing"),
57         ("mozilla", "mozilla"),
58     )
59 
60     _browser_version_re = r"(?:{pattern})[/\sa-z(]*(\d+[.\da-z]+)?"
61     _language_re = re.compile(
62         r"(?:;\s*|\s+)(\b\w{2}\b(?:-\b\w{2}\b)?)\s*;|"
63         r"(?:\(|\[|;)\s*(\b\w{2}\b(?:-\b\w{2}\b)?)\s*(?:\]|\)|;)"
64     )
65 
66     def __init__(self) -> None:
67         self.platforms = [(b, re.compile(a, re.I)) for a, b in self.platform_rules]
68         self.browsers = [
69             (b, re.compile(self._browser_version_re.format(pattern=a), re.I))
70             for a, b in self.browser_rules
71         ]
72 
73     def __call__(
74         self, user_agent: str
75     ) -> t.Tuple[t.Optional[str], t.Optional[str], t.Optional[str], t.Optional[str]]:
76         platform: t.Optional[str]
77         browser: t.Optional[str]
78         version: t.Optional[str]
79         language: t.Optional[str]
80 
81         for platform, regex in self.platforms:  # noqa: B007
82             match = regex.search(user_agent)
83             if match is not None:
84                 break
85         else:
86             platform = None
87         for browser, regex in self.browsers:  # noqa: B007
88             match = regex.search(user_agent)
89             if match is not None:
90                 version = match.group(1)
91                 break
92         else:
93             browser = version = None
94         match = self._language_re.search(user_agent)
95         if match is not None:
96             language = match.group(1) or match.group(2)
97         else:
98             language = None
99         return platform, browser, version, language
100 
101 
102 class UserAgent:
103     """Represents a user agent.  Pass it a WSGI environment or a user agent
104     string and you can inspect some of the details from the user agent
105     string via the attributes.  The following attributes exist:
106 
107     .. attribute:: string
108 
109        the raw user agent string
110 
111     .. attribute:: platform
112 
113        the browser platform. ``None`` if not recognized.
114        The following platforms are currently recognized:
115 
116        -   `aix`
117        -   `amiga`
118        -   `android`
119        -   `blackberry`
120        -   `bsd`
121        -   `chromeos`
122        -   `dragonflybsd`
123        -   `freebsd`
124        -   `hpux`
125        -   `ipad`
126        -   `iphone`
127        -   `irix`
128        -   `linux`
129        -   `macos`
130        -   `netbsd`
131        -   `openbsd`
132        -   `sco`
133        -   `solaris`
134        -   `symbian`
135        -   `wii`
136        -   `windows`
137 
138     .. attribute:: browser
139 
140         the name of the browser. ``None`` if not recognized.
141         The following browsers are currently recognized:
142 
143         -   `aol` *
144         -   `ask` *
145         -   `baidu` *
146         -   `bing` *
147         -   `camino`
148         -   `chrome`
149         -   `edge`
150         -   `firefox`
151         -   `galeon`
152         -   `google` *
153         -   `kmeleon`
154         -   `konqueror`
155         -   `links`
156         -   `lynx`
157         -   `mozilla`
158         -   `msie`
159         -   `msn`
160         -   `netscape`
161         -   `opera`
162         -   `safari`
163         -   `seamonkey`
164         -   `webkit`
165         -   `yahoo` *
166 
167         (Browsers marked with a star (``*``) are crawlers.)
168 
169     .. attribute:: version
170 
171         the version of the browser. ``None`` if not recognized.
172 
173     .. attribute:: language
174 
175         the language of the browser. ``None`` if not recognized.
176     """
177 
178     _parser = UserAgentParser()
179 
180     def __init__(self, environ_or_string: t.Union["WSGIEnvironment", str]) -> None:
181         if isinstance(environ_or_string, dict):
182             self.string = environ_or_string.get("HTTP_USER_AGENT", "")
183         else:
184             self.string = environ_or_string
185 
186         self.platform, self.browser, self.version, self.language = self._parser(
187             self.string
188         )
189 
190     def to_header(self) -> str:
191         return self.string
192 
193     def __str__(self) -> str:
194         return self.string
195 
196     def __bool__(self) -> bool:
197         return bool(self.browser)
198 
199     def __repr__(self):
200         return f"<{type(self).__name__} {self.browser!r}/{self.version}>"
201
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/werkzeug/useragents.py b/src/werkzeug/useragents.py
--- a/src/werkzeug/useragents.py
+++ b/src/werkzeug/useragents.py
@@ -12,7 +12,7 @@
         (" cros ", "chromeos"),
         ("iphone|ios", "iphone"),
         ("ipad", "ipad"),
-        (r"darwin|mac|os\s*x", "macos"),
+        (r"darwin\b|mac\b|os\s*x", "macos"),
         ("win", "windows"),
         (r"android", "android"),
         ("netbsd", "netbsd"),
@@ -20,7 +20,7 @@
         ("freebsd", "freebsd"),
         ("dragonfly", "dragonflybsd"),
         ("(sun|i86)os", "solaris"),
-        (r"x11|lin(\b|ux)?", "linux"),
+        (r"x11\b|lin(\b|ux)?", "linux"),
         (r"nintendo\s+wii", "wii"),
         ("irix", "irix"),
         ("hp-?ux", "hpux"),

{"golden_diff": "diff --git a/src/werkzeug/useragents.py b/src/werkzeug/useragents.py\n--- a/src/werkzeug/useragents.py\n+++ b/src/werkzeug/useragents.py\n@@ -12,7 +12,7 @@\n         (\" cros \", \"chromeos\"),\n         (\"iphone|ios\", \"iphone\"),\n         (\"ipad\", \"ipad\"),\n-        (r\"darwin|mac|os\\s*x\", \"macos\"),\n+        (r\"darwin\\b|mac\\b|os\\s*x\", \"macos\"),\n         (\"win\", \"windows\"),\n         (r\"android\", \"android\"),\n         (\"netbsd\", \"netbsd\"),\n@@ -20,7 +20,7 @@\n         (\"freebsd\", \"freebsd\"),\n         (\"dragonfly\", \"dragonflybsd\"),\n         (\"(sun|i86)os\", \"solaris\"),\n-        (r\"x11|lin(\\b|ux)?\", \"linux\"),\n+        (r\"x11\\b|lin(\\b|ux)?\", \"linux\"),\n         (r\"nintendo\\s+wii\", \"wii\"),\n         (\"irix\", \"irix\"),\n         (\"hp-?ux\", \"hpux\"),\n", "issue": "Werkzeug useragent parsing is off for Motorola One Macro Android phone\nI noticed this in a flask app but that uses werkzeug to parse useragent info and saw the same behavior in both the flask request object and standalone werkzeug useragent parser.\r\n\r\nIt looks like the presence of the substring \"mac\" in \"macro\" (the device model) is throwing it off. However, I feel like that should be overridden by the clear \"Linux\" and/or \"Android 9\".\r\n\r\n```\r\n>>> from werkzeug.useragents import UserAgent\r\n>>> UserAgent(\"Mozilla/5.0 (Linux; Android 9; motorola one macro) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.111 Mobile Safari/537.36\").platform\r\n'macos'\r\n```\r\n\r\nI would expect the `platform` for this useragent string to be \"android\".\r\n\r\nEnvironment: Linux\r\n\r\n- Python version: 3.7.3\r\n- Werkzeug version: 1.01\r\n\n", "before_files": [{"content": "import re\nimport typing as t\n\nif t.TYPE_CHECKING:\n    from wsgiref.types import WSGIEnvironment\n\n\nclass UserAgentParser:\n    \"\"\"A simple user agent parser.  Used by the `UserAgent`.\"\"\"\n\n    platform_rules: t.ClassVar[t.Iterable[t.Tuple[str, str]]] = (\n        (\" cros \", \"chromeos\"),\n        (\"iphone|ios\", \"iphone\"),\n        (\"ipad\", \"ipad\"),\n        (r\"darwin|mac|os\\s*x\", \"macos\"),\n        (\"win\", \"windows\"),\n        (r\"android\", \"android\"),\n        (\"netbsd\", \"netbsd\"),\n        (\"openbsd\", \"openbsd\"),\n        (\"freebsd\", \"freebsd\"),\n        (\"dragonfly\", \"dragonflybsd\"),\n        (\"(sun|i86)os\", \"solaris\"),\n        (r\"x11|lin(\\b|ux)?\", \"linux\"),\n        (r\"nintendo\\s+wii\", \"wii\"),\n        (\"irix\", \"irix\"),\n        (\"hp-?ux\", \"hpux\"),\n        (\"aix\", \"aix\"),\n        (\"sco|unix_sv\", \"sco\"),\n        (\"bsd\", \"bsd\"),\n        (\"amiga\", \"amiga\"),\n        (\"blackberry|playbook\", \"blackberry\"),\n        (\"symbian\", \"symbian\"),\n    )\n    browser_rules: t.ClassVar[t.Iterable[t.Tuple[str, str]]] = (\n        (\"googlebot\", \"google\"),\n        (\"msnbot\", \"msn\"),\n        (\"yahoo\", \"yahoo\"),\n        (\"ask jeeves\", \"ask\"),\n        (r\"aol|america\\s+online\\s+browser\", \"aol\"),\n        (r\"opera|opr\", \"opera\"),\n        (\"edge|edg\", \"edge\"),\n        (\"chrome|crios\", \"chrome\"),\n        (\"seamonkey\", \"seamonkey\"),\n        (\"firefox|firebird|phoenix|iceweasel\", \"firefox\"),\n        (\"galeon\", \"galeon\"),\n        (\"safari|version\", \"safari\"),\n        (\"webkit\", \"webkit\"),\n        (\"camino\", \"camino\"),\n        (\"konqueror\", \"konqueror\"),\n        (\"k-meleon\", \"kmeleon\"),\n        (\"netscape\", \"netscape\"),\n        (r\"msie|microsoft\\s+internet\\s+explorer|trident/.+? rv:\", \"msie\"),\n        (\"lynx\", \"lynx\"),\n        (\"links\", \"links\"),\n        (\"Baiduspider\", \"baidu\"),\n        (\"bingbot\", \"bing\"),\n        (\"mozilla\", \"mozilla\"),\n    )\n\n    _browser_version_re = r\"(?:{pattern})[/\\sa-z(]*(\\d+[.\\da-z]+)?\"\n    _language_re = re.compile(\n        r\"(?:;\\s*|\\s+)(\\b\\w{2}\\b(?:-\\b\\w{2}\\b)?)\\s*;|\"\n        r\"(?:\\(|\\[|;)\\s*(\\b\\w{2}\\b(?:-\\b\\w{2}\\b)?)\\s*(?:\\]|\\)|;)\"\n    )\n\n    def __init__(self) -> None:\n        self.platforms = [(b, re.compile(a, re.I)) for a, b in self.platform_rules]\n        self.browsers = [\n            (b, re.compile(self._browser_version_re.format(pattern=a), re.I))\n            for a, b in self.browser_rules\n        ]\n\n    def __call__(\n        self, user_agent: str\n    ) -> t.Tuple[t.Optional[str], t.Optional[str], t.Optional[str], t.Optional[str]]:\n        platform: t.Optional[str]\n        browser: t.Optional[str]\n        version: t.Optional[str]\n        language: t.Optional[str]\n\n        for platform, regex in self.platforms:  # noqa: B007\n            match = regex.search(user_agent)\n            if match is not None:\n                break\n        else:\n            platform = None\n        for browser, regex in self.browsers:  # noqa: B007\n            match = regex.search(user_agent)\n            if match is not None:\n                version = match.group(1)\n                break\n        else:\n            browser = version = None\n        match = self._language_re.search(user_agent)\n        if match is not None:\n            language = match.group(1) or match.group(2)\n        else:\n            language = None\n        return platform, browser, version, language\n\n\nclass UserAgent:\n    \"\"\"Represents a user agent.  Pass it a WSGI environment or a user agent\n    string and you can inspect some of the details from the user agent\n    string via the attributes.  The following attributes exist:\n\n    .. attribute:: string\n\n       the raw user agent string\n\n    .. attribute:: platform\n\n       the browser platform. ``None`` if not recognized.\n       The following platforms are currently recognized:\n\n       -   `aix`\n       -   `amiga`\n       -   `android`\n       -   `blackberry`\n       -   `bsd`\n       -   `chromeos`\n       -   `dragonflybsd`\n       -   `freebsd`\n       -   `hpux`\n       -   `ipad`\n       -   `iphone`\n       -   `irix`\n       -   `linux`\n       -   `macos`\n       -   `netbsd`\n       -   `openbsd`\n       -   `sco`\n       -   `solaris`\n       -   `symbian`\n       -   `wii`\n       -   `windows`\n\n    .. attribute:: browser\n\n        the name of the browser. ``None`` if not recognized.\n        The following browsers are currently recognized:\n\n        -   `aol` *\n        -   `ask` *\n        -   `baidu` *\n        -   `bing` *\n        -   `camino`\n        -   `chrome`\n        -   `edge`\n        -   `firefox`\n        -   `galeon`\n        -   `google` *\n        -   `kmeleon`\n        -   `konqueror`\n        -   `links`\n        -   `lynx`\n        -   `mozilla`\n        -   `msie`\n        -   `msn`\n        -   `netscape`\n        -   `opera`\n        -   `safari`\n        -   `seamonkey`\n        -   `webkit`\n        -   `yahoo` *\n\n        (Browsers marked with a star (``*``) are crawlers.)\n\n    .. attribute:: version\n\n        the version of the browser. ``None`` if not recognized.\n\n    .. attribute:: language\n\n        the language of the browser. ``None`` if not recognized.\n    \"\"\"\n\n    _parser = UserAgentParser()\n\n    def __init__(self, environ_or_string: t.Union[\"WSGIEnvironment\", str]) -> None:\n        if isinstance(environ_or_string, dict):\n            self.string = environ_or_string.get(\"HTTP_USER_AGENT\", \"\")\n        else:\n            self.string = environ_or_string\n\n        self.platform, self.browser, self.version, self.language = self._parser(\n            self.string\n        )\n\n    def to_header(self) -> str:\n        return self.string\n\n    def __str__(self) -> str:\n        return self.string\n\n    def __bool__(self) -> bool:\n        return bool(self.browser)\n\n    def __repr__(self):\n        return f\"<{type(self).__name__} {self.browser!r}/{self.version}>\"\n", "path": "src/werkzeug/useragents.py"}], "after_files": [{"content": "import re\nimport typing as t\n\nif t.TYPE_CHECKING:\n    from wsgiref.types import WSGIEnvironment\n\n\nclass UserAgentParser:\n    \"\"\"A simple user agent parser.  Used by the `UserAgent`.\"\"\"\n\n    platform_rules: t.ClassVar[t.Iterable[t.Tuple[str, str]]] = (\n        (\" cros \", \"chromeos\"),\n        (\"iphone|ios\", \"iphone\"),\n        (\"ipad\", \"ipad\"),\n        (r\"darwin\\b|mac\\b|os\\s*x\", \"macos\"),\n        (\"win\", \"windows\"),\n        (r\"android\", \"android\"),\n        (\"netbsd\", \"netbsd\"),\n        (\"openbsd\", \"openbsd\"),\n        (\"freebsd\", \"freebsd\"),\n        (\"dragonfly\", \"dragonflybsd\"),\n        (\"(sun|i86)os\", \"solaris\"),\n        (r\"x11\\b|lin(\\b|ux)?\", \"linux\"),\n        (r\"nintendo\\s+wii\", \"wii\"),\n        (\"irix\", \"irix\"),\n        (\"hp-?ux\", \"hpux\"),\n        (\"aix\", \"aix\"),\n        (\"sco|unix_sv\", \"sco\"),\n        (\"bsd\", \"bsd\"),\n        (\"amiga\", \"amiga\"),\n        (\"blackberry|playbook\", \"blackberry\"),\n        (\"symbian\", \"symbian\"),\n    )\n    browser_rules: t.ClassVar[t.Iterable[t.Tuple[str, str]]] = (\n        (\"googlebot\", \"google\"),\n        (\"msnbot\", \"msn\"),\n        (\"yahoo\", \"yahoo\"),\n        (\"ask jeeves\", \"ask\"),\n        (r\"aol|america\\s+online\\s+browser\", \"aol\"),\n        (r\"opera|opr\", \"opera\"),\n        (\"edge|edg\", \"edge\"),\n        (\"chrome|crios\", \"chrome\"),\n        (\"seamonkey\", \"seamonkey\"),\n        (\"firefox|firebird|phoenix|iceweasel\", \"firefox\"),\n        (\"galeon\", \"galeon\"),\n        (\"safari|version\", \"safari\"),\n        (\"webkit\", \"webkit\"),\n        (\"camino\", \"camino\"),\n        (\"konqueror\", \"konqueror\"),\n        (\"k-meleon\", \"kmeleon\"),\n        (\"netscape\", \"netscape\"),\n        (r\"msie|microsoft\\s+internet\\s+explorer|trident/.+? rv:\", \"msie\"),\n        (\"lynx\", \"lynx\"),\n        (\"links\", \"links\"),\n        (\"Baiduspider\", \"baidu\"),\n        (\"bingbot\", \"bing\"),\n        (\"mozilla\", \"mozilla\"),\n    )\n\n    _browser_version_re = r\"(?:{pattern})[/\\sa-z(]*(\\d+[.\\da-z]+)?\"\n    _language_re = re.compile(\n        r\"(?:;\\s*|\\s+)(\\b\\w{2}\\b(?:-\\b\\w{2}\\b)?)\\s*;|\"\n        r\"(?:\\(|\\[|;)\\s*(\\b\\w{2}\\b(?:-\\b\\w{2}\\b)?)\\s*(?:\\]|\\)|;)\"\n    )\n\n    def __init__(self) -> None:\n        self.platforms = [(b, re.compile(a, re.I)) for a, b in self.platform_rules]\n        self.browsers = [\n            (b, re.compile(self._browser_version_re.format(pattern=a), re.I))\n            for a, b in self.browser_rules\n        ]\n\n    def __call__(\n        self, user_agent: str\n    ) -> t.Tuple[t.Optional[str], t.Optional[str], t.Optional[str], t.Optional[str]]:\n        platform: t.Optional[str]\n        browser: t.Optional[str]\n        version: t.Optional[str]\n        language: t.Optional[str]\n\n        for platform, regex in self.platforms:  # noqa: B007\n            match = regex.search(user_agent)\n            if match is not None:\n                break\n        else:\n            platform = None\n        for browser, regex in self.browsers:  # noqa: B007\n            match = regex.search(user_agent)\n            if match is not None:\n                version = match.group(1)\n                break\n        else:\n            browser = version = None\n        match = self._language_re.search(user_agent)\n        if match is not None:\n            language = match.group(1) or match.group(2)\n        else:\n            language = None\n        return platform, browser, version, language\n\n\nclass UserAgent:\n    \"\"\"Represents a user agent.  Pass it a WSGI environment or a user agent\n    string and you can inspect some of the details from the user agent\n    string via the attributes.  The following attributes exist:\n\n    .. attribute:: string\n\n       the raw user agent string\n\n    .. attribute:: platform\n\n       the browser platform. ``None`` if not recognized.\n       The following platforms are currently recognized:\n\n       -   `aix`\n       -   `amiga`\n       -   `android`\n       -   `blackberry`\n       -   `bsd`\n       -   `chromeos`\n       -   `dragonflybsd`\n       -   `freebsd`\n       -   `hpux`\n       -   `ipad`\n       -   `iphone`\n       -   `irix`\n       -   `linux`\n       -   `macos`\n       -   `netbsd`\n       -   `openbsd`\n       -   `sco`\n       -   `solaris`\n       -   `symbian`\n       -   `wii`\n       -   `windows`\n\n    .. attribute:: browser\n\n        the name of the browser. ``None`` if not recognized.\n        The following browsers are currently recognized:\n\n        -   `aol` *\n        -   `ask` *\n        -   `baidu` *\n        -   `bing` *\n        -   `camino`\n        -   `chrome`\n        -   `edge`\n        -   `firefox`\n        -   `galeon`\n        -   `google` *\n        -   `kmeleon`\n        -   `konqueror`\n        -   `links`\n        -   `lynx`\n        -   `mozilla`\n        -   `msie`\n        -   `msn`\n        -   `netscape`\n        -   `opera`\n        -   `safari`\n        -   `seamonkey`\n        -   `webkit`\n        -   `yahoo` *\n\n        (Browsers marked with a star (``*``) are crawlers.)\n\n    .. attribute:: version\n\n        the version of the browser. ``None`` if not recognized.\n\n    .. attribute:: language\n\n        the language of the browser. ``None`` if not recognized.\n    \"\"\"\n\n    _parser = UserAgentParser()\n\n    def __init__(self, environ_or_string: t.Union[\"WSGIEnvironment\", str]) -> None:\n        if isinstance(environ_or_string, dict):\n            self.string = environ_or_string.get(\"HTTP_USER_AGENT\", \"\")\n        else:\n            self.string = environ_or_string\n\n        self.platform, self.browser, self.version, self.language = self._parser(\n            self.string\n        )\n\n    def to_header(self) -> str:\n        return self.string\n\n    def __str__(self) -> str:\n        return self.string\n\n    def __bool__(self) -> bool:\n        return bool(self.browser)\n\n    def __repr__(self):\n        return f\"<{type(self).__name__} {self.browser!r}/{self.version}>\"\n", "path": "src/werkzeug/useragents.py"}]}