'use strict'; // ⚠️ DO NOT MODIFY - SOURCE FILE: "../../python/mip.py" module.exports = new TextEncoder().encode("from uio import StringIO\nimport sys\n\nclass Response:\n def __init__(self, f):\n self.raw = f\n self.encoding = \"utf-8\"\n self._cached = None\n\n def close(self):\n if self.raw:\n self.raw.close()\n self.raw = None\n self._cached = None\n\n @property\n def content(self):\n if self._cached is None:\n try:\n self._cached = self.raw.read()\n finally:\n self.raw.close()\n self.raw = None\n return self._cached\n\n @property\n def text(self):\n return str(self.content, self.encoding)\n\n def json(self):\n import ujson\n\n return ujson.loads(self.content)\n\n\n# TODO try to support streaming xhr requests, a-la pyodide-http\nHEADERS_TO_IGNORE = (\"user-agent\",)\n\n\ntry:\n import js\nexcept Exception as err:\n raise OSError(\"This version of urequests can only be used in the browser\")\n\n# TODO try to support streaming xhr requests, a-la pyodide-http\n\nHEADERS_TO_IGNORE = (\"user-agent\",)\n\n\ndef request(\n method,\n url,\n data=None,\n json=None,\n headers={},\n stream=None,\n auth=None,\n timeout=None,\n parse_headers=True,\n):\n from js import XMLHttpRequest\n\n xhr = XMLHttpRequest.new()\n xhr.withCredentials = False\n\n if auth is not None:\n import ubinascii\n\n username, password = auth\n xhr.open(method, url, False, username, password)\n else:\n xhr.open(method, url, False)\n\n for name, value in headers.items():\n if name.lower() not in HEADERS_TO_IGNORE:\n xhr.setRequestHeader(name, value)\n\n if timeout:\n xhr.timeout = int(timeout * 1000)\n\n if json is not None:\n assert data is None\n import ujson\n\n data = ujson.dumps(json)\n # s.write(b\"Content-Type: application/json\\r\\n\")\n xhr.setRequestHeader(\"Content-Type\", \"application/json\")\n\n xhr.send(data)\n\n # Emulates the construction process in the original urequests\n resp = Response(StringIO(xhr.responseText))\n resp.status_code = xhr.status\n resp.reason = xhr.statusText\n resp.headers = xhr.getAllResponseHeaders()\n\n return resp\n\n\n# Other methods - head, post, put, patch, delete - are not used by\n# mip and therefore not included\n\n\ndef get(url, **kw):\n return request(\"GET\", url, **kw)\n\n\n# Content below this line is from the Micropython MIP package and is covered\n# by the applicable MIT license:\n# \n# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, \n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER \n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING \n# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER \n# DEALINGS IN THE SOFTWARE.\n\n# MicroPython package installer\n# MIT license; Copyright (c) 2022 Jim Mussared\n\n\n_PACKAGE_INDEX = const(\"https://micropython.org/pi/v2\")\n_CHUNK_SIZE = 128\n\n\n# This implements os.makedirs(os.dirname(path))\ndef _ensure_path_exists(path):\n import os\n\n split = path.split(\"/\")\n\n # Handle paths starting with \"/\".\n if not split[0]:\n split.pop(0)\n split[0] = \"/\" + split[0]\n\n prefix = \"\"\n for i in range(len(split) - 1):\n prefix += split[i]\n try:\n os.stat(prefix)\n except:\n os.mkdir(prefix)\n prefix += \"/\"\n\n\n# Copy from src (stream) to dest (function-taking-bytes)\ndef _chunk(src, dest):\n buf = memoryview(bytearray(_CHUNK_SIZE))\n while True:\n n = src.readinto(buf)\n if n == 0:\n break\n dest(buf if n == _CHUNK_SIZE else buf[:n])\n\n\n# Check if the specified path exists and matches the hash.\ndef _check_exists(path, short_hash):\n import os\n\n try:\n import binascii\n import hashlib\n\n with open(path, \"rb\") as f:\n hs256 = hashlib.sha256()\n _chunk(f, hs256.update)\n existing_hash = str(binascii.hexlify(hs256.digest())[: len(short_hash)], \"utf-8\")\n return existing_hash == short_hash\n except:\n return False\n\n\ndef _rewrite_url(url, branch=None):\n if not branch:\n branch = \"HEAD\"\n if url.startswith(\"github:\"):\n url = url[7:].split(\"/\")\n url = (\n \"https://raw.githubusercontent.com/\"\n + url[0]\n + \"/\"\n + url[1]\n + \"/\"\n + branch\n + \"/\"\n + \"/\".join(url[2:])\n )\n return url\n\n\ndef _download_file(url, dest):\n response = get(url)\n try:\n if response.status_code != 200:\n print(\"Error\", response.status_code, \"requesting\", url)\n return False\n\n print(\"Copying:\", dest)\n _ensure_path_exists(dest)\n with open(dest, \"wb\") as f:\n _chunk(response.raw, f.write)\n\n return True\n finally:\n response.close()\n\n\ndef _install_json(package_json_url, index, target, version, mpy):\n response = get(_rewrite_url(package_json_url, version))\n try:\n if response.status_code != 200:\n print(\"Package not found:\", package_json_url)\n return False\n\n package_json = response.json()\n finally:\n response.close()\n for target_path, short_hash in package_json.get(\"hashes\", ()):\n fs_target_path = target + \"/\" + target_path\n if _check_exists(fs_target_path, short_hash):\n print(\"Exists:\", fs_target_path)\n else:\n file_url = \"{}/file/{}/{}\".format(index, short_hash[:2], short_hash)\n if not _download_file(file_url, fs_target_path):\n print(\"File not found: {} {}\".format(target_path, short_hash))\n return False\n for target_path, url in package_json.get(\"urls\", ()):\n fs_target_path = target + \"/\" + target_path\n if not _download_file(_rewrite_url(url, version), fs_target_path):\n print(\"File not found: {} {}\".format(target_path, url))\n return False\n for dep, dep_version in package_json.get(\"deps\", ()):\n if not _install_package(dep, index, target, dep_version, mpy):\n return False\n return True\n\n\ndef _install_package(package, index, target, version, mpy):\n if (\n package.startswith(\"http://\")\n or package.startswith(\"https://\")\n or package.startswith(\"github:\")\n ):\n if package.endswith(\".py\") or package.endswith(\".mpy\"):\n print(\"Downloading {} to {}\".format(package, target))\n return _download_file(\n _rewrite_url(package, version), target + \"/\" + package.rsplit(\"/\")[-1]\n )\n else:\n if not package.endswith(\".json\"):\n if not package.endswith(\"/\"):\n package += \"/\"\n package += \"package.json\"\n print(\"Installing {} to {}\".format(package, target))\n else:\n if not version:\n version = \"latest\"\n print(\"Installing {} ({}) from {} to {}\".format(package, version, index, target))\n\n mpy_version = (\n sys.implementation._mpy & 0xFF if mpy and hasattr(sys.implementation, \"_mpy\") else \"py\"\n )\n\n package = \"{}/package/{}/{}/{}.json\".format(index, mpy_version, package, version)\n\n return _install_json(package, index, target, version, mpy)\n\n\ndef install(package, index=None, target=None, version=None, mpy=True):\n if not target:\n for p in sys.path:\n if p.endswith(\"/lib\"):\n target = p\n break\n else:\n print(\"Unable to find lib dir in sys.path\")\n return\n\n if not index:\n index = _PACKAGE_INDEX\n\n if _install_package(package, index.rstrip(\"/\"), target, version, mpy):\n print(\"Done\")\n else:\n print(\"Package may be partially installed\")\n");