prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  plugins.wasd: service gone
  ### Checklist
  
  - [X] This is a [plugin issue](https://streamlink.github.io/plugins.html) and not [a different kind of issue](https://github.com/streamlink/streamlink/issues/new/choose)
  - [X] [I have read the contribution guidelines](https://github.com/streamlink/streamlink/blob/master/CONTRIBUTING.md#contributing-to-streamlink)
  - [X] [I have checked the list of open and recently closed plugin issues](https://github.com/streamlink/streamlink/issues?q=is%3Aissue+label%3A%22plugin+issue%22)
  - [X] [I have checked the commit log of the master branch](https://github.com/streamlink/streamlink/commits/master)
  
  ### Streamlink version
  
  6.4.2
  
  ### Description
  
  A few days ago, the service [gone](https://mts.ru/personal/novosti/2023-12-05/vstrechajte-polzovatelskuyu-videoplatformu-nuum). Now this [nuum.ru](https://nuum.ru).
  
  Though we could easily replace the plugin, but I'm not sure it's worth adding it to upstream, because it's a beta version.
  <details>
  
  ```diff
  diff --git a/src/streamlink/plugins/wasd.py b/src/streamlink/plugins/wasd.py
  index 7d61304e..656a16eb 100644
  --- a/src/streamlink/plugins/wasd.py
  +++ b/src/streamlink/plugins/wasd.py
  @@ -16,7 +16,7 @@ log = logging.getLogger(__name__)
   
   
   @pluginmatcher(re.compile(
  -    r"https?://(?:www\.)?wasd\.tv/(?P<nickname>[^/]+)/?$",
  +    r"https?://(?:www\.)?nuum\.ru/channel/(?P<nickname>[^/]+)/?$",
   ))
   class WASD(Plugin):
       _media_schema = validate.Schema({
  @@ -53,11 +53,11 @@ class WASD(Plugin):
   
       def _get_streams(self):
           nickname = self.match.group("nickname")
  -        res = self.session.http.get(f"https://wasd.tv/api/channels/nicknames/{nickname}")
  +        res = self.session.http.get(f"https://nuum.ru/api/channels/nicknames/{nickname}")
           channel_id = self.session.http.json(res, schema=self._api_nicknames_schema)
   
           res = self.session.http.get(
  -            "https://wasd.tv/api/v2/media-containers",
  +            "https://nuum.ru/api/v2/media-containers",
               params={
                   "media_container_status": "RUNNING",
                   "limit": "1",
  ```
  </details>
  
  ### Debug log
  
  
  
  </issue>
  <code>
  [start of src/streamlink/plugins/wasd.py]
  1 """
  2 $description Russian live-streaming social platform.
  3 $url wasd.tv
  4 $type live
  5 """
  6 
  7 import logging
  8 import re
  9 
  10 from streamlink.plugin import Plugin, PluginError, pluginmatcher
  11 from streamlink.plugin.api import validate
  12 from streamlink.stream.hls import HLSStream
  13 
  14 
  15 log = logging.getLogger(__name__)
  16 
  17 
  18 @pluginmatcher(re.compile(
  19     r"https?://(?:www\.)?wasd\.tv/(?P<nickname>[^/]+)/?$",
  20 ))
  21 class WASD(Plugin):
  22     _media_schema = validate.Schema({
  23         "user_id": int,
  24         "media_container_online_status": str,
  25         "media_container_status": str,
  26         "media_container_streams": [{
  27             "stream_media": [{
  28                 "media_id": int,
  29                 "media_meta": {
  30                     "media_url": validate.any(str, None),
  31                     "media_archive_url": validate.any(str, None),
  32                 },
  33                 "media_status": validate.any("STOPPED", "RUNNING"),
  34                 "media_type": "HLS",
  35             }],
  36         }],
  37     })
  38     _api_schema = validate.Schema({
  39         "result":
  40             validate.any(
  41                 _media_schema,
  42                 validate.all(list,
  43                              validate.get(0),
  44                              _media_schema),
  45                 [],
  46             ),
  47     }, validate.get("result"))
  48     _api_nicknames_schema = validate.Schema({
  49         "result": {
  50             "channel_id": int,
  51         },
  52     }, validate.get("result"), validate.get("channel_id"))
  53 
  54     def _get_streams(self):
  55         nickname = self.match.group("nickname")
  56         res = self.session.http.get(f"https://wasd.tv/api/channels/nicknames/{nickname}")
  57         channel_id = self.session.http.json(res, schema=self._api_nicknames_schema)
  58 
  59         res = self.session.http.get(
  60             "https://wasd.tv/api/v2/media-containers",
  61             params={
  62                 "media_container_status": "RUNNING",
  63                 "limit": "1",
  64                 "offset": "0",
  65                 "channel_id": channel_id,
  66                 "media_container_type": "SINGLE,COOP",
  67             },
  68         )
  69 
  70         json_res = self.session.http.json(res, schema=self._api_schema)
  71         log.trace("{0!r}".format(json_res))
  72         if not json_res:
  73             raise PluginError("No data returned from URL={0}".format(res.url))
  74 
  75         for stream in json_res["media_container_streams"]:
  76             log.debug("media_container_status: {0}, media_container_online_status: {1}".format(
  77                 json_res["media_container_status"], json_res["media_container_online_status"]))
  78             for stream_media in stream["stream_media"]:
  79                 if stream_media["media_status"] == "STOPPED":
  80                     hls_url = stream_media["media_meta"]["media_archive_url"]
  81                 else:
  82                     hls_url = stream_media["media_meta"]["media_url"]
  83 
  84                 yield from HLSStream.parse_variant_playlist(self.session, hls_url).items()
  85 
  86 
  87 __plugin__ = WASD
  88
  [end of src/streamlink/plugins/wasd.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/src/streamlink/plugins/wasd.py b/src/streamlink/plugins/wasd.py
  deleted file mode 100644
  --- a/src/streamlink/plugins/wasd.py
  +++ /dev/null
  @@ -1,87 +0,0 @@
  -"""
  -$description Russian live-streaming social platform.
  -$url wasd.tv
  -$type live
  -"""
  -
  -import logging
  -import re
  -
  -from streamlink.plugin import Plugin, PluginError, pluginmatcher
  -from streamlink.plugin.api import validate
  -from streamlink.stream.hls import HLSStream
  -
  -
  -log = logging.getLogger(__name__)
  -
  -
  -@pluginmatcher(re.compile(
  -    r"https?://(?:www\.)?wasd\.tv/(?P<nickname>[^/]+)/?$",
  -))
  -class WASD(Plugin):
  -    _media_schema = validate.Schema({
  -        "user_id": int,
  -        "media_container_online_status": str,
  -        "media_container_status": str,
  -        "media_container_streams": [{
  -            "stream_media": [{
  -                "media_id": int,
  -                "media_meta": {
  -                    "media_url": validate.any(str, None),
  -                    "media_archive_url": validate.any(str, None),
  -                },
  -                "media_status": validate.any("STOPPED", "RUNNING"),
  -                "media_type": "HLS",
  -            }],
  -        }],
  -    })
  -    _api_schema = validate.Schema({
  -        "result":
  -            validate.any(
  -                _media_schema,
  -                validate.all(list,
  -                             validate.get(0),
  -                             _media_schema),
  -                [],
  -            ),
  -    }, validate.get("result"))
  -    _api_nicknames_schema = validate.Schema({
  -        "result": {
  -            "channel_id": int,
  -        },
  -    }, validate.get("result"), validate.get("channel_id"))
  -
  -    def _get_streams(self):
  -        nickname = self.match.group("nickname")
  -        res = self.session.http.get(f"https://wasd.tv/api/channels/nicknames/{nickname}")
  -        channel_id = self.session.http.json(res, schema=self._api_nicknames_schema)
  -
  -        res = self.session.http.get(
  -            "https://wasd.tv/api/v2/media-containers",
  -            params={
  -                "media_container_status": "RUNNING",
  -                "limit": "1",
  -                "offset": "0",
  -                "channel_id": channel_id,
  -                "media_container_type": "SINGLE,COOP",
  -            },
  -        )
  -
  -        json_res = self.session.http.json(res, schema=self._api_schema)
  -        log.trace("{0!r}".format(json_res))
  -        if not json_res:
  -            raise PluginError("No data returned from URL={0}".format(res.url))
  -
  -        for stream in json_res["media_container_streams"]:
  -            log.debug("media_container_status: {0}, media_container_online_status: {1}".format(
  -                json_res["media_container_status"], json_res["media_container_online_status"]))
  -            for stream_media in stream["stream_media"]:
  -                if stream_media["media_status"] == "STOPPED":
  -                    hls_url = stream_media["media_meta"]["media_archive_url"]
  -                else:
  -                    hls_url = stream_media["media_meta"]["media_url"]
  -
  -                yield from HLSStream.parse_variant_playlist(self.session, hls_url).items()
  -
  -
  -__plugin__ = WASD
  
verification_info: {"golden_diff": "diff --git a/src/streamlink/plugins/wasd.py b/src/streamlink/plugins/wasd.py\ndeleted file mode 100644\n--- a/src/streamlink/plugins/wasd.py\n+++ /dev/null\n@@ -1,87 +0,0 @@\n-\"\"\"\n-$description Russian live-streaming social platform.\n-$url wasd.tv\n-$type live\n-\"\"\"\n-\n-import logging\n-import re\n-\n-from streamlink.plugin import Plugin, PluginError, pluginmatcher\n-from streamlink.plugin.api import validate\n-from streamlink.stream.hls import HLSStream\n-\n-\n-log = logging.getLogger(__name__)\n-\n-\n-@pluginmatcher(re.compile(\n-    r\"https?://(?:www\\.)?wasd\\.tv/(?P<nickname>[^/]+)/?$\",\n-))\n-class WASD(Plugin):\n-    _media_schema = validate.Schema({\n-        \"user_id\": int,\n-        \"media_container_online_status\": str,\n-        \"media_container_status\": str,\n-        \"media_container_streams\": [{\n-            \"stream_media\": [{\n-                \"media_id\": int,\n-                \"media_meta\": {\n-                    \"media_url\": validate.any(str, None),\n-                    \"media_archive_url\": validate.any(str, None),\n-                },\n-                \"media_status\": validate.any(\"STOPPED\", \"RUNNING\"),\n-                \"media_type\": \"HLS\",\n-            }],\n-        }],\n-    })\n-    _api_schema = validate.Schema({\n-        \"result\":\n-            validate.any(\n-                _media_schema,\n-                validate.all(list,\n-                             validate.get(0),\n-                             _media_schema),\n-                [],\n-            ),\n-    }, validate.get(\"result\"))\n-    _api_nicknames_schema = validate.Schema({\n-        \"result\": {\n-            \"channel_id\": int,\n-        },\n-    }, validate.get(\"result\"), validate.get(\"channel_id\"))\n-\n-    def _get_streams(self):\n-        nickname = self.match.group(\"nickname\")\n-        res = self.session.http.get(f\"https://wasd.tv/api/channels/nicknames/{nickname}\")\n-        channel_id = self.session.http.json(res, schema=self._api_nicknames_schema)\n-\n-        res = self.session.http.get(\n-            \"https://wasd.tv/api/v2/media-containers\",\n-            params={\n-                \"media_container_status\": \"RUNNING\",\n-                \"limit\": \"1\",\n-                \"offset\": \"0\",\n-                \"channel_id\": channel_id,\n-                \"media_container_type\": \"SINGLE,COOP\",\n-            },\n-        )\n-\n-        json_res = self.session.http.json(res, schema=self._api_schema)\n-        log.trace(\"{0!r}\".format(json_res))\n-        if not json_res:\n-            raise PluginError(\"No data returned from URL={0}\".format(res.url))\n-\n-        for stream in json_res[\"media_container_streams\"]:\n-            log.debug(\"media_container_status: {0}, media_container_online_status: {1}\".format(\n-                json_res[\"media_container_status\"], json_res[\"media_container_online_status\"]))\n-            for stream_media in stream[\"stream_media\"]:\n-                if stream_media[\"media_status\"] == \"STOPPED\":\n-                    hls_url = stream_media[\"media_meta\"][\"media_archive_url\"]\n-                else:\n-                    hls_url = stream_media[\"media_meta\"][\"media_url\"]\n-\n-                yield from HLSStream.parse_variant_playlist(self.session, hls_url).items()\n-\n-\n-__plugin__ = WASD\n", "issue": "plugins.wasd: service gone\n### Checklist\r\n\r\n- [X] This is a [plugin issue](https://streamlink.github.io/plugins.html) and not [a different kind of issue](https://github.com/streamlink/streamlink/issues/new/choose)\r\n- [X] [I have read the contribution guidelines](https://github.com/streamlink/streamlink/blob/master/CONTRIBUTING.md#contributing-to-streamlink)\r\n- [X] [I have checked the list of open and recently closed plugin issues](https://github.com/streamlink/streamlink/issues?q=is%3Aissue+label%3A%22plugin+issue%22)\r\n- [X] [I have checked the commit log of the master branch](https://github.com/streamlink/streamlink/commits/master)\r\n\r\n### Streamlink version\r\n\r\n6.4.2\r\n\r\n### Description\r\n\r\nA few days ago, the service [gone](https://mts.ru/personal/novosti/2023-12-05/vstrechajte-polzovatelskuyu-videoplatformu-nuum). Now this [nuum.ru](https://nuum.ru).\r\n\r\nThough we could easily replace the plugin, but I'm not sure it's worth adding it to upstream, because it's a beta version.\r\n<details>\r\n\r\n```diff\r\ndiff --git a/src/streamlink/plugins/wasd.py b/src/streamlink/plugins/wasd.py\r\nindex 7d61304e..656a16eb 100644\r\n--- a/src/streamlink/plugins/wasd.py\r\n+++ b/src/streamlink/plugins/wasd.py\r\n@@ -16,7 +16,7 @@ log = logging.getLogger(__name__)\r\n \r\n \r\n @pluginmatcher(re.compile(\r\n-    r\"https?://(?:www\\.)?wasd\\.tv/(?P<nickname>[^/]+)/?$\",\r\n+    r\"https?://(?:www\\.)?nuum\\.ru/channel/(?P<nickname>[^/]+)/?$\",\r\n ))\r\n class WASD(Plugin):\r\n     _media_schema = validate.Schema({\r\n@@ -53,11 +53,11 @@ class WASD(Plugin):\r\n \r\n     def _get_streams(self):\r\n         nickname = self.match.group(\"nickname\")\r\n-        res = self.session.http.get(f\"https://wasd.tv/api/channels/nicknames/{nickname}\")\r\n+        res = self.session.http.get(f\"https://nuum.ru/api/channels/nicknames/{nickname}\")\r\n         channel_id = self.session.http.json(res, schema=self._api_nicknames_schema)\r\n \r\n         res = self.session.http.get(\r\n-            \"https://wasd.tv/api/v2/media-containers\",\r\n+            \"https://nuum.ru/api/v2/media-containers\",\r\n             params={\r\n                 \"media_container_status\": \"RUNNING\",\r\n                 \"limit\": \"1\",\r\n```\r\n</details>\r\n\r\n### Debug log\r\n\r\n\n", "before_files": [{"content": "\"\"\"\n$description Russian live-streaming social platform.\n$url wasd.tv\n$type live\n\"\"\"\n\nimport logging\nimport re\n\nfrom streamlink.plugin import Plugin, PluginError, pluginmatcher\nfrom streamlink.plugin.api import validate\nfrom streamlink.stream.hls import HLSStream\n\n\nlog = logging.getLogger(__name__)\n\n\n@pluginmatcher(re.compile(\n    r\"https?://(?:www\\.)?wasd\\.tv/(?P<nickname>[^/]+)/?$\",\n))\nclass WASD(Plugin):\n    _media_schema = validate.Schema({\n        \"user_id\": int,\n        \"media_container_online_status\": str,\n        \"media_container_status\": str,\n        \"media_container_streams\": [{\n            \"stream_media\": [{\n                \"media_id\": int,\n                \"media_meta\": {\n                    \"media_url\": validate.any(str, None),\n                    \"media_archive_url\": validate.any(str, None),\n                },\n                \"media_status\": validate.any(\"STOPPED\", \"RUNNING\"),\n                \"media_type\": \"HLS\",\n            }],\n        }],\n    })\n    _api_schema = validate.Schema({\n        \"result\":\n            validate.any(\n                _media_schema,\n                validate.all(list,\n                             validate.get(0),\n                             _media_schema),\n                [],\n            ),\n    }, validate.get(\"result\"))\n    _api_nicknames_schema = validate.Schema({\n        \"result\": {\n            \"channel_id\": int,\n        },\n    }, validate.get(\"result\"), validate.get(\"channel_id\"))\n\n    def _get_streams(self):\n        nickname = self.match.group(\"nickname\")\n        res = self.session.http.get(f\"https://wasd.tv/api/channels/nicknames/{nickname}\")\n        channel_id = self.session.http.json(res, schema=self._api_nicknames_schema)\n\n        res = self.session.http.get(\n            \"https://wasd.tv/api/v2/media-containers\",\n            params={\n                \"media_container_status\": \"RUNNING\",\n                \"limit\": \"1\",\n                \"offset\": \"0\",\n                \"channel_id\": channel_id,\n                \"media_container_type\": \"SINGLE,COOP\",\n            },\n        )\n\n        json_res = self.session.http.json(res, schema=self._api_schema)\n        log.trace(\"{0!r}\".format(json_res))\n        if not json_res:\n            raise PluginError(\"No data returned from URL={0}\".format(res.url))\n\n        for stream in json_res[\"media_container_streams\"]:\n            log.debug(\"media_container_status: {0}, media_container_online_status: {1}\".format(\n                json_res[\"media_container_status\"], json_res[\"media_container_online_status\"]))\n            for stream_media in stream[\"stream_media\"]:\n                if stream_media[\"media_status\"] == \"STOPPED\":\n                    hls_url = stream_media[\"media_meta\"][\"media_archive_url\"]\n                else:\n                    hls_url = stream_media[\"media_meta\"][\"media_url\"]\n\n                yield from HLSStream.parse_variant_playlist(self.session, hls_url).items()\n\n\n__plugin__ = WASD\n", "path": "src/streamlink/plugins/wasd.py"}]}