diff --git a/.gitattributes b/.gitattributes index f95b6d6ae7c256bd69234e30c2ee9c6c78e6a268..be07e57677468ba250c32aca5f4c34a018889335 100644 --- a/.gitattributes +++ b/.gitattributes @@ -72,3 +72,26 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text .venv/Lib/site-packages/streamlit/static/static/media/SourceSansVF-Upright.ttf.BsWL4Kly.woff2 filter=lfs diff=lfs merge=lfs -text .venv/Lib/site-packages/streamlit/static/static/media/SourceSerifVariable-Italic.ttf.CVdzAtxO.woff2 filter=lfs diff=lfs merge=lfs -text .venv/Lib/site-packages/streamlit/static/static/media/SourceSerifVariable-Roman.ttf.mdpVL9bi.woff2 filter=lfs diff=lfs merge=lfs -text +.venv/Scripts/f2py.exe filter=lfs diff=lfs merge=lfs -text +.venv/Scripts/hf.exe filter=lfs diff=lfs merge=lfs -text +.venv/Scripts/httpx.exe filter=lfs diff=lfs merge=lfs -text +.venv/Scripts/huggingface-cli.exe filter=lfs diff=lfs merge=lfs -text +.venv/Scripts/idna.exe filter=lfs diff=lfs merge=lfs -text +.venv/Scripts/jsonschema.exe filter=lfs diff=lfs merge=lfs -text +.venv/Scripts/normalizer.exe filter=lfs diff=lfs merge=lfs -text +.venv/Scripts/numpy-config.exe filter=lfs diff=lfs merge=lfs -text +.venv/Scripts/pip.exe filter=lfs diff=lfs merge=lfs -text +.venv/Scripts/pip3.12.exe filter=lfs diff=lfs merge=lfs -text +.venv/Scripts/pip3.exe filter=lfs diff=lfs merge=lfs -text +.venv/Scripts/py.test.exe filter=lfs diff=lfs merge=lfs -text +.venv/Scripts/pygmentize.exe filter=lfs diff=lfs merge=lfs -text +.venv/Scripts/pytest.exe filter=lfs diff=lfs merge=lfs -text +.venv/Scripts/python.exe filter=lfs diff=lfs merge=lfs -text +.venv/Scripts/pythonw.exe filter=lfs diff=lfs merge=lfs -text +.venv/Scripts/streamlit.exe filter=lfs diff=lfs merge=lfs -text +.venv/Scripts/tiny-agents.exe filter=lfs diff=lfs merge=lfs -text +.venv/Scripts/tqdm.exe filter=lfs diff=lfs merge=lfs -text +.venv/Scripts/uvicorn.exe filter=lfs diff=lfs merge=lfs -text +.venv/Scripts/watchmedo.exe filter=lfs diff=lfs merge=lfs -text +.venv/Scripts/websockets.exe filter=lfs diff=lfs merge=lfs -text +.venv/share/jupyter/nbextensions/pydeck/index.js.map filter=lfs diff=lfs merge=lfs -text diff --git a/.venv/Lib/site-packages/urllib3-2.7.0.dist-info/INSTALLER b/.venv/Lib/site-packages/urllib3-2.7.0.dist-info/INSTALLER new file mode 100644 index 0000000000000000000000000000000000000000..a1b589e38a32041e49332e5e81c2d363dc418d68 --- /dev/null +++ b/.venv/Lib/site-packages/urllib3-2.7.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/Lib/site-packages/urllib3-2.7.0.dist-info/METADATA b/.venv/Lib/site-packages/urllib3-2.7.0.dist-info/METADATA new file mode 100644 index 0000000000000000000000000000000000000000..9c7a4703f89e94e7c3391dc4e71ed9d1931e8936 --- /dev/null +++ b/.venv/Lib/site-packages/urllib3-2.7.0.dist-info/METADATA @@ -0,0 +1,163 @@ +Metadata-Version: 2.4 +Name: urllib3 +Version: 2.7.0 +Summary: HTTP library with thread-safe connection pooling, file post, and more. +Project-URL: Changelog, https://github.com/urllib3/urllib3/blob/main/CHANGES.rst +Project-URL: Documentation, https://urllib3.readthedocs.io +Project-URL: Code, https://github.com/urllib3/urllib3 +Project-URL: Issue tracker, https://github.com/urllib3/urllib3/issues +Author-email: Andrey Petrov +Maintainer-email: Seth Michael Larson , Quentin Pradet , Illia Volochii +License-Expression: MIT +License-File: LICENSE.txt +Keywords: filepost,http,httplib,https,pooling,ssl,threadsafe,urllib +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Classifier: Programming Language :: Python :: Free Threading :: 2 - Beta +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Internet :: WWW/HTTP +Classifier: Topic :: Software Development :: Libraries +Requires-Python: >=3.10 +Provides-Extra: brotli +Requires-Dist: brotli>=1.2.0; (platform_python_implementation == 'CPython') and extra == 'brotli' +Requires-Dist: brotlicffi>=1.2.0.0; (platform_python_implementation != 'CPython') and extra == 'brotli' +Provides-Extra: h2 +Requires-Dist: h2<5,>=4; extra == 'h2' +Provides-Extra: socks +Requires-Dist: pysocks!=1.5.7,<2.0,>=1.5.6; extra == 'socks' +Provides-Extra: zstd +Requires-Dist: backports-zstd>=1.0.0; (python_version < '3.14') and extra == 'zstd' +Description-Content-Type: text/markdown + +

+ +![urllib3](https://github.com/urllib3/urllib3/raw/main/docs/_static/banner_github.svg) + +

+ +

+ PyPI Version + Python Versions + Join our Discord + Coverage Status + Build Status on GitHub + Documentation Status
+ OpenSSF Scorecard + SLSA 3 + CII Best Practices +

+ +urllib3 is a powerful, *user-friendly* HTTP client for Python. +urllib3 brings many critical features that are missing from the Python +standard libraries: + +- Thread safety. +- Connection pooling. +- Client-side SSL/TLS verification. +- File uploads with multipart encoding. +- Helpers for retrying requests and dealing with HTTP redirects. +- Support for gzip, deflate, brotli, and zstd encoding. +- Proxy support for HTTP and SOCKS. +- 100% test coverage. + +... and many more features, but most importantly: Our maintainers have a 15+ +year track record of maintaining urllib3 with the highest code standards and +attention to security and safety. + +[Much of the Python ecosystem already uses urllib3](https://urllib3.readthedocs.io/en/stable/#who-uses) +and you should too. + + +## Installing + +urllib3 can be installed with [pip](https://pip.pypa.io): + +```bash +$ python -m pip install urllib3 +``` + +Alternatively, you can grab the latest source code from [GitHub](https://github.com/urllib3/urllib3): + +```bash +$ git clone https://github.com/urllib3/urllib3.git +$ cd urllib3 +$ pip install . +``` + +## Getting Started + +urllib3 is easy to use: + +```python3 +>>> import urllib3 +>>> resp = urllib3.request("GET", "http://httpbin.org/robots.txt") +>>> resp.status +200 +>>> resp.data +b"User-agent: *\nDisallow: /deny\n" +``` + +urllib3 has usage and reference documentation at [urllib3.readthedocs.io](https://urllib3.readthedocs.io). + + +## Community + +urllib3 has a [community Discord channel](https://discord.gg/urllib3) for asking questions and +collaborating with other contributors. Drop by and say hello πŸ‘‹ + + +## Contributing + +urllib3 happily accepts contributions. Please see our +[contributing documentation](https://urllib3.readthedocs.io/en/latest/contributing.html) +for some tips on getting started. + + +## Security Disclosures + +To report a security vulnerability, please use the +[Tidelift security contact](https://tidelift.com/security). +Tidelift will coordinate the fix and disclosure with maintainers. + + +## Maintainers + +Meet our maintainers since 2008: + +- Current Lead: [@illia-v](https://github.com/illia-v) (Illia Volochii) +- [@sethmlarson](https://github.com/sethmlarson) (Seth M. Larson) +- [@pquentin](https://github.com/pquentin) (Quentin Pradet) +- [@theacodes](https://github.com/theacodes) (Thea Flowers) +- [@haikuginger](https://github.com/haikuginger) (Jess Shapiro) +- [@lukasa](https://github.com/lukasa) (Cory Benfield) +- [@sigmavirus24](https://github.com/sigmavirus24) (Ian Stapleton Cordasco) +- [@shazow](https://github.com/shazow) (Andrey Petrov) + +πŸ‘‹ + + +## Sponsorship + +If your company benefits from this library, please consider [sponsoring its +development](https://urllib3.readthedocs.io/en/latest/sponsors.html). + + +## For Enterprise + +Professional support for urllib3 is available as part of the [Tidelift +Subscription][1]. Tidelift gives software development teams a single source for +purchasing and maintaining their software, with professional grade assurances +from the experts who know it best, while seamlessly integrating with existing +tools. + +[1]: https://tidelift.com/subscription/pkg/pypi-urllib3?utm_source=pypi-urllib3&utm_medium=referral&utm_campaign=readme diff --git a/.venv/Lib/site-packages/urllib3-2.7.0.dist-info/RECORD b/.venv/Lib/site-packages/urllib3-2.7.0.dist-info/RECORD new file mode 100644 index 0000000000000000000000000000000000000000..e1961925f18c7231faf1f6a6c8cf856e7ab563eb --- /dev/null +++ b/.venv/Lib/site-packages/urllib3-2.7.0.dist-info/RECORD @@ -0,0 +1,79 @@ +urllib3-2.7.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +urllib3-2.7.0.dist-info/METADATA,sha256=ZhR4VtMLu2vtAcbOMybQ9I2E7V8oasF3YzoUhrgurOU,6852 +urllib3-2.7.0.dist-info/RECORD,, +urllib3-2.7.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87 +urllib3-2.7.0.dist-info/licenses/LICENSE.txt,sha256=Ew46ZNX91dCWp1JpRjSn2d8oRGnehuVzIQAmgEHj1oY,1093 +urllib3/__init__.py,sha256=JMo1tg1nIV1AeJ2vENC_Txfl0e5h6Gzl9DGVk1rWRbo,6979 +urllib3/__pycache__/__init__.cpython-312.pyc,, +urllib3/__pycache__/_base_connection.cpython-312.pyc,, +urllib3/__pycache__/_collections.cpython-312.pyc,, +urllib3/__pycache__/_request_methods.cpython-312.pyc,, +urllib3/__pycache__/_version.cpython-312.pyc,, +urllib3/__pycache__/connection.cpython-312.pyc,, +urllib3/__pycache__/connectionpool.cpython-312.pyc,, +urllib3/__pycache__/exceptions.cpython-312.pyc,, +urllib3/__pycache__/fields.cpython-312.pyc,, +urllib3/__pycache__/filepost.cpython-312.pyc,, +urllib3/__pycache__/poolmanager.cpython-312.pyc,, +urllib3/__pycache__/response.cpython-312.pyc,, +urllib3/_base_connection.py,sha256=HzcSEHexgDrRUr60jNniB2KQjdw97SedD5luRfHtCXg,5580 +urllib3/_collections.py,sha256=aOVm2mKilvuvT1efAGtkA7pi65C1NC3HJfpFxvYBS8A,17522 +urllib3/_request_methods.py,sha256=gCeF85SO_UU4WoPwYHIoz_tw-eM_EVOkLFp8OFsC7DA,9931 +urllib3/_version.py,sha256=-gMrKhsPiOj0XzUezVFa59d1S6QgQiKgQT5gGgyM8-w,520 +urllib3/connection.py,sha256=Zos3qxKDW9-GQ6aVqfBQVRM5soB0IjHxY_xXWpJaFTI,42786 +urllib3/connectionpool.py,sha256=sGFnddXYwlx7KC4JCP1gKvdNGLNK-YTCJDdGACGj3Y8,44164 +urllib3/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +urllib3/contrib/__pycache__/__init__.cpython-312.pyc,, +urllib3/contrib/__pycache__/pyopenssl.cpython-312.pyc,, +urllib3/contrib/__pycache__/socks.cpython-312.pyc,, +urllib3/contrib/emscripten/__init__.py,sha256=wyXve8rmqX7s2KqRQBxD5Wl48jzWPn5-1u_XoQBELVc,836 +urllib3/contrib/emscripten/__pycache__/__init__.cpython-312.pyc,, +urllib3/contrib/emscripten/__pycache__/connection.cpython-312.pyc,, +urllib3/contrib/emscripten/__pycache__/fetch.cpython-312.pyc,, +urllib3/contrib/emscripten/__pycache__/request.cpython-312.pyc,, +urllib3/contrib/emscripten/__pycache__/response.cpython-312.pyc,, +urllib3/contrib/emscripten/connection.py,sha256=giElsBoUsKVURbZzb8GCrJmqW23Xnvj2aNyQVF42slg,8960 +urllib3/contrib/emscripten/emscripten_fetch_worker.js,sha256=z1k3zZ4_hDKd3-tN7wzz8LHjHC2pxN_uu8B3k9D9A3c,3677 +urllib3/contrib/emscripten/fetch.py,sha256=5xcd--viFxZd2nBy0aK73dtJ9Tsh1yYZU_SUXwnwibk,23520 +urllib3/contrib/emscripten/request.py,sha256=mL28szy1KvE3NJhWor5jNmarp8gwplDU-7gwGZY5g0Q,566 +urllib3/contrib/emscripten/response.py,sha256=CDpY0GFoluR3IxECkM2gH5uDfYDM0EL1FWr7B76wtgM,9719 +urllib3/contrib/pyopenssl.py,sha256=XZY-QzyT7s8d43qisA4o-eSZYBeIkPyBMZhtj2kkLZs,19734 +urllib3/contrib/socks.py,sha256=rSuklfha4-vto-8qSLhSPmf5lmRPIYuqdAxKe9bg2RA,7639 +urllib3/exceptions.py,sha256=hQPHoqo4yw46esNSVkciVQXVUgAxWAglsh6MbyQta-Q,9945 +urllib3/fields.py,sha256=aGLFAVZpVU-FbJlllve4Ahg0-pH9ZZBQ2Iz7lfpkjkM,10801 +urllib3/filepost.py,sha256=U8eNZ-mpKKHhrlbHEEiTxxgK16IejhEa7uz42yqA_dI,2388 +urllib3/http2/__init__.py,sha256=xzrASH7R5ANRkPJOot5lGnATOq3KKuyXzI42rcnwmqs,1741 +urllib3/http2/__pycache__/__init__.cpython-312.pyc,, +urllib3/http2/__pycache__/connection.cpython-312.pyc,, +urllib3/http2/__pycache__/probe.cpython-312.pyc,, +urllib3/http2/connection.py,sha256=bHMH6fNvatwXPrKqrcn74yA3pUWcqPDppnK1LcKCbP8,12578 +urllib3/http2/probe.py,sha256=nnAkqbhAakOiF75rz7W0udZ38Eeh_uD8fjV74N73FEI,3014 +urllib3/poolmanager.py,sha256=c0rh0rcUC1t5tDGuUeGIgAzlErasPOwWwLiB67lX8pM,23895 +urllib3/py.typed,sha256=UaCuPFa3H8UAakbt-5G8SPacldTOGvJv18pPjUJ5gDY,93 +urllib3/response.py,sha256=9SX4BkkdoLgsx1ne6hpt-5PncrnDzPzeqC1DaShSc-M,53219 +urllib3/util/__init__.py,sha256=-qeS0QceivazvBEKDNFCAI-6ACcdDOE4TMvo7SLNlAQ,1001 +urllib3/util/__pycache__/__init__.cpython-312.pyc,, +urllib3/util/__pycache__/connection.cpython-312.pyc,, +urllib3/util/__pycache__/proxy.cpython-312.pyc,, +urllib3/util/__pycache__/request.cpython-312.pyc,, +urllib3/util/__pycache__/response.cpython-312.pyc,, +urllib3/util/__pycache__/retry.cpython-312.pyc,, +urllib3/util/__pycache__/ssl_.cpython-312.pyc,, +urllib3/util/__pycache__/ssl_match_hostname.cpython-312.pyc,, +urllib3/util/__pycache__/ssltransport.cpython-312.pyc,, +urllib3/util/__pycache__/timeout.cpython-312.pyc,, +urllib3/util/__pycache__/url.cpython-312.pyc,, +urllib3/util/__pycache__/util.cpython-312.pyc,, +urllib3/util/__pycache__/wait.cpython-312.pyc,, +urllib3/util/connection.py,sha256=JjO722lzHlzLXPTkr9ZWBdhseXnMVjMSb1DJLVrXSnQ,4444 +urllib3/util/proxy.py,sha256=seP8-Q5B6bB0dMtwPj-YcZZQ30vHuLqRu-tI0JZ2fzs,1148 +urllib3/util/request.py,sha256=itpnC8ug7D4nVfDmGUCRMlgkARUQ13r_XMxSnzTwmpE,8363 +urllib3/util/response.py,sha256=vQE639uoEhj1vpjEdxu5lNIhJCSUZkd7pqllUI0BZOA,3374 +urllib3/util/retry.py,sha256=2YnSX-_FecMShD61Mx5s68J0_btUHZrrc_BkFVRS1P4,19577 +urllib3/util/ssl_.py,sha256=Oqe3rIhUU3e3GVgZob2hxmR8Q0ZDhrhESPlPP_GLaVQ,17742 +urllib3/util/ssl_match_hostname.py,sha256=Ft44KJzTzGMmKff_ZXP91li2V4WhmvEy16PKBcv4vZk,5479 +urllib3/util/ssltransport.py,sha256=Ez4O8pR_vT8dan_FvqBYS6dgDfBXEMfVfrzcdUoWfi4,8847 +urllib3/util/timeout.py,sha256=4eT1FVeZZU7h7mYD1Jq2OXNe4fxekdNvhoWUkZusRpA,10346 +urllib3/util/url.py,sha256=WRh-TMYXosmgp8m8lT4H5spoHw5yUjlcMCfU53AkoAs,15205 +urllib3/util/util.py,sha256=j3lbZK1jPyiwD34T8IgJzdWEZVT-4E-0vYIJi9UjeNA,1146 +urllib3/util/wait.py,sha256=_ph8IrUR3sqPqi0OopQgJUlH4wzkGeM5CiyA7XGGtmI,4423 diff --git a/.venv/Lib/site-packages/urllib3-2.7.0.dist-info/WHEEL b/.venv/Lib/site-packages/urllib3-2.7.0.dist-info/WHEEL new file mode 100644 index 0000000000000000000000000000000000000000..b1b94fd58e7e9ed0ef3449473bc48de68afcc3fe --- /dev/null +++ b/.venv/Lib/site-packages/urllib3-2.7.0.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: hatchling 1.29.0 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/.venv/Lib/site-packages/urllib3-2.7.0.dist-info/licenses/LICENSE.txt b/.venv/Lib/site-packages/urllib3-2.7.0.dist-info/licenses/LICENSE.txt new file mode 100644 index 0000000000000000000000000000000000000000..e6183d0276b26c5b87aecccf8d0d5bcd7b1148d4 --- /dev/null +++ b/.venv/Lib/site-packages/urllib3-2.7.0.dist-info/licenses/LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2008-2020 Andrey Petrov and contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/.venv/Lib/site-packages/urllib3/util/wait.py b/.venv/Lib/site-packages/urllib3/util/wait.py new file mode 100644 index 0000000000000000000000000000000000000000..aeca0c7ad5b232eeb1ad9c43d315bd1d74eaed9a --- /dev/null +++ b/.venv/Lib/site-packages/urllib3/util/wait.py @@ -0,0 +1,124 @@ +from __future__ import annotations + +import select +import socket +from functools import partial + +__all__ = ["wait_for_read", "wait_for_write"] + + +# How should we wait on sockets? +# +# There are two types of APIs you can use for waiting on sockets: the fancy +# modern stateful APIs like epoll/kqueue, and the older stateless APIs like +# select/poll. The stateful APIs are more efficient when you have a lots of +# sockets to keep track of, because you can set them up once and then use them +# lots of times. But we only ever want to wait on a single socket at a time +# and don't want to keep track of state, so the stateless APIs are actually +# more efficient. So we want to use select() or poll(). +# +# Now, how do we choose between select() and poll()? On traditional Unixes, +# select() has a strange calling convention that makes it slow, or fail +# altogether, for high-numbered file descriptors. The point of poll() is to fix +# that, so on Unixes, we prefer poll(). +# +# On Windows, there is no poll() (or at least Python doesn't provide a wrapper +# for it), but that's OK, because on Windows, select() doesn't have this +# strange calling convention; plain select() works fine. +# +# So: on Windows we use select(), and everywhere else we use poll(). We also +# fall back to select() in case poll() is somehow broken or missing. + + +def select_wait_for_socket( + sock: socket.socket, + read: bool = False, + write: bool = False, + timeout: float | None = None, +) -> bool: + if not read and not write: + raise RuntimeError("must specify at least one of read=True, write=True") + rcheck = [] + wcheck = [] + if read: + rcheck.append(sock) + if write: + wcheck.append(sock) + # When doing a non-blocking connect, most systems signal success by + # marking the socket writable. Windows, though, signals success by marked + # it as "exceptional". We paper over the difference by checking the write + # sockets for both conditions. (The stdlib selectors module does the same + # thing.) + fn = partial(select.select, rcheck, wcheck, wcheck) + rready, wready, xready = fn(timeout) + return bool(rready or wready or xready) + + +def poll_wait_for_socket( + sock: socket.socket, + read: bool = False, + write: bool = False, + timeout: float | None = None, +) -> bool: + if not read and not write: + raise RuntimeError("must specify at least one of read=True, write=True") + mask = 0 + if read: + mask |= select.POLLIN + if write: + mask |= select.POLLOUT + poll_obj = select.poll() + poll_obj.register(sock, mask) + + # For some reason, poll() takes timeout in milliseconds + def do_poll(t: float | None) -> list[tuple[int, int]]: + if t is not None: + t *= 1000 + return poll_obj.poll(t) + + return bool(do_poll(timeout)) + + +def _have_working_poll() -> bool: + # Apparently some systems have a select.poll that fails as soon as you try + # to use it, either due to strange configuration or broken monkeypatching + # from libraries like eventlet/greenlet. + try: + poll_obj = select.poll() + poll_obj.poll(0) + except (AttributeError, OSError): + return False + else: + return True + + +def wait_for_socket( + sock: socket.socket, + read: bool = False, + write: bool = False, + timeout: float | None = None, +) -> bool: + # We delay choosing which implementation to use until the first time we're + # called. We could do it at import time, but then we might make the wrong + # decision if someone goes wild with monkeypatching select.poll after + # we're imported. + global wait_for_socket + if _have_working_poll(): + wait_for_socket = poll_wait_for_socket + elif hasattr(select, "select"): + wait_for_socket = select_wait_for_socket + return wait_for_socket(sock, read, write, timeout) + + +def wait_for_read(sock: socket.socket, timeout: float | None = None) -> bool: + """Waits for reading to be available on a given socket. + Returns True if the socket is readable, or False if the timeout expired. + """ + return wait_for_socket(sock, read=True, timeout=timeout) + + +def wait_for_write(sock: socket.socket, timeout: float | None = None) -> bool: + """Waits for writing to be available on a given socket. + Returns True if the socket is readable, or False if the timeout expired. + """ + return wait_for_socket(sock, write=True, timeout=timeout) diff --git a/.venv/Lib/site-packages/uvicorn-0.51.0.dist-info/INSTALLER b/.venv/Lib/site-packages/uvicorn-0.51.0.dist-info/INSTALLER new file mode 100644 index 0000000000000000000000000000000000000000..a1b589e38a32041e49332e5e81c2d363dc418d68 --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn-0.51.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/Lib/site-packages/uvicorn-0.51.0.dist-info/METADATA b/.venv/Lib/site-packages/uvicorn-0.51.0.dist-info/METADATA new file mode 100644 index 0000000000000000000000000000000000000000..00101f1dea8c3920d13829f47d6d95a144b0a40c --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn-0.51.0.dist-info/METADATA @@ -0,0 +1,189 @@ +Metadata-Version: 2.4 +Name: uvicorn +Version: 0.51.0 +Summary: The lightning-fast ASGI server. +Project-URL: Changelog, https://uvicorn.dev/release-notes +Project-URL: Funding, https://github.com/sponsors/encode +Project-URL: Homepage, https://uvicorn.dev/ +Project-URL: Source, https://github.com/Kludex/uvicorn +Author-email: Tom Christie +Maintainer-email: Marcelo Trylesinski +License-Expression: BSD-3-Clause +License-File: LICENSE.md +Classifier: Development Status :: 4 - Beta +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Topic :: Internet :: WWW/HTTP +Requires-Python: >=3.10 +Requires-Dist: click>=7.0 +Requires-Dist: h11>=0.8 +Requires-Dist: typing-extensions>=4.0; python_version < '3.11' +Provides-Extra: standard +Requires-Dist: httptools>=0.8.0; extra == 'standard' +Requires-Dist: python-dotenv>=0.13; extra == 'standard' +Requires-Dist: pyyaml>=5.1; extra == 'standard' +Requires-Dist: uvloop>=0.15.1; (sys_platform != 'win32' and (sys_platform != 'cygwin' and platform_python_implementation != 'PyPy')) and extra == 'standard' +Requires-Dist: watchfiles>=0.20; extra == 'standard' +Requires-Dist: websockets>=13.0; extra == 'standard' +Description-Content-Type: text/markdown + +

+ uvicorn +

+ +

+An ASGI web server, for Python. +

+ +--- + +[![Build Status](https://github.com/Kludex/uvicorn/workflows/Test%20Suite/badge.svg)](https://github.com/Kludex/uvicorn/actions) +[![Package version](https://badge.fury.io/py/uvicorn.svg)](https://pypi.python.org/pypi/uvicorn) +[![Supported Python Version](https://img.shields.io/pypi/pyversions/uvicorn.svg?color=%2334D058)](https://pypi.org/project/uvicorn) +[![Discord](https://img.shields.io/discord/1051468649518616576?logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2)](https://discord.gg/RxKUF5JuHs) + +--- + +**Documentation**: [https://uvicorn.dev](https://uvicorn.dev) + +**Source Code**: [https://www.github.com/Kludex/uvicorn](https://www.github.com/Kludex/uvicorn) + +--- + +Uvicorn is an ASGI web server implementation for Python. + +Until recently Python has lacked a minimal low-level server/application interface for +async frameworks. The [ASGI specification][asgi] fills this gap, and means we're now able to +start building a common set of tooling usable across all async frameworks. + +Uvicorn supports HTTP/1.1 and WebSockets. + +## Quickstart + +Install using `pip`: + +```shell +$ pip install uvicorn +``` + +This will install uvicorn with minimal (pure Python) dependencies. + +```shell +$ pip install 'uvicorn[standard]' +``` + +This will install uvicorn with "Cython-based" dependencies (where possible) and other "optional extras". + +In this context, "Cython-based" means the following: + +- the event loop `uvloop` will be installed and used if possible. +- the http protocol will be handled by `httptools` if possible. + +Moreover, "optional extras" means that: + +- the websocket protocol will be handled by `websockets` (should you want to use `wsproto` you'd need to install it manually) if possible. +- the `--reload` flag in development mode will use `watchfiles`. +- `python-dotenv` will be installed should you want to use the `--env-file` option. +- `PyYAML` will be installed to allow you to provide a `.yaml` file to `--log-config`, if desired. + +Create an application, in `example.py`: + +```python +async def app(scope, receive, send): + assert scope['type'] == 'http' + + await send({ + 'type': 'http.response.start', + 'status': 200, + 'headers': [ + (b'content-type', b'text/plain'), + ], + }) + await send({ + 'type': 'http.response.body', + 'body': b'Hello, world!', + }) +``` + +Run the server: + +```shell +$ uvicorn example:app +``` + +--- + +## Why ASGI? + +Most well established Python Web frameworks started out as WSGI-based frameworks. + +WSGI applications are a single, synchronous callable that takes a request and returns a response. +This doesn’t allow for long-lived connections, like you get with long-poll HTTP or WebSocket connections, +which WSGI doesn't support well. + +Having an async concurrency model also allows for options such as lightweight background tasks, +and can be less of a limiting factor for endpoints that have long periods being blocked on network +I/O such as dealing with slow HTTP requests. + +--- + +## Alternative ASGI servers + +A strength of the ASGI protocol is that it decouples the server implementation +from the application framework. This allows for an ecosystem of interoperating +webservers and application frameworks. + +### Daphne + +The first ASGI server implementation, originally developed to power Django Channels, is [the Daphne webserver][daphne]. + +It is run widely in production, and supports HTTP/1.1, HTTP/2, and WebSockets. + +Any of the example applications given here can equally well be run using `daphne` instead. + +``` +$ pip install daphne +$ daphne app:App +``` + +### Hypercorn + +[Hypercorn][hypercorn] was initially part of the Quart web framework, before +being separated out into a standalone ASGI server. + +Hypercorn supports HTTP/1.1, HTTP/2, and WebSockets. + +It also supports [the excellent `trio` async framework][trio], as an alternative to `asyncio`. + +``` +$ pip install hypercorn +$ hypercorn app:App +``` + +### Mangum + +[Mangum][mangum] is an adapter for using ASGI applications with AWS Lambda & API Gateway. + +### Granian + +[Granian][granian] is an ASGI compatible Rust HTTP server which supports HTTP/2, TLS and WebSockets. + +--- + +

Uvicorn is BSD licensed code.
Designed & crafted with care.

— πŸ¦„ —

+ +[asgi]: https://asgi.readthedocs.io/en/latest/ +[daphne]: https://github.com/django/daphne +[hypercorn]: https://github.com/pgjones/hypercorn +[trio]: https://trio.readthedocs.io +[mangum]: https://github.com/jordaneremieff/mangum +[granian]: https://github.com/emmett-framework/granian diff --git a/.venv/Lib/site-packages/uvicorn-0.51.0.dist-info/RECORD b/.venv/Lib/site-packages/uvicorn-0.51.0.dist-info/RECORD new file mode 100644 index 0000000000000000000000000000000000000000..e2f77854801c0eaa288f88814a85e6afcdfa8e63 --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn-0.51.0.dist-info/RECORD @@ -0,0 +1,90 @@ +../../Scripts/uvicorn.exe,sha256=-SPhVkmoKomyN2m_cAAR7z-HvoWGTKbiaz4lKy7BacU,108462 +uvicorn-0.51.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +uvicorn-0.51.0.dist-info/METADATA,sha256=B8cHkMDN5oEviRaPeqfBhYAKaQ9-ZX37VgOEjBN1AX4,6589 +uvicorn-0.51.0.dist-info/RECORD,, +uvicorn-0.51.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87 +uvicorn-0.51.0.dist-info/entry_points.txt,sha256=FW1w-hkc9QgwaGoovMvm0ZY73w_NcycWdGAUfDsNGxw,46 +uvicorn-0.51.0.dist-info/licenses/LICENSE.md,sha256=7-Gs8-YvuZwoiw7HPlp3O3Jo70Mg_nV-qZQhTktjw3E,1526 +uvicorn/__init__.py,sha256=07oX9VGq6TnIs3mghqQk0uZIIdF08SJFBE0JXx3ps9g,147 +uvicorn/__main__.py,sha256=DQizy6nKP0ywhPpnCHgmRDYIMfcqZKVEzNIWQZjqtVQ,62 +uvicorn/__pycache__/__init__.cpython-312.pyc,, +uvicorn/__pycache__/__main__.cpython-312.pyc,, +uvicorn/__pycache__/_ansi.cpython-312.pyc,, +uvicorn/__pycache__/_compat.cpython-312.pyc,, +uvicorn/__pycache__/_subprocess.cpython-312.pyc,, +uvicorn/__pycache__/_types.cpython-312.pyc,, +uvicorn/__pycache__/config.cpython-312.pyc,, +uvicorn/__pycache__/importer.cpython-312.pyc,, +uvicorn/__pycache__/logging.cpython-312.pyc,, +uvicorn/__pycache__/main.cpython-312.pyc,, +uvicorn/__pycache__/server.cpython-312.pyc,, +uvicorn/__pycache__/workers.cpython-312.pyc,, +uvicorn/_ansi.py,sha256=s8RPpmPTO6QGRgEYbsNGeasSWqiEnCsTroyA8Z59Q00,617 +uvicorn/_compat.py,sha256=6X49c9ovzmMHir2S3syinOQMzSPBcp8MNuI9ZQrbYiU,2916 +uvicorn/_subprocess.py,sha256=fQ4JTajuXay6mVc8KQNGfXu6JHoab46aS6kyIMWJMPk,2776 +uvicorn/_types.py,sha256=JDM6E-hqZ6o_cSZvjDULjAv77PFH2pLe_Vgqshe8qH4,7677 +uvicorn/config.py,sha256=hjwBd2_PcHz92eeTvRgtbWIEvWKhMCITPT2M7fy0o68,24495 +uvicorn/importer.py,sha256=nRt0QQ3qpi264-n_mR0l55C2ddM8nowTNzT1jsWaam8,1128 +uvicorn/lifespan/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +uvicorn/lifespan/__pycache__/__init__.cpython-312.pyc,, +uvicorn/lifespan/__pycache__/off.cpython-312.pyc,, +uvicorn/lifespan/__pycache__/on.cpython-312.pyc,, +uvicorn/lifespan/off.py,sha256=nfI6qHAUo_8-BEXMBKoHQ9wUbsXrPaXLCbDSS0vKSr8,332 +uvicorn/lifespan/on.py,sha256=iETPFj6SFhPDPcdeGxfa43LKImJU7MI5i7QUUepBcPE,5173 +uvicorn/logging.py,sha256=kCB1n45B5O55SSApiv2x6UQG3LnFqNlGvcohGyAwblU,4256 +uvicorn/loops/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +uvicorn/loops/__pycache__/__init__.cpython-312.pyc,, +uvicorn/loops/__pycache__/asyncio.cpython-312.pyc,, +uvicorn/loops/__pycache__/auto.cpython-312.pyc,, +uvicorn/loops/__pycache__/uvloop.cpython-312.pyc,, +uvicorn/loops/asyncio.py,sha256=a8wO4fB4pCk-RLICq7CnGr_cxQI7MBLJj-Go4UQldD8,333 +uvicorn/loops/auto.py,sha256=pdTsMcqkbE8fvdNgLs1y4c6hsuN598mZOSOlC0a23S4,566 +uvicorn/loops/uvloop.py,sha256=Ca-TL-W8tbdEW5uvL_GrMih7G8e_t_vhNevi2NKYjEU,236 +uvicorn/main.py,sha256=YitRjBbr9ECYXUYzV5_y0tVud-8RfkGXrk9dnJJqndg,18812 +uvicorn/middleware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +uvicorn/middleware/__pycache__/__init__.cpython-312.pyc,, +uvicorn/middleware/__pycache__/asgi2.cpython-312.pyc,, +uvicorn/middleware/__pycache__/message_logger.cpython-312.pyc,, +uvicorn/middleware/__pycache__/proxy_headers.cpython-312.pyc,, +uvicorn/middleware/__pycache__/wsgi.cpython-312.pyc,, +uvicorn/middleware/asgi2.py,sha256=YQrQNm3RehFts3mzk3k4yw8aD8Egtj0tRS3N45YkQa0,394 +uvicorn/middleware/message_logger.py,sha256=IHEZUSnFNaMFUFdwtZO3AuFATnYcSor-gVtOjbCzt8M,2859 +uvicorn/middleware/proxy_headers.py,sha256=pNZk80NNscLEwi8pGn6cIbaF0bSfJhCKn3pHjqqfW90,7421 +uvicorn/middleware/wsgi.py,sha256=VnbnkdCL3_ctLWzk1j39xvxysuoAB3kSYmi8TsOLpNs,7125 +uvicorn/protocols/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +uvicorn/protocols/__pycache__/__init__.cpython-312.pyc,, +uvicorn/protocols/__pycache__/utils.cpython-312.pyc,, +uvicorn/protocols/http/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +uvicorn/protocols/http/__pycache__/__init__.cpython-312.pyc,, +uvicorn/protocols/http/__pycache__/auto.cpython-312.pyc,, +uvicorn/protocols/http/__pycache__/flow_control.cpython-312.pyc,, +uvicorn/protocols/http/__pycache__/h11_impl.cpython-312.pyc,, +uvicorn/protocols/http/__pycache__/httptools_impl.cpython-312.pyc,, +uvicorn/protocols/http/auto.py,sha256=YfXGyzWTaaE2p_jkTPWrJCXsxEaQnC3NK0-G7Wgmnls,403 +uvicorn/protocols/http/flow_control.py,sha256=050WVg31EvPOkHwynCoMP1zXFl_vO3U4durlc5vyp4U,1701 +uvicorn/protocols/http/h11_impl.py,sha256=DBDE_HnnQtqW50bAb4OW3dKKDgEATUSOvNqfDCDBF2Q,21202 +uvicorn/protocols/http/httptools_impl.py,sha256=Aq2MlNrL99irluvR673AfcVbo6qlogl8fiR9IODMxxA,22355 +uvicorn/protocols/utils.py,sha256=1hKdDCmo_GtGrK1zZfa70jL7Hr3mDE8RnL69O4rHQRg,2058 +uvicorn/protocols/websockets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +uvicorn/protocols/websockets/__pycache__/__init__.cpython-312.pyc,, +uvicorn/protocols/websockets/__pycache__/auto.cpython-312.pyc,, +uvicorn/protocols/websockets/__pycache__/websockets_impl.cpython-312.pyc,, +uvicorn/protocols/websockets/__pycache__/websockets_sansio_impl.cpython-312.pyc,, +uvicorn/protocols/websockets/__pycache__/wsproto_impl.cpython-312.pyc,, +uvicorn/protocols/websockets/auto.py,sha256=QOnMKZfXHfOcZHdq1OITHwv7Awx1BTS3eJfZswuGEU0,611 +uvicorn/protocols/websockets/websockets_impl.py,sha256=7Bu_Ic_7AdxBcttG0GTLb3tzgQBsHx0Kyb_C49jBzxw,15176 +uvicorn/protocols/websockets/websockets_sansio_impl.py,sha256=Tr54qVO78q0PiCUM-9-jnFabWahGZHLWa5ecKvkOsaY,20607 +uvicorn/protocols/websockets/wsproto_impl.py,sha256=8088Bp8SOz4Z2L2gcqOqV3zgWDVxIN0eIkjhuR9oqYU,19821 +uvicorn/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1 +uvicorn/server.py,sha256=ao_gfmmVQ_Ily8fQwAJ__Sb-yVeX1cahBEbTjHkp7Vc,13382 +uvicorn/supervisors/__init__.py,sha256=wT8eOEIqT1yWQgytZtv5taWMul7xoTIY0xm1m4oyPTw,507 +uvicorn/supervisors/__pycache__/__init__.cpython-312.pyc,, +uvicorn/supervisors/__pycache__/basereload.cpython-312.pyc,, +uvicorn/supervisors/__pycache__/multiprocess.cpython-312.pyc,, +uvicorn/supervisors/__pycache__/statreload.cpython-312.pyc,, +uvicorn/supervisors/__pycache__/watchfilesreload.cpython-312.pyc,, +uvicorn/supervisors/basereload.py,sha256=C-YD18flOKKVRNTRsSCOEvyqGf3ZxpvuUvR0z0Y1Wpg,4018 +uvicorn/supervisors/multiprocess.py,sha256=U1QZdiJ_7Auazix6XOj1ku0Nj_N_PJPCoYuq6SNjZcI,10271 +uvicorn/supervisors/statreload.py,sha256=XPaEtVXaasII1kkG32UUG8oD7-fS0FwyXkQLF9QYPbA,1548 +uvicorn/supervisors/watchfilesreload.py,sha256=u-MuYm0LsZMN670u_TtSWiMBUA2z4j1sIe3O2A67Ep4,2923 +uvicorn/workers.py,sha256=lMCubn1Wi-4h2jxrXNMmhOJZy7ZP8QxbZbP3_2O1iHE,3873 diff --git a/.venv/Lib/site-packages/uvicorn-0.51.0.dist-info/WHEEL b/.venv/Lib/site-packages/uvicorn-0.51.0.dist-info/WHEEL new file mode 100644 index 0000000000000000000000000000000000000000..bd842267444de3fff37e8c9981cd8662490531b4 --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn-0.51.0.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: hatchling 1.30.1 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/.venv/Lib/site-packages/uvicorn-0.51.0.dist-info/entry_points.txt b/.venv/Lib/site-packages/uvicorn-0.51.0.dist-info/entry_points.txt new file mode 100644 index 0000000000000000000000000000000000000000..4b00fcb60173c5497fb24839da1837e8bdbfd98c --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn-0.51.0.dist-info/entry_points.txt @@ -0,0 +1,2 @@ +[console_scripts] +uvicorn = uvicorn.main:main diff --git a/.venv/Lib/site-packages/uvicorn-0.51.0.dist-info/licenses/LICENSE.md b/.venv/Lib/site-packages/uvicorn-0.51.0.dist-info/licenses/LICENSE.md new file mode 100644 index 0000000000000000000000000000000000000000..a6bba14552c7673a7db57a5750ddb06508264273 --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn-0.51.0.dist-info/licenses/LICENSE.md @@ -0,0 +1,27 @@ +Copyright Β© 2017-present, [Encode OSS Ltd](https://www.encode.io/). +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/.venv/Lib/site-packages/uvicorn/__init__.py b/.venv/Lib/site-packages/uvicorn/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..6b773b5a9f2a72bf5ae4ea5582e4d5e92864e21b --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/__init__.py @@ -0,0 +1,5 @@ +from uvicorn.config import Config +from uvicorn.main import Server, main, run + +__version__ = "0.51.0" +__all__ = ["main", "run", "Config", "Server"] diff --git a/.venv/Lib/site-packages/uvicorn/__main__.py b/.venv/Lib/site-packages/uvicorn/__main__.py new file mode 100644 index 0000000000000000000000000000000000000000..8a1dc979a39e36ce81e987843391479f125d73f3 --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/__main__.py @@ -0,0 +1,4 @@ +import uvicorn + +if __name__ == "__main__": + uvicorn.main() diff --git a/.venv/Lib/site-packages/uvicorn/_ansi.py b/.venv/Lib/site-packages/uvicorn/_ansi.py new file mode 100644 index 0000000000000000000000000000000000000000..8f60f404ea2ab5526716bb78260665570d05590a --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/_ansi.py @@ -0,0 +1,29 @@ +from __future__ import annotations + +_ANSI_COLORS = { + "black": 30, + "red": 31, + "green": 32, + "yellow": 33, + "blue": 34, + "magenta": 35, + "cyan": 36, + "white": 37, + "bright_black": 90, + "bright_red": 91, + "bright_green": 92, + "bright_yellow": 93, + "bright_blue": 94, + "bright_magenta": 95, + "bright_cyan": 96, + "bright_white": 97, +} + + +def style(text: str, fg: str | None = None, bold: bool = False) -> str: + prefix = "" + if fg is not None: + prefix += f"\033[{_ANSI_COLORS[fg]}m" + if bold: + prefix += "\033[1m" + return f"{prefix}{text}\033[0m" diff --git a/.venv/Lib/site-packages/uvicorn/_compat.py b/.venv/Lib/site-packages/uvicorn/_compat.py new file mode 100644 index 0000000000000000000000000000000000000000..118a19ac0c43e518a24cf1108bfbb9dde507bd0c --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/_compat.py @@ -0,0 +1,91 @@ +from __future__ import annotations + +import asyncio +import sys +from collections.abc import Callable, Coroutine +from typing import Any, TypeVar + +__all__ = ["asyncio_run", "iscoroutinefunction"] + +if sys.version_info >= (3, 14): + from inspect import iscoroutinefunction +else: + from asyncio import iscoroutinefunction + +_T = TypeVar("_T") + +if sys.version_info >= (3, 12): + asyncio_run = asyncio.run +elif sys.version_info >= (3, 11): + + def asyncio_run( + main: Coroutine[Any, Any, _T], + *, + debug: bool = False, + loop_factory: Callable[[], asyncio.AbstractEventLoop] | None = None, + ) -> _T: + # asyncio.run from Python 3.12 + # https://docs.python.org/3/license.html#psf-license + with asyncio.Runner(debug=debug, loop_factory=loop_factory) as runner: + return runner.run(main) + +else: + # modified version of asyncio.run from Python 3.10 to add loop_factory kwarg + # https://docs.python.org/3/license.html#psf-license + def asyncio_run( + main: Coroutine[Any, Any, _T], + *, + debug: bool = False, + loop_factory: Callable[[], asyncio.AbstractEventLoop] | None = None, + ) -> _T: + try: + asyncio.get_running_loop() + except RuntimeError: + pass + else: + raise RuntimeError("asyncio.run() cannot be called from a running event loop") + + if not asyncio.iscoroutine(main): + raise ValueError(f"a coroutine was expected, got {main!r}") + + if loop_factory is None: + loop = asyncio.new_event_loop() + else: + loop = loop_factory() + try: + if loop_factory is None: + asyncio.set_event_loop(loop) + if debug is not None: + loop.set_debug(debug) + return loop.run_until_complete(main) + finally: + try: + _cancel_all_tasks(loop) + loop.run_until_complete(loop.shutdown_asyncgens()) + loop.run_until_complete(loop.shutdown_default_executor()) + finally: + if loop_factory is None: + asyncio.set_event_loop(None) + loop.close() + + def _cancel_all_tasks(loop: asyncio.AbstractEventLoop) -> None: + to_cancel = asyncio.all_tasks(loop) + if not to_cancel: + return + + for task in to_cancel: + task.cancel() + + loop.run_until_complete(asyncio.gather(*to_cancel, return_exceptions=True)) + + for task in to_cancel: + if task.cancelled(): + continue + if task.exception() is not None: + loop.call_exception_handler( + { + "message": "unhandled exception during asyncio.run() shutdown", + "exception": task.exception(), + "task": task, + } + ) diff --git a/.venv/Lib/site-packages/uvicorn/_subprocess.py b/.venv/Lib/site-packages/uvicorn/_subprocess.py new file mode 100644 index 0000000000000000000000000000000000000000..c084ec90b6a16c9e4824808d22283642e2757ded --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/_subprocess.py @@ -0,0 +1,84 @@ +""" +Some light wrappers around Python's multiprocessing, to deal with cleanly +starting child processes. +""" + +from __future__ import annotations + +import multiprocessing +import os +import sys +from collections.abc import Callable +from multiprocessing.context import SpawnProcess +from socket import socket + +from uvicorn.config import Config + +multiprocessing.allow_connection_pickling() +spawn = multiprocessing.get_context("spawn") + + +def get_subprocess( + config: Config, + target: Callable[..., None], + sockets: list[socket], +) -> SpawnProcess: + """ + Called in the parent process, to instantiate a new child process instance. + The child is not yet started at this point. + + * config - The Uvicorn configuration instance. + * target - A callable that accepts a list of sockets. In practice this will + be the `Server.run()` method. + * sockets - A list of sockets to pass to the server. Sockets are bound once + by the parent process, and then passed to the child processes. + """ + # We pass across the stdin fileno, and reopen it in the child process. + # This is required for some debugging environments. + try: + stdin_fileno = sys.stdin.fileno() + # The `sys.stdin` can be `None`, see https://docs.python.org/3/library/sys.html#sys.__stdin__. + except (AttributeError, OSError): + stdin_fileno = None + + kwargs = { + "config": config, + "target": target, + "sockets": sockets, + "stdin_fileno": stdin_fileno, + } + + return spawn.Process(target=subprocess_started, kwargs=kwargs) + + +def subprocess_started( + config: Config, + target: Callable[..., None], + sockets: list[socket], + stdin_fileno: int | None, +) -> None: + """ + Called when the child process starts. + + * config - The Uvicorn configuration instance. + * target - A callable that accepts a list of sockets. In practice this will + be the `Server.run()` method. + * sockets - A list of sockets to pass to the server. Sockets are bound once + by the parent process, and then passed to the child processes. + * stdin_fileno - The file number of sys.stdin, so that it can be reattached + to the child process. + """ + # Re-open stdin. + if stdin_fileno is not None: + sys.stdin = os.fdopen(stdin_fileno) # pragma: full coverage + + # Logging needs to be setup again for each child. + config.configure_logging() + + try: + # Now we can call into `Server.run(sockets=sockets)` + target(sockets=sockets) + except KeyboardInterrupt: # pragma: no cover + # suppress the exception to avoid a traceback from subprocess.Popen + # the parent already expects us to end, so no vital information is lost + pass diff --git a/.venv/Lib/site-packages/uvicorn/_types.py b/.venv/Lib/site-packages/uvicorn/_types.py new file mode 100644 index 0000000000000000000000000000000000000000..822445a7b58bb5b0726a9be205e8855a958dcdcf --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/_types.py @@ -0,0 +1,274 @@ +""" +Copyright (c) Django Software Foundation and individual contributors. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Django nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +""" + +from __future__ import annotations + +import sys +import types +from collections.abc import Awaitable, Callable, Iterable, MutableMapping +from typing import Any, Literal, Protocol, TypedDict + +if sys.version_info >= (3, 11): # pragma: py-lt-311 + from typing import NotRequired +else: # pragma: py-gte-311 + from typing_extensions import NotRequired + +# WSGI +Environ = MutableMapping[str, Any] +ExcInfo = tuple[type[BaseException], BaseException, types.TracebackType | None] +StartResponse = Callable[[str, Iterable[tuple[str, str]], ExcInfo | None], None] +WSGIApp = Callable[[Environ, StartResponse], Iterable[bytes] | BaseException] + + +# ASGI +class ASGIVersions(TypedDict): + spec_version: str + version: Literal["2.0"] | Literal["3.0"] + + +class HTTPScope(TypedDict): + type: Literal["http"] + asgi: ASGIVersions + http_version: str + method: str + scheme: str + path: str + raw_path: bytes + query_string: bytes + root_path: str + headers: Iterable[tuple[bytes, bytes]] + client: tuple[str, int] | None + server: tuple[str, int | None] | None + state: NotRequired[dict[str, Any]] + extensions: NotRequired[dict[str, dict[object, object]]] + + +class WebSocketScope(TypedDict): + type: Literal["websocket"] + asgi: ASGIVersions + http_version: str + scheme: str + path: str + raw_path: bytes + query_string: bytes + root_path: str + headers: Iterable[tuple[bytes, bytes]] + client: tuple[str, int] | None + server: tuple[str, int | None] | None + subprotocols: Iterable[str] + state: NotRequired[dict[str, Any]] + extensions: NotRequired[dict[str, dict[object, object]]] + + +class LifespanScope(TypedDict): + type: Literal["lifespan"] + asgi: ASGIVersions + state: NotRequired[dict[str, Any]] + + +WWWScope = HTTPScope | WebSocketScope +Scope = HTTPScope | WebSocketScope | LifespanScope + + +class HTTPRequestEvent(TypedDict): + type: Literal["http.request"] + body: bytes + more_body: bool + + +class HTTPResponseDebugEvent(TypedDict): + type: Literal["http.response.debug"] + info: dict[str, object] + + +class HTTPResponseStartEvent(TypedDict): + type: Literal["http.response.start"] + status: int + headers: NotRequired[Iterable[tuple[bytes, bytes]]] + trailers: NotRequired[bool] + + +class HTTPResponseBodyEvent(TypedDict): + type: Literal["http.response.body"] + body: bytes + more_body: NotRequired[bool] + + +class HTTPResponseTrailersEvent(TypedDict): + type: Literal["http.response.trailers"] + headers: Iterable[tuple[bytes, bytes]] + more_trailers: bool + + +class HTTPServerPushEvent(TypedDict): + type: Literal["http.response.push"] + path: str + headers: Iterable[tuple[bytes, bytes]] + + +class HTTPDisconnectEvent(TypedDict): + type: Literal["http.disconnect"] + + +class WebSocketConnectEvent(TypedDict): + type: Literal["websocket.connect"] + + +class WebSocketAcceptEvent(TypedDict): + type: Literal["websocket.accept"] + subprotocol: NotRequired[str | None] + headers: NotRequired[Iterable[tuple[bytes, bytes]]] + + +class _WebSocketReceiveEventBytes(TypedDict): + type: Literal["websocket.receive"] + bytes: bytes + text: NotRequired[None] + + +class _WebSocketReceiveEventText(TypedDict): + type: Literal["websocket.receive"] + bytes: NotRequired[None] + text: str + + +WebSocketReceiveEvent = _WebSocketReceiveEventBytes | _WebSocketReceiveEventText + + +class _WebSocketSendEventBytes(TypedDict): + type: Literal["websocket.send"] + bytes: bytes + text: NotRequired[None] + + +class _WebSocketSendEventText(TypedDict): + type: Literal["websocket.send"] + bytes: NotRequired[None] + text: str + + +WebSocketSendEvent = _WebSocketSendEventBytes | _WebSocketSendEventText + + +class WebSocketResponseStartEvent(TypedDict): + type: Literal["websocket.http.response.start"] + status: int + headers: Iterable[tuple[bytes, bytes]] + + +class WebSocketResponseBodyEvent(TypedDict): + type: Literal["websocket.http.response.body"] + body: bytes + more_body: NotRequired[bool] + + +class WebSocketDisconnectEvent(TypedDict): + type: Literal["websocket.disconnect"] + code: int + reason: NotRequired[str | None] + + +class WebSocketCloseEvent(TypedDict): + type: Literal["websocket.close"] + code: NotRequired[int] + reason: NotRequired[str | None] + + +class LifespanStartupEvent(TypedDict): + type: Literal["lifespan.startup"] + + +class LifespanShutdownEvent(TypedDict): + type: Literal["lifespan.shutdown"] + + +class LifespanStartupCompleteEvent(TypedDict): + type: Literal["lifespan.startup.complete"] + + +class LifespanStartupFailedEvent(TypedDict): + type: Literal["lifespan.startup.failed"] + message: str + + +class LifespanShutdownCompleteEvent(TypedDict): + type: Literal["lifespan.shutdown.complete"] + + +class LifespanShutdownFailedEvent(TypedDict): + type: Literal["lifespan.shutdown.failed"] + message: str + + +WebSocketEvent = WebSocketReceiveEvent | WebSocketDisconnectEvent | WebSocketConnectEvent + + +ASGIReceiveEvent = ( + HTTPRequestEvent + | HTTPDisconnectEvent + | WebSocketConnectEvent + | WebSocketReceiveEvent + | WebSocketDisconnectEvent + | LifespanStartupEvent + | LifespanShutdownEvent +) + + +ASGISendEvent = ( + HTTPResponseStartEvent + | HTTPResponseBodyEvent + | HTTPResponseTrailersEvent + | HTTPServerPushEvent + | HTTPDisconnectEvent + | WebSocketAcceptEvent + | WebSocketSendEvent + | WebSocketResponseStartEvent + | WebSocketResponseBodyEvent + | WebSocketCloseEvent + | LifespanStartupCompleteEvent + | LifespanStartupFailedEvent + | LifespanShutdownCompleteEvent + | LifespanShutdownFailedEvent +) + + +ASGIReceiveCallable = Callable[[], Awaitable[ASGIReceiveEvent]] +ASGISendCallable = Callable[[ASGISendEvent], Awaitable[None]] + + +class ASGI2Protocol(Protocol): + def __init__(self, scope: Scope) -> None: ... # pragma: no cover + + async def __call__(self, receive: ASGIReceiveCallable, send: ASGISendCallable) -> None: ... # pragma: no cover + + +ASGI2Application = type[ASGI2Protocol] +ASGI3Application = Callable[[Scope, ASGIReceiveCallable, ASGISendCallable], Awaitable[None]] +ASGIApplication = ASGI2Application | ASGI3Application diff --git a/.venv/Lib/site-packages/uvicorn/config.py b/.venv/Lib/site-packages/uvicorn/config.py new file mode 100644 index 0000000000000000000000000000000000000000..ef60cce3a4425a7f3e92729b1aef7ea6de0877f7 --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/config.py @@ -0,0 +1,600 @@ +from __future__ import annotations + +import asyncio +import inspect +import json +import logging +import logging.config +import os +import socket +import ssl +import sys +from collections.abc import Awaitable, Callable +from configparser import RawConfigParser +from pathlib import Path +from typing import IO, Any, Literal + +from uvicorn._ansi import style +from uvicorn._compat import iscoroutinefunction +from uvicorn._types import ASGIApplication +from uvicorn.importer import ImportFromStringError, import_from_string +from uvicorn.logging import TRACE_LOG_LEVEL +from uvicorn.middleware.asgi2 import ASGI2Middleware +from uvicorn.middleware.message_logger import MessageLoggerMiddleware +from uvicorn.middleware.proxy_headers import ProxyHeadersMiddleware +from uvicorn.middleware.wsgi import WSGIMiddleware + + +class UvicornDeprecationWarning(UserWarning): + """A custom deprecation warning for Uvicorn. + + Unlike the built-in DeprecationWarning, this inherits from UserWarning to ensure it is visible by default, helping + users discover deprecated features without needing to enable warnings explicitly. + + Reference: https://sethmlarson.dev/deprecations-via-warnings-dont-work-for-python-libraries + """ + + +HTTPProtocolType = Literal["auto", "h11", "httptools"] +WSProtocolType = Literal["auto", "none", "websockets", "websockets-sansio", "wsproto"] +LifespanType = Literal["auto", "on", "off"] +LoopFactoryType = Literal["none", "auto", "asyncio", "uvloop"] +InterfaceType = Literal["auto", "asgi3", "asgi2", "wsgi"] + +LOG_LEVELS: dict[str, int] = { + "critical": logging.CRITICAL, + "error": logging.ERROR, + "warning": logging.WARNING, + "info": logging.INFO, + "debug": logging.DEBUG, + "trace": TRACE_LOG_LEVEL, +} +HTTP_PROTOCOLS: dict[str, str] = { + "auto": "uvicorn.protocols.http.auto:AutoHTTPProtocol", + "h11": "uvicorn.protocols.http.h11_impl:H11Protocol", + "httptools": "uvicorn.protocols.http.httptools_impl:HttpToolsProtocol", +} +WS_PROTOCOLS: dict[str, str | None] = { + "auto": "uvicorn.protocols.websockets.auto:AutoWebSocketsProtocol", + "none": None, + "websockets": "uvicorn.protocols.websockets.websockets_impl:WebSocketProtocol", + "websockets-sansio": "uvicorn.protocols.websockets.websockets_sansio_impl:WebSocketsSansIOProtocol", + "wsproto": "uvicorn.protocols.websockets.wsproto_impl:WSProtocol", +} +LIFESPAN: dict[str, str] = { + "auto": "uvicorn.lifespan.on:LifespanOn", + "on": "uvicorn.lifespan.on:LifespanOn", + "off": "uvicorn.lifespan.off:LifespanOff", +} +LOOP_FACTORIES: dict[str, str | None] = { + "none": None, + "auto": "uvicorn.loops.auto:auto_loop_factory", + "asyncio": "uvicorn.loops.asyncio:asyncio_loop_factory", + "uvloop": "uvicorn.loops.uvloop:uvloop_loop_factory", +} +INTERFACES: list[InterfaceType] = ["auto", "asgi3", "asgi2", "wsgi"] + +SSL_PROTOCOL_VERSION: int = ssl.PROTOCOL_TLS_SERVER + +STARTUP_FAILURE = 3 + +LOGGING_CONFIG: dict[str, Any] = { + "version": 1, + "disable_existing_loggers": False, + "formatters": { + "default": { + "()": "uvicorn.logging.DefaultFormatter", + "fmt": "%(levelprefix)s %(message)s", + "use_colors": None, + }, + "access": { + "()": "uvicorn.logging.AccessFormatter", + "fmt": '%(levelprefix)s %(client_addr)s - "%(request_line)s" %(status_code)s', # noqa: E501 + }, + }, + "handlers": { + "default": { + "formatter": "default", + "class": "logging.StreamHandler", + "stream": "ext://sys.stderr", + }, + "access": { + "formatter": "access", + "class": "logging.StreamHandler", + "stream": "ext://sys.stdout", + }, + }, + "loggers": { + "uvicorn": {"handlers": ["default"], "level": "INFO", "propagate": False}, + "uvicorn.error": {"level": "INFO"}, + "uvicorn.access": {"handlers": ["access"], "level": "INFO", "propagate": False}, + }, +} + +logger = logging.getLogger("uvicorn.error") + + +def create_ssl_context( + certfile: str | os.PathLike[str], + keyfile: str | os.PathLike[str] | None, + password: str | None, + ssl_version: int, + cert_reqs: int, + ca_certs: str | os.PathLike[str] | None, + ciphers: str | None, +) -> ssl.SSLContext: + ctx = ssl.SSLContext(ssl_version) + get_password = (lambda: password) if password else None + ctx.load_cert_chain(certfile, keyfile, get_password) + ctx.verify_mode = ssl.VerifyMode(cert_reqs) + if ca_certs: + ctx.load_verify_locations(ca_certs) + if ciphers: + ctx.set_ciphers(ciphers) + return ctx + + +def is_dir(path: Path) -> bool: + try: + if not path.is_absolute(): + path = path.resolve() + return path.is_dir() + except OSError: # pragma: full coverage + return False + + +def resolve_reload_patterns(patterns_list: list[str], directories_list: list[str]) -> tuple[list[str], list[Path]]: + directories: list[Path] = list(set(map(Path, directories_list.copy()))) + patterns: list[str] = patterns_list.copy() + + current_working_directory = Path.cwd() + for pattern in patterns_list: + # Special case for the .* pattern, otherwise this would only match + # hidden directories which is probably undesired + if pattern == ".*": + continue # pragma: py-not-linux + patterns.append(pattern) + if is_dir(Path(pattern)): + directories.append(Path(pattern)) + else: + for match in current_working_directory.glob(pattern): + if is_dir(match): + directories.append(match) + + directories = list(set(directories)) + directories = list(map(Path, directories)) + directories = list(map(lambda x: x.resolve(), directories)) + directories = list({reload_path for reload_path in directories if is_dir(reload_path)}) + + children = [] + for j in range(len(directories)): + for k in range(j + 1, len(directories)): # pragma: full coverage + if directories[j] in directories[k].parents: + children.append(directories[k]) + elif directories[k] in directories[j].parents: + children.append(directories[j]) + + directories = list(set(directories).difference(set(children))) + + return list(set(patterns)), directories + + +def _normalize_dirs(dirs: list[str] | str | None) -> list[str]: + if dirs is None: + return [] + if isinstance(dirs, str): + return [dirs] + return list(set(dirs)) + + +class Config: + def __init__( + self, + app: ASGIApplication | Callable[..., Any] | str, + host: str = "127.0.0.1", + port: int = 8000, + uds: str | None = None, + fd: int | None = None, + loop: LoopFactoryType | str = "auto", + http: type[asyncio.Protocol] | HTTPProtocolType | str = "auto", + ws: type[asyncio.Protocol] | WSProtocolType | str = "auto", + ws_max_size: int = 16 * 1024 * 1024, + ws_max_queue: int = 32, + ws_ping_interval: float | None = 20.0, + ws_ping_timeout: float | None = 20.0, + ws_per_message_deflate: bool = True, + lifespan: LifespanType = "auto", + env_file: str | os.PathLike[str] | None = None, + log_config: dict[str, Any] | str | os.PathLike[str] | RawConfigParser | IO[Any] | None = LOGGING_CONFIG, + log_level: str | int | None = None, + access_log: bool = True, + use_colors: bool | None = None, + interface: InterfaceType = "auto", + reload: bool = False, + reload_dirs: list[str] | str | None = None, + reload_delay: float = 0.25, + reload_includes: list[str] | str | None = None, + reload_excludes: list[str] | str | None = None, + workers: int | None = None, + proxy_headers: bool = True, + server_header: bool = True, + date_header: bool = True, + forwarded_allow_ips: list[str] | str | None = None, + root_path: str = "", + limit_concurrency: int | None = None, + limit_max_requests: int | None = None, + limit_max_requests_jitter: int = 0, + backlog: int = 2048, + timeout_keep_alive: int = 5, + timeout_notify: int = 30, + timeout_graceful_shutdown: int | None = None, + timeout_worker_healthcheck: int = 5, + callback_notify: Callable[..., Awaitable[None]] | None = None, + ssl_keyfile: str | os.PathLike[str] | None = None, + ssl_certfile: str | os.PathLike[str] | None = None, + ssl_keyfile_password: str | None = None, + ssl_version: int = SSL_PROTOCOL_VERSION, + ssl_cert_reqs: int = ssl.CERT_NONE, + ssl_ca_certs: str | os.PathLike[str] | None = None, + ssl_ciphers: str | None = None, + ssl_context_factory: Callable[[Config, Callable[[], ssl.SSLContext]], ssl.SSLContext] | None = None, + headers: list[tuple[str, str]] | None = None, + factory: bool = False, + h11_max_incomplete_event_size: int | None = None, + reset_contextvars: bool = False, + ): + self.app = app + self.host = host + self.port = port + self.uds = uds + self.fd = fd + self.loop = loop + self.http = http + self.ws = ws + self.ws_max_size = ws_max_size + self.ws_max_queue = ws_max_queue + self.ws_ping_interval = ws_ping_interval + self.ws_ping_timeout = ws_ping_timeout + self.ws_per_message_deflate = ws_per_message_deflate + self.lifespan = lifespan + self.log_config = log_config + self.log_level = log_level + self.access_log = access_log + self.use_colors = use_colors + self.interface = interface + self.reload = reload + self.reload_delay = reload_delay + self.workers = workers or 1 + self.proxy_headers = proxy_headers + self.server_header = server_header + self.date_header = date_header + self.root_path = root_path + self.limit_concurrency = limit_concurrency + self.limit_max_requests = limit_max_requests + self.limit_max_requests_jitter = limit_max_requests_jitter + self.backlog = backlog + self.timeout_keep_alive = timeout_keep_alive + self.timeout_notify = timeout_notify + self.timeout_graceful_shutdown = timeout_graceful_shutdown + self.timeout_worker_healthcheck = timeout_worker_healthcheck + self.callback_notify = callback_notify + self.ssl_keyfile = ssl_keyfile + self.ssl_certfile = ssl_certfile + self.ssl_keyfile_password = ssl_keyfile_password + self.ssl_version = ssl_version + self.ssl_cert_reqs = ssl_cert_reqs + self.ssl_ca_certs = ssl_ca_certs + self.ssl_ciphers = ssl_ciphers + self.ssl_context_factory = ssl_context_factory + self.headers: list[tuple[str, str]] = headers or [] + self.encoded_headers: list[tuple[bytes, bytes]] = [] + self.factory = factory + self.h11_max_incomplete_event_size = h11_max_incomplete_event_size + self.reset_contextvars = reset_contextvars + + self.loaded = False + self.configure_logging() + + self.reload_dirs: list[Path] = [] + self.reload_dirs_excludes: list[Path] = [] + self.reload_includes: list[str] = [] + self.reload_excludes: list[str] = [] + + if (reload_dirs or reload_includes or reload_excludes) and not self.should_reload: + logger.warning( + "Current configuration will not reload as not all conditions are met, please refer to documentation." + ) + + if self.should_reload: + reload_dirs = _normalize_dirs(reload_dirs) + reload_includes = _normalize_dirs(reload_includes) + reload_excludes = _normalize_dirs(reload_excludes) + + self.reload_includes, self.reload_dirs = resolve_reload_patterns(reload_includes, reload_dirs) + + self.reload_excludes, self.reload_dirs_excludes = resolve_reload_patterns(reload_excludes, []) + + reload_dirs_tmp = self.reload_dirs.copy() + + for directory in self.reload_dirs_excludes: + for reload_directory in reload_dirs_tmp: + if directory == reload_directory or directory in reload_directory.parents: + try: + self.reload_dirs.remove(reload_directory) + except ValueError: # pragma: full coverage + pass + + for pattern in self.reload_excludes: + if pattern in self.reload_includes: + self.reload_includes.remove(pattern) # pragma: full coverage + + if not self.reload_dirs: + if reload_dirs: + logger.warning( + "Provided reload directories %s did not contain valid " + + "directories, watching current working directory.", + reload_dirs, + ) + self.reload_dirs = [Path.cwd()] + + logger.info( + "Will watch for changes in these directories: %s", + sorted(list(map(str, self.reload_dirs))), + ) + + if env_file is not None: + from dotenv import load_dotenv + + logger.info("Loading environment from '%s'", env_file) + load_dotenv(dotenv_path=env_file) + + if workers is None and "WEB_CONCURRENCY" in os.environ: + self.workers = int(os.environ["WEB_CONCURRENCY"]) + + self.forwarded_allow_ips: list[str] | str + if forwarded_allow_ips is None: + self.forwarded_allow_ips = os.environ.get("FORWARDED_ALLOW_IPS", "127.0.0.1") + else: + self.forwarded_allow_ips = forwarded_allow_ips # pragma: full coverage + + if self.reload and self.workers > 1: + logger.warning('"workers" flag is ignored when reloading is enabled.') + + @property + def asgi_version(self) -> Literal["2.0", "3.0"]: + mapping: dict[str, Literal["2.0", "3.0"]] = { + "asgi2": "2.0", + "asgi3": "3.0", + "wsgi": "3.0", + } + return mapping[self.interface] + + @property + def is_ssl(self) -> bool: + return bool(self.ssl_keyfile or self.ssl_certfile or self.ssl_context_factory) + + @property + def use_subprocess(self) -> bool: + return bool(self.reload or self.workers > 1) + + def configure_logging(self) -> None: + logging.addLevelName(TRACE_LOG_LEVEL, "TRACE") + + if self.log_config is not None: + if isinstance(self.log_config, os.PathLike): + self.log_config = os.fspath(self.log_config) + + if isinstance(self.log_config, dict): + if self.use_colors in (True, False): + self.log_config["formatters"]["default"]["use_colors"] = self.use_colors + self.log_config["formatters"]["access"]["use_colors"] = self.use_colors + logging.config.dictConfig(self.log_config) + elif isinstance(self.log_config, str) and self.log_config.endswith(".json"): + with open(self.log_config) as file: + loaded_config = json.load(file) + logging.config.dictConfig(loaded_config) + elif isinstance(self.log_config, str) and self.log_config.endswith((".yaml", ".yml")): + try: + import yaml + except ImportError as e: + raise ImportError( + "Install the PyYAML package or uvicorn[standard] to use `--log-config` with YAML files." + ) from e + + with open(self.log_config) as file: + loaded_config = yaml.safe_load(file) + logging.config.dictConfig(loaded_config) + else: + # See the note about fileConfig() here: + # https://docs.python.org/3/library/logging.config.html#configuration-file-format + logging.config.fileConfig(self.log_config, disable_existing_loggers=False) + + if self.log_level is not None: + if isinstance(self.log_level, str): + log_level = LOG_LEVELS[self.log_level.lower()] + else: + log_level = self.log_level + logging.getLogger("uvicorn.error").setLevel(log_level) + logging.getLogger("uvicorn.access").setLevel(log_level) + logging.getLogger("uvicorn.asgi").setLevel(log_level) + if self.access_log is False: + logging.getLogger("uvicorn.access").handlers = [] + logging.getLogger("uvicorn.access").propagate = False + + def load_app(self) -> Any: + """Import the app and return it. Exits on failure.""" + try: + return import_from_string(self.app) + except ImportFromStringError as exc: + logger.error("Error loading ASGI app. %s" % exc) + sys.exit(STARTUP_FAILURE) + + def load(self) -> None: + assert not self.loaded + + if self.ssl_context_factory is not None: + + def default_factory() -> ssl.SSLContext: + if not self.ssl_certfile: + raise RuntimeError( + "`default_ssl_context_factory()` requires `ssl_certfile` to be set on `Config`. " + "Either pass `ssl_certfile` (and optionally `ssl_keyfile`) or build the `SSLContext` " + "directly inside `ssl_context_factory` without calling the default factory." + ) + return create_ssl_context( + keyfile=self.ssl_keyfile, + certfile=self.ssl_certfile, + password=self.ssl_keyfile_password, + ssl_version=self.ssl_version, + cert_reqs=self.ssl_cert_reqs, + ca_certs=self.ssl_ca_certs, + ciphers=self.ssl_ciphers, + ) + + context = self.ssl_context_factory(self, default_factory) + if not isinstance(context, ssl.SSLContext): + raise TypeError(f"`ssl_context_factory` must return an `ssl.SSLContext`, got {type(context).__name__}") + self.ssl: ssl.SSLContext | None = context + elif self.is_ssl: + assert self.ssl_certfile + self.ssl = create_ssl_context( + keyfile=self.ssl_keyfile, + certfile=self.ssl_certfile, + password=self.ssl_keyfile_password, + ssl_version=self.ssl_version, + cert_reqs=self.ssl_cert_reqs, + ca_certs=self.ssl_ca_certs, + ciphers=self.ssl_ciphers, + ) + else: + self.ssl = None + + encoded_headers = [(key.lower().encode("latin1"), value.encode("latin1")) for key, value in self.headers] + self.encoded_headers = ( + [(b"server", b"uvicorn")] + encoded_headers + if b"server" not in dict(encoded_headers) and self.server_header + else encoded_headers + ) + + if isinstance(self.http, str): + http_protocol_class = import_from_string(HTTP_PROTOCOLS.get(self.http, self.http)) + self.http_protocol_class: type[asyncio.Protocol] = http_protocol_class + else: + self.http_protocol_class = self.http + + if isinstance(self.ws, str): + ws_protocol_class = import_from_string(WS_PROTOCOLS.get(self.ws, self.ws)) + self.ws_protocol_class: type[asyncio.Protocol] | None = ws_protocol_class + else: + self.ws_protocol_class = self.ws + + self.lifespan_class = import_from_string(LIFESPAN[self.lifespan]) + + self.loaded_app = self.load_app() + + try: + self.loaded_app = self.loaded_app() + except TypeError as exc: + if self.factory: + logger.error("Error loading ASGI app factory: %s", exc) + sys.exit(STARTUP_FAILURE) + else: + if not self.factory: + logger.warning( + "ASGI app factory detected. Using it, but please consider setting the --factory flag explicitly." + ) + + if self.interface == "auto": + if inspect.isclass(self.loaded_app): + use_asgi_3 = hasattr(self.loaded_app, "__await__") + elif inspect.isfunction(self.loaded_app): + use_asgi_3 = iscoroutinefunction(self.loaded_app) + else: + call = getattr(self.loaded_app, "__call__", None) + use_asgi_3 = iscoroutinefunction(call) + self.interface = "asgi3" if use_asgi_3 else "asgi2" + + if self.interface == "wsgi": + self.loaded_app = WSGIMiddleware(self.loaded_app) + self.ws_protocol_class = None + elif self.interface == "asgi2": + self.loaded_app = ASGI2Middleware(self.loaded_app) + + if logger.getEffectiveLevel() <= TRACE_LOG_LEVEL: + self.loaded_app = MessageLoggerMiddleware(self.loaded_app) + if self.proxy_headers: + self.loaded_app = ProxyHeadersMiddleware(self.loaded_app, trusted_hosts=self.forwarded_allow_ips) + + self.loaded = True + + def setup_event_loop(self) -> None: + raise AttributeError( + "The `setup_event_loop` method was replaced by `get_loop_factory` in uvicorn 0.36.0.\n" + "None of those methods are supposed to be used directly. If you are doing it, please let me know here: " + "https://github.com/Kludex/uvicorn/discussions/2706. Thank you, and sorry for the inconvenience." + ) + + def get_loop_factory(self) -> Callable[[], asyncio.AbstractEventLoop] | None: + if self.loop in LOOP_FACTORIES: + loop_factory: Callable[..., Any] | None = import_from_string(LOOP_FACTORIES[self.loop]) + else: + try: + return import_from_string(self.loop) + except ImportFromStringError as exc: + logger.error("Error loading custom loop setup function. %s" % exc) + sys.exit(STARTUP_FAILURE) + if loop_factory is None: + return None + return loop_factory(use_subprocess=self.use_subprocess) + + def bind_socket(self) -> socket.socket: + logger_args: list[str | int] + if self.uds is not None: # pragma: py-win32 + path = self.uds + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + try: + sock.bind(path) + uds_perms = 0o666 + os.chmod(self.uds, uds_perms) + except OSError as exc: # pragma: full coverage + logger.error(exc) + sys.exit(STARTUP_FAILURE) + + message = "Uvicorn running on unix socket %s (Press CTRL+C to quit)" + sock_name_format = "%s" + color_message = "Uvicorn running on " + style(sock_name_format, bold=True) + " (Press CTRL+C to quit)" + logger_args = [self.uds] + elif self.fd is not None: # pragma: py-win32 + sock = socket.fromfd(self.fd, socket.AF_UNIX, socket.SOCK_STREAM) + message = "Uvicorn running on socket %s (Press CTRL+C to quit)" + fd_name_format = "%s" + color_message = "Uvicorn running on " + style(fd_name_format, bold=True) + " (Press CTRL+C to quit)" + logger_args = [sock.getsockname()] + else: + family = socket.AF_INET + addr_format = "%s://%s:%d" + + if self.host and ":" in self.host: # pragma: full coverage + # It's an IPv6 address. + family = socket.AF_INET6 + addr_format = "%s://[%s]:%d" + + sock = socket.socket(family=family) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + try: + sock.bind((self.host, self.port)) + except OSError as exc: # pragma: full coverage + logger.error(exc) + sys.exit(STARTUP_FAILURE) + + message = f"Uvicorn running on {addr_format} (Press CTRL+C to quit)" + color_message = "Uvicorn running on " + style(addr_format, bold=True) + " (Press CTRL+C to quit)" + protocol_name = "https" if self.is_ssl else "http" + logger_args = [protocol_name, self.host, sock.getsockname()[1]] + logger.info(message, *logger_args, extra={"color_message": color_message}) + sock.set_inheritable(True) + return sock + + @property + def should_reload(self) -> bool: + return isinstance(self.app, str) and self.reload diff --git a/.venv/Lib/site-packages/uvicorn/importer.py b/.venv/Lib/site-packages/uvicorn/importer.py new file mode 100644 index 0000000000000000000000000000000000000000..f77520ee106deeedee30a48005479806ff9a19e2 --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/importer.py @@ -0,0 +1,34 @@ +import importlib +from typing import Any + + +class ImportFromStringError(Exception): + pass + + +def import_from_string(import_str: Any) -> Any: + if not isinstance(import_str, str): + return import_str + + module_str, _, attrs_str = import_str.partition(":") + if not module_str or not attrs_str: + message = 'Import string "{import_str}" must be in format ":".' + raise ImportFromStringError(message.format(import_str=import_str)) + + try: + module = importlib.import_module(module_str) + except ModuleNotFoundError as exc: + if exc.name != module_str: + raise exc from None + message = 'Could not import module "{module_str}".' + raise ImportFromStringError(message.format(module_str=module_str)) + + instance = module + try: + for attr_str in attrs_str.split("."): + instance = getattr(instance, attr_str) + except AttributeError: + message = 'Attribute "{attrs_str}" not found in module "{module_str}".' + raise ImportFromStringError(message.format(attrs_str=attrs_str, module_str=module_str)) + + return instance diff --git a/.venv/Lib/site-packages/uvicorn/lifespan/__init__.py b/.venv/Lib/site-packages/uvicorn/lifespan/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/.venv/Lib/site-packages/uvicorn/lifespan/off.py b/.venv/Lib/site-packages/uvicorn/lifespan/off.py new file mode 100644 index 0000000000000000000000000000000000000000..74554b1e2a149c37131168fbe283f3e2476a8f75 --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/lifespan/off.py @@ -0,0 +1,17 @@ +from __future__ import annotations + +from typing import Any + +from uvicorn import Config + + +class LifespanOff: + def __init__(self, config: Config) -> None: + self.should_exit = False + self.state: dict[str, Any] = {} + + async def startup(self) -> None: + pass + + async def shutdown(self) -> None: + pass diff --git a/.venv/Lib/site-packages/uvicorn/lifespan/on.py b/.venv/Lib/site-packages/uvicorn/lifespan/on.py new file mode 100644 index 0000000000000000000000000000000000000000..71ac39472e9e07025f25c62b074b1d44df39cf8e --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/lifespan/on.py @@ -0,0 +1,137 @@ +from __future__ import annotations + +import asyncio +import logging +from asyncio import Queue +from typing import Any + +from uvicorn import Config +from uvicorn._types import ( + LifespanScope, + LifespanShutdownCompleteEvent, + LifespanShutdownEvent, + LifespanShutdownFailedEvent, + LifespanStartupCompleteEvent, + LifespanStartupEvent, + LifespanStartupFailedEvent, +) + +LifespanReceiveMessage = LifespanStartupEvent | LifespanShutdownEvent +LifespanSendMessage = ( + LifespanStartupFailedEvent + | LifespanShutdownFailedEvent + | LifespanStartupCompleteEvent + | LifespanShutdownCompleteEvent +) + + +STATE_TRANSITION_ERROR = "Got invalid state transition on lifespan protocol." + + +class LifespanOn: + def __init__(self, config: Config) -> None: + if not config.loaded: + config.load() + + self.config = config + self.logger = logging.getLogger("uvicorn.error") + self.startup_event = asyncio.Event() + self.shutdown_event = asyncio.Event() + self.receive_queue: Queue[LifespanReceiveMessage] = asyncio.Queue() + self.error_occurred = False + self.startup_failed = False + self.shutdown_failed = False + self.should_exit = False + self.state: dict[str, Any] = {} + + async def startup(self) -> None: + self.logger.info("Waiting for application startup.") + + loop = asyncio.get_event_loop() + main_lifespan_task = loop.create_task(self.main()) # noqa: F841 + # Keep a hard reference to prevent garbage collection + # See https://github.com/Kludex/uvicorn/pull/972 + startup_event: LifespanStartupEvent = {"type": "lifespan.startup"} + await self.receive_queue.put(startup_event) + await self.startup_event.wait() + + if self.startup_failed or (self.error_occurred and self.config.lifespan == "on"): + self.logger.error("Application startup failed. Exiting.") + self.should_exit = True + else: + self.logger.info("Application startup complete.") + + async def shutdown(self) -> None: + if self.error_occurred: + return + self.logger.info("Waiting for application shutdown.") + shutdown_event: LifespanShutdownEvent = {"type": "lifespan.shutdown"} + await self.receive_queue.put(shutdown_event) + await self.shutdown_event.wait() + + if self.shutdown_failed or (self.error_occurred and self.config.lifespan == "on"): + self.logger.error("Application shutdown failed. Exiting.") + self.should_exit = True + else: + self.logger.info("Application shutdown complete.") + + async def main(self) -> None: + try: + app = self.config.loaded_app + scope: LifespanScope = { + "type": "lifespan", + "asgi": {"version": self.config.asgi_version, "spec_version": "2.0"}, + "state": self.state, + } + await app(scope, self.receive, self.send) + except BaseException as exc: + self.asgi = None + self.error_occurred = True + if self.startup_failed or self.shutdown_failed: + return + if self.config.lifespan == "auto": + msg = "ASGI 'lifespan' protocol appears unsupported." + self.logger.info(msg) + else: + msg = "Exception in 'lifespan' protocol\n" + self.logger.error(msg, exc_info=exc) + finally: + self.startup_event.set() + self.shutdown_event.set() + + async def send(self, message: LifespanSendMessage) -> None: + assert message["type"] in ( + "lifespan.startup.complete", + "lifespan.startup.failed", + "lifespan.shutdown.complete", + "lifespan.shutdown.failed", + ) + + if message["type"] == "lifespan.startup.complete": + assert not self.startup_event.is_set(), STATE_TRANSITION_ERROR + assert not self.shutdown_event.is_set(), STATE_TRANSITION_ERROR + self.startup_event.set() + + elif message["type"] == "lifespan.startup.failed": + assert not self.startup_event.is_set(), STATE_TRANSITION_ERROR + assert not self.shutdown_event.is_set(), STATE_TRANSITION_ERROR + self.startup_event.set() + self.startup_failed = True + if message.get("message"): + self.logger.error(message["message"]) + + elif message["type"] == "lifespan.shutdown.complete": + assert self.startup_event.is_set(), STATE_TRANSITION_ERROR + assert not self.shutdown_event.is_set(), STATE_TRANSITION_ERROR + self.shutdown_event.set() + + elif message["type"] == "lifespan.shutdown.failed": + assert self.startup_event.is_set(), STATE_TRANSITION_ERROR + assert not self.shutdown_event.is_set(), STATE_TRANSITION_ERROR + self.shutdown_event.set() + self.shutdown_failed = True + if message.get("message"): + self.logger.error(message["message"]) + + async def receive(self) -> LifespanReceiveMessage: + return await self.receive_queue.get() diff --git a/.venv/Lib/site-packages/uvicorn/logging.py b/.venv/Lib/site-packages/uvicorn/logging.py new file mode 100644 index 0000000000000000000000000000000000000000..28c65fcd16e6c96a9e63e0e9e978b7908a8a1904 --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/logging.py @@ -0,0 +1,117 @@ +from __future__ import annotations + +import http +import logging +import sys +from copy import copy +from typing import Literal + +from uvicorn._ansi import style as ansi_style + +TRACE_LOG_LEVEL = 5 + + +class ColourizedFormatter(logging.Formatter): + """ + A custom log formatter class that: + + * Outputs the LOG_LEVEL with an appropriate color. + * If a log call includes an `extra={"color_message": ...}` it will be used + for formatting the output, instead of the plain text message. + """ + + level_name_colors = { + TRACE_LOG_LEVEL: lambda level_name: ansi_style(str(level_name), fg="blue"), + logging.DEBUG: lambda level_name: ansi_style(str(level_name), fg="cyan"), + logging.INFO: lambda level_name: ansi_style(str(level_name), fg="green"), + logging.WARNING: lambda level_name: ansi_style(str(level_name), fg="yellow"), + logging.ERROR: lambda level_name: ansi_style(str(level_name), fg="red"), + logging.CRITICAL: lambda level_name: ansi_style(str(level_name), fg="bright_red"), + } + + def __init__( + self, + fmt: str | None = None, + datefmt: str | None = None, + style: Literal["%", "{", "$"] = "%", + use_colors: bool | None = None, + ): + if use_colors in (True, False): + self.use_colors = use_colors + else: + self.use_colors = sys.stdout.isatty() + super().__init__(fmt=fmt, datefmt=datefmt, style=style) + + def color_level_name(self, level_name: str, level_no: int) -> str: + def default(level_name: str) -> str: + return str(level_name) # pragma: no cover + + func = self.level_name_colors.get(level_no, default) + return func(level_name) + + def should_use_colors(self) -> bool: + return True # pragma: no cover + + def formatMessage(self, record: logging.LogRecord) -> str: + recordcopy = copy(record) + levelname = recordcopy.levelname + separator = " " * (8 - len(recordcopy.levelname)) + if self.use_colors: + levelname = self.color_level_name(levelname, recordcopy.levelno) + if "color_message" in recordcopy.__dict__: + recordcopy.msg = recordcopy.__dict__["color_message"] + recordcopy.__dict__["message"] = recordcopy.getMessage() + recordcopy.__dict__["levelprefix"] = levelname + ":" + separator + return super().formatMessage(recordcopy) + + +class DefaultFormatter(ColourizedFormatter): + def should_use_colors(self) -> bool: + return sys.stderr.isatty() # pragma: no cover + + +class AccessFormatter(ColourizedFormatter): + status_code_colours = { + 1: lambda code: ansi_style(str(code), fg="bright_white"), + 2: lambda code: ansi_style(str(code), fg="green"), + 3: lambda code: ansi_style(str(code), fg="yellow"), + 4: lambda code: ansi_style(str(code), fg="red"), + 5: lambda code: ansi_style(str(code), fg="bright_red"), + } + + def get_status_code(self, status_code: int) -> str: + try: + status_phrase = http.HTTPStatus(status_code).phrase + except ValueError: + status_phrase = "" + status_and_phrase = f"{status_code} {status_phrase}" + if self.use_colors: + + def default(code: int) -> str: + return status_and_phrase # pragma: no cover + + func = self.status_code_colours.get(status_code // 100, default) + return func(status_and_phrase) + return status_and_phrase + + def formatMessage(self, record: logging.LogRecord) -> str: + recordcopy = copy(record) + ( + client_addr, + method, + full_path, + http_version, + status_code, + ) = recordcopy.args # type: ignore[misc] + status_code = self.get_status_code(int(status_code)) # type: ignore[arg-type] + request_line = f"{method} {full_path} HTTP/{http_version}" + if self.use_colors: + request_line = ansi_style(request_line, bold=True) + recordcopy.__dict__.update( + { + "client_addr": client_addr, + "request_line": request_line, + "status_code": status_code, + } + ) + return super().formatMessage(recordcopy) diff --git a/.venv/Lib/site-packages/uvicorn/loops/__init__.py b/.venv/Lib/site-packages/uvicorn/loops/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/.venv/Lib/site-packages/uvicorn/loops/asyncio.py b/.venv/Lib/site-packages/uvicorn/loops/asyncio.py new file mode 100644 index 0000000000000000000000000000000000000000..ad6121ee086b0c3b2fc2cb8dd378134725c1edf6 --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/loops/asyncio.py @@ -0,0 +1,11 @@ +from __future__ import annotations + +import asyncio +import sys +from collections.abc import Callable + + +def asyncio_loop_factory(use_subprocess: bool = False) -> Callable[[], asyncio.AbstractEventLoop]: + if sys.platform == "win32" and not use_subprocess: + return asyncio.ProactorEventLoop + return asyncio.SelectorEventLoop diff --git a/.venv/Lib/site-packages/uvicorn/loops/auto.py b/.venv/Lib/site-packages/uvicorn/loops/auto.py new file mode 100644 index 0000000000000000000000000000000000000000..190839905566f0c0e59c6119604887c326078115 --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/loops/auto.py @@ -0,0 +1,17 @@ +from __future__ import annotations + +import asyncio +from collections.abc import Callable + + +def auto_loop_factory(use_subprocess: bool = False) -> Callable[[], asyncio.AbstractEventLoop]: + try: + import uvloop # noqa + except ImportError: # pragma: no cover + from uvicorn.loops.asyncio import asyncio_loop_factory as loop_factory + + return loop_factory(use_subprocess=use_subprocess) + else: # pragma: no cover + from uvicorn.loops.uvloop import uvloop_loop_factory + + return uvloop_loop_factory(use_subprocess=use_subprocess) diff --git a/.venv/Lib/site-packages/uvicorn/loops/uvloop.py b/.venv/Lib/site-packages/uvicorn/loops/uvloop.py new file mode 100644 index 0000000000000000000000000000000000000000..c6692c58f5c63501b2ad0f3d3c1d6b2336d88aad --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/loops/uvloop.py @@ -0,0 +1,10 @@ +from __future__ import annotations + +import asyncio +from collections.abc import Callable + +import uvloop + + +def uvloop_loop_factory(use_subprocess: bool = False) -> Callable[[], asyncio.AbstractEventLoop]: + return uvloop.new_event_loop diff --git a/.venv/Lib/site-packages/uvicorn/main.py b/.venv/Lib/site-packages/uvicorn/main.py new file mode 100644 index 0000000000000000000000000000000000000000..3ac7816364b4f7af09290aa9d0c5e5b29c2a63c0 --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/main.py @@ -0,0 +1,645 @@ +from __future__ import annotations + +import asyncio +import logging +import os +import platform +import ssl +import sys +import warnings +from collections.abc import Callable +from configparser import RawConfigParser +from typing import IO, Any, get_args + +import click + +import uvicorn +from uvicorn._types import ASGIApplication +from uvicorn.config import ( + INTERFACES, + LIFESPAN, + LOG_LEVELS, + LOGGING_CONFIG, + SSL_PROTOCOL_VERSION, + STARTUP_FAILURE, + Config, + HTTPProtocolType, + InterfaceType, + LifespanType, + LoopFactoryType, + WSProtocolType, +) +from uvicorn.server import Server +from uvicorn.supervisors import ChangeReload, Multiprocess + +LEVEL_CHOICES = click.Choice(list(LOG_LEVELS.keys())) +LIFESPAN_CHOICES = click.Choice(list(LIFESPAN.keys())) +INTERFACE_CHOICES = click.Choice(INTERFACES) + + +def _metavar_from_type(_type: Any) -> str: + return f"[{'|'.join(key for key in get_args(_type) if key != 'none')}]" + + +logger = logging.getLogger("uvicorn.error") + + +def print_version(ctx: click.Context, param: click.Parameter, value: bool) -> None: + if not value or ctx.resilient_parsing: + return + click.echo( + "Running uvicorn {version} with {py_implementation} {py_version} on {system}".format( # noqa: UP032 + version=uvicorn.__version__, + py_implementation=platform.python_implementation(), + py_version=platform.python_version(), + system=platform.system(), + ) + ) + ctx.exit() + + +@click.command(context_settings={"auto_envvar_prefix": "UVICORN"}) +@click.argument("app", envvar="UVICORN_APP") +@click.option( + "--host", + type=str, + default="127.0.0.1", + help="Bind socket to this host.", + show_default=True, +) +@click.option( + "--port", + type=int, + default=8000, + help="Bind socket to this port. If 0, an available port will be picked.", + show_default=True, +) +@click.option("--uds", type=str, default=None, help="Bind to a UNIX domain socket.") +@click.option("--fd", type=int, default=None, help="Bind to socket from this file descriptor.") +@click.option("--reload", is_flag=True, default=False, help="Enable auto-reload.") +@click.option( + "--reload-dir", + "reload_dirs", + multiple=True, + help="Set reload directories explicitly, instead of using the current working directory.", + type=click.Path(exists=True), +) +@click.option( + "--reload-include", + "reload_includes", + multiple=True, + help="Set glob patterns to include while watching for files. Includes '*.py' " + "by default; these defaults can be overridden with `--reload-exclude`. " + "This option has no effect unless watchfiles is installed.", +) +@click.option( + "--reload-exclude", + "reload_excludes", + multiple=True, + help="Set glob patterns to exclude while watching for files. Includes " + "'.*, .py[cod], .sw.*, ~*' by default; these defaults can be overridden " + "with `--reload-include`. This option has no effect unless watchfiles is " + "installed.", +) +@click.option( + "--reload-delay", + type=float, + default=0.25, + show_default=True, + help="Delay between previous and next check if application needs to be. Defaults to 0.25s.", +) +@click.option( + "--workers", + default=None, + type=int, + help="Number of worker processes. Defaults to the $WEB_CONCURRENCY environment" + " variable if available, or 1. Not valid with --reload.", +) +@click.option( + "--loop", + type=str, + metavar=_metavar_from_type(LoopFactoryType), + default="auto", + help="Event loop factory implementation.", + show_default=True, +) +@click.option( + "--http", + type=str, + metavar=_metavar_from_type(HTTPProtocolType), + default="auto", + help="HTTP protocol implementation.", + show_default=True, +) +@click.option( + "--ws", + type=str, + metavar=_metavar_from_type(WSProtocolType), + default="auto", + help="WebSocket protocol implementation.", + show_default=True, +) +@click.option( + "--ws-max-size", + type=int, + default=16777216, + help="WebSocket max size message in bytes", + show_default=True, +) +@click.option( + "--ws-max-queue", + type=int, + default=32, + help="The maximum length of the WebSocket message queue.", + show_default=True, +) +@click.option( + "--ws-ping-interval", + type=float, + default=20.0, + help="WebSocket ping interval in seconds.", + show_default=True, +) +@click.option( + "--ws-ping-timeout", + type=float, + default=20.0, + help="WebSocket ping timeout in seconds.", + show_default=True, +) +@click.option( + "--ws-per-message-deflate", + type=bool, + default=True, + help="WebSocket per-message-deflate compression", + show_default=True, +) +@click.option( + "--lifespan", + type=LIFESPAN_CHOICES, + default="auto", + help="Lifespan implementation.", + show_default=True, +) +@click.option( + "--interface", + type=INTERFACE_CHOICES, + default="auto", + help="Select ASGI3, ASGI2, or WSGI as the application interface.", + show_default=True, +) +@click.option( + "--env-file", + type=click.Path(exists=True), + default=None, + help="Environment configuration file.", + show_default=True, +) +@click.option( + "--log-config", + type=click.Path(exists=True), + default=None, + help="Logging configuration file. Supported formats: .ini, .json, .yaml.", + show_default=True, +) +@click.option( + "--log-level", + type=LEVEL_CHOICES, + default=None, + help="Log level. [default: info]", + show_default=True, +) +@click.option( + "--access-log/--no-access-log", + is_flag=True, + default=True, + help="Enable/Disable access log.", +) +@click.option( + "--use-colors/--no-use-colors", + is_flag=True, + default=None, + help="Enable/Disable colorized logging.", +) +@click.option( + "--proxy-headers/--no-proxy-headers", + is_flag=True, + default=True, + help="Enable/Disable X-Forwarded-Proto, X-Forwarded-For to populate url scheme and remote address info.", +) +@click.option( + "--server-header/--no-server-header", + is_flag=True, + default=True, + help="Enable/Disable default Server header.", +) +@click.option( + "--date-header/--no-date-header", + is_flag=True, + default=True, + help="Enable/Disable default Date header.", +) +@click.option( + "--forwarded-allow-ips", + type=str, + default=None, + help="Comma separated list of IP Addresses, IP Networks, or literals " + "(e.g. UNIX Socket path) to trust with proxy headers. Defaults to the " + "$FORWARDED_ALLOW_IPS environment variable if available, or '127.0.0.1'. " + "The literal '*' means trust everything.", +) +@click.option( + "--root-path", + type=str, + default="", + help="Set the ASGI 'root_path' for applications submounted below a given URL path.", +) +@click.option( + "--limit-concurrency", + type=int, + default=None, + help="Maximum number of concurrent connections or tasks to allow, before issuing HTTP 503 responses.", +) +@click.option( + "--backlog", + type=int, + default=2048, + help="Maximum number of connections to hold in backlog", +) +@click.option( + "--limit-max-requests", + type=int, + default=None, + help="Maximum number of requests to service before terminating the process.", +) +@click.option( + "--limit-max-requests-jitter", + type=int, + default=0, + help="Maximum jitter to add to limit_max_requests." + " Staggers worker restarts to avoid all workers restarting simultaneously.", + show_default=True, +) +@click.option( + "--timeout-keep-alive", + type=int, + default=5, + help="Close Keep-Alive connections if no new data is received within this timeout (in seconds).", + show_default=True, +) +@click.option( + "--timeout-graceful-shutdown", + type=int, + default=None, + help="Maximum number of seconds to wait for graceful shutdown.", +) +@click.option( + "--timeout-worker-healthcheck", + type=int, + default=5, + help="Maximum number of seconds to wait for a worker to respond to a healthcheck.", + show_default=True, +) +@click.option("--ssl-keyfile", type=str, default=None, help="SSL key file", show_default=True) +@click.option( + "--ssl-certfile", + type=str, + default=None, + help="SSL certificate file", + show_default=True, +) +@click.option( + "--ssl-keyfile-password", + type=str, + default=None, + help="SSL keyfile password", + show_default=True, +) +@click.option( + "--ssl-version", + type=int, + default=int(SSL_PROTOCOL_VERSION), + help="SSL version to use (see stdlib ssl module's)", + show_default=True, +) +@click.option( + "--ssl-cert-reqs", + type=int, + default=int(ssl.CERT_NONE), + help="Whether client certificate is required (see stdlib ssl module's)", + show_default=True, +) +@click.option( + "--ssl-ca-certs", + type=str, + default=None, + help="CA certificates file", + show_default=True, +) +@click.option( + "--ssl-ciphers", + type=str, + default=None, + help="Ciphers to use (see stdlib ssl module's). Defaults to OpenSSL's safe defaults.", + show_default=True, +) +@click.option( + "--header", + "headers", + multiple=True, + help="Specify custom default HTTP response headers as a Name:Value pair", +) +@click.option( + "--version", + is_flag=True, + callback=print_version, + expose_value=False, + is_eager=True, + help="Display the uvicorn version and exit.", +) +@click.option( + "--app-dir", + default="", + show_default=True, + help="Look for APP in the specified directory, by adding this to the PYTHONPATH." + " Defaults to the current working directory.", +) +@click.option( + "--h11-max-incomplete-event-size", + "h11_max_incomplete_event_size", + type=int, + default=None, + help="For h11, the maximum number of bytes to buffer of an incomplete event.", +) +@click.option( + "--reset-contextvars", + is_flag=True, + default=False, + help="Run each ASGI request in a fresh contextvars.Context. Hides context set in the lifespan.", + show_default=True, +) +@click.option( + "--factory", + is_flag=True, + default=False, + help="Treat APP as an application factory, i.e. a () -> callable.", + show_default=True, +) +def main( + app: str, + host: str, + port: int, + uds: str, + fd: int, + loop: LoopFactoryType | str, + http: HTTPProtocolType | str, + ws: WSProtocolType | str, + ws_max_size: int, + ws_max_queue: int, + ws_ping_interval: float, + ws_ping_timeout: float, + ws_per_message_deflate: bool, + lifespan: LifespanType, + interface: InterfaceType, + reload: bool, + reload_dirs: list[str], + reload_includes: list[str], + reload_excludes: list[str], + reload_delay: float, + workers: int, + env_file: str, + log_config: str, + log_level: str, + access_log: bool, + proxy_headers: bool, + server_header: bool, + date_header: bool, + forwarded_allow_ips: str, + root_path: str, + limit_concurrency: int, + backlog: int, + limit_max_requests: int, + limit_max_requests_jitter: int, + timeout_keep_alive: int, + timeout_graceful_shutdown: int | None, + timeout_worker_healthcheck: int, + ssl_keyfile: str, + ssl_certfile: str, + ssl_keyfile_password: str, + ssl_version: int, + ssl_cert_reqs: int, + ssl_ca_certs: str, + ssl_ciphers: str | None, + headers: list[str], + use_colors: bool, + app_dir: str, + h11_max_incomplete_event_size: int | None, + reset_contextvars: bool, + factory: bool, +) -> None: + run( + app, + host=host, + port=port, + uds=uds, + fd=fd, + loop=loop, + http=http, + ws=ws, + ws_max_size=ws_max_size, + ws_max_queue=ws_max_queue, + ws_ping_interval=ws_ping_interval, + ws_ping_timeout=ws_ping_timeout, + ws_per_message_deflate=ws_per_message_deflate, + lifespan=lifespan, + env_file=env_file, + log_config=LOGGING_CONFIG if log_config is None else log_config, + log_level=log_level, + access_log=access_log, + interface=interface, + reload=reload, + reload_dirs=reload_dirs or None, + reload_includes=reload_includes or None, + reload_excludes=reload_excludes or None, + reload_delay=reload_delay, + workers=workers, + proxy_headers=proxy_headers, + server_header=server_header, + date_header=date_header, + forwarded_allow_ips=forwarded_allow_ips, + root_path=root_path, + limit_concurrency=limit_concurrency, + backlog=backlog, + limit_max_requests=limit_max_requests, + limit_max_requests_jitter=limit_max_requests_jitter, + timeout_keep_alive=timeout_keep_alive, + timeout_graceful_shutdown=timeout_graceful_shutdown, + timeout_worker_healthcheck=timeout_worker_healthcheck, + ssl_keyfile=ssl_keyfile, + ssl_certfile=ssl_certfile, + ssl_keyfile_password=ssl_keyfile_password, + ssl_version=ssl_version, + ssl_cert_reqs=ssl_cert_reqs, + ssl_ca_certs=ssl_ca_certs, + ssl_ciphers=ssl_ciphers, + headers=[header.split(":", 1) for header in headers], # type: ignore[misc] + use_colors=use_colors, + factory=factory, + app_dir=app_dir, + h11_max_incomplete_event_size=h11_max_incomplete_event_size, + reset_contextvars=reset_contextvars, + ) + + +def run( + app: ASGIApplication | Callable[..., Any] | str, + *, + host: str = "127.0.0.1", + port: int = 8000, + uds: str | None = None, + fd: int | None = None, + loop: LoopFactoryType | str = "auto", + http: type[asyncio.Protocol] | HTTPProtocolType | str = "auto", + ws: type[asyncio.Protocol] | WSProtocolType | str = "auto", + ws_max_size: int = 16777216, + ws_max_queue: int = 32, + ws_ping_interval: float | None = 20.0, + ws_ping_timeout: float | None = 20.0, + ws_per_message_deflate: bool = True, + lifespan: LifespanType = "auto", + interface: InterfaceType = "auto", + reload: bool = False, + reload_dirs: list[str] | str | None = None, + reload_includes: list[str] | str | None = None, + reload_excludes: list[str] | str | None = None, + reload_delay: float = 0.25, + workers: int | None = None, + env_file: str | os.PathLike[str] | None = None, + log_config: dict[str, Any] | str | os.PathLike[str] | RawConfigParser | IO[Any] | None = LOGGING_CONFIG, + log_level: str | int | None = None, + access_log: bool = True, + proxy_headers: bool = True, + server_header: bool = True, + date_header: bool = True, + forwarded_allow_ips: list[str] | str | None = None, + root_path: str = "", + limit_concurrency: int | None = None, + backlog: int = 2048, + limit_max_requests: int | None = None, + limit_max_requests_jitter: int = 0, + timeout_keep_alive: int = 5, + timeout_graceful_shutdown: int | None = None, + timeout_worker_healthcheck: int = 5, + ssl_keyfile: str | os.PathLike[str] | None = None, + ssl_certfile: str | os.PathLike[str] | None = None, + ssl_keyfile_password: str | None = None, + ssl_version: int = SSL_PROTOCOL_VERSION, + ssl_cert_reqs: int = ssl.CERT_NONE, + ssl_ca_certs: str | os.PathLike[str] | None = None, + ssl_ciphers: str | None = None, + ssl_context_factory: Callable[[Config, Callable[[], ssl.SSLContext]], ssl.SSLContext] | None = None, + headers: list[tuple[str, str]] | None = None, + use_colors: bool | None = None, + app_dir: str | None = None, + factory: bool = False, + h11_max_incomplete_event_size: int | None = None, + reset_contextvars: bool = False, +) -> None: + if app_dir is not None: + sys.path.insert(0, app_dir) + + config = Config( + app, + host=host, + port=port, + uds=uds, + fd=fd, + loop=loop, + http=http, + ws=ws, + ws_max_size=ws_max_size, + ws_max_queue=ws_max_queue, + ws_ping_interval=ws_ping_interval, + ws_ping_timeout=ws_ping_timeout, + ws_per_message_deflate=ws_per_message_deflate, + lifespan=lifespan, + interface=interface, + reload=reload, + reload_dirs=reload_dirs, + reload_includes=reload_includes, + reload_excludes=reload_excludes, + reload_delay=reload_delay, + workers=workers, + env_file=env_file, + log_config=log_config, + log_level=log_level, + access_log=access_log, + proxy_headers=proxy_headers, + server_header=server_header, + date_header=date_header, + forwarded_allow_ips=forwarded_allow_ips, + root_path=root_path, + limit_concurrency=limit_concurrency, + backlog=backlog, + limit_max_requests=limit_max_requests, + limit_max_requests_jitter=limit_max_requests_jitter, + timeout_keep_alive=timeout_keep_alive, + timeout_graceful_shutdown=timeout_graceful_shutdown, + timeout_worker_healthcheck=timeout_worker_healthcheck, + ssl_keyfile=ssl_keyfile, + ssl_certfile=ssl_certfile, + ssl_keyfile_password=ssl_keyfile_password, + ssl_version=ssl_version, + ssl_cert_reqs=ssl_cert_reqs, + ssl_ca_certs=ssl_ca_certs, + ssl_ciphers=ssl_ciphers, + ssl_context_factory=ssl_context_factory, + headers=headers, + use_colors=use_colors, + factory=factory, + h11_max_incomplete_event_size=h11_max_incomplete_event_size, + reset_contextvars=reset_contextvars, + ) + if config.reload or config.workers > 1: + if not isinstance(app, str): + logger = logging.getLogger("uvicorn.error") + logger.warning("You must pass the application as an import string to enable 'reload' or 'workers'.") + sys.exit(STARTUP_FAILURE) + else: + config.load_app() + + server = Server(config=config) + + try: + if config.should_reload: + sock = config.bind_socket() + ChangeReload(config, target=server.run, sockets=[sock]).run() + elif config.workers > 1: + sock = config.bind_socket() + Multiprocess(config, sockets=[sock]).run() + else: + server.run() + except KeyboardInterrupt: # pragma: full coverage + pass + finally: + if config.uds and os.path.exists(config.uds): + os.remove(config.uds) # pragma: py-win32 + + if not server.started and not config.should_reload and config.workers == 1: + sys.exit(STARTUP_FAILURE) + + +def __getattr__(name: str) -> Any: + if name == "ServerState": + warnings.warn( + "uvicorn.main.ServerState is deprecated, use uvicorn.server.ServerState instead.", + DeprecationWarning, + ) + from uvicorn.server import ServerState + + return ServerState + raise AttributeError(f"module {__name__} has no attribute {name}") + + +if __name__ == "__main__": + main() # pragma: no cover diff --git a/.venv/Lib/site-packages/uvicorn/middleware/__init__.py b/.venv/Lib/site-packages/uvicorn/middleware/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/.venv/Lib/site-packages/uvicorn/middleware/asgi2.py b/.venv/Lib/site-packages/uvicorn/middleware/asgi2.py new file mode 100644 index 0000000000000000000000000000000000000000..4e15d1599bab04ac38f56cf271d2ff9b1b9984c8 --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/middleware/asgi2.py @@ -0,0 +1,15 @@ +from uvicorn._types import ( + ASGI2Application, + ASGIReceiveCallable, + ASGISendCallable, + Scope, +) + + +class ASGI2Middleware: + def __init__(self, app: "ASGI2Application"): + self.app = app + + async def __call__(self, scope: "Scope", receive: "ASGIReceiveCallable", send: "ASGISendCallable") -> None: + instance = self.app(scope) + await instance(receive, send) diff --git a/.venv/Lib/site-packages/uvicorn/middleware/message_logger.py b/.venv/Lib/site-packages/uvicorn/middleware/message_logger.py new file mode 100644 index 0000000000000000000000000000000000000000..0174bcce6d48de946214d59bcae5543d38d89c3a --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/middleware/message_logger.py @@ -0,0 +1,87 @@ +import logging +from typing import Any + +from uvicorn._types import ( + ASGI3Application, + ASGIReceiveCallable, + ASGIReceiveEvent, + ASGISendCallable, + ASGISendEvent, + WWWScope, +) +from uvicorn.logging import TRACE_LOG_LEVEL + +PLACEHOLDER_FORMAT = { + "body": "<{length} bytes>", + "bytes": "<{length} bytes>", + "text": "<{length} chars>", + "headers": "<...>", +} + + +def message_with_placeholders(message: Any) -> Any: + """ + Return an ASGI message, with any body-type content omitted and replaced + with a placeholder. + """ + new_message = message.copy() + for attr in PLACEHOLDER_FORMAT.keys(): + if message.get(attr) is not None: + content = message[attr] + placeholder = PLACEHOLDER_FORMAT[attr].format(length=len(content)) + new_message[attr] = placeholder + return new_message + + +class MessageLoggerMiddleware: + def __init__(self, app: "ASGI3Application"): + self.task_counter = 0 + self.app = app + self.logger = logging.getLogger("uvicorn.asgi") + + def trace(message: Any, *args: Any, **kwargs: Any) -> None: + self.logger.log(TRACE_LOG_LEVEL, message, *args, **kwargs) + + self.logger.trace = trace # type: ignore + + async def __call__( + self, + scope: "WWWScope", + receive: "ASGIReceiveCallable", + send: "ASGISendCallable", + ) -> None: + self.task_counter += 1 + + task_counter = self.task_counter + client = scope.get("client") + prefix = "%s:%d - ASGI" % (client[0], client[1]) if client else "ASGI" + + async def inner_receive() -> "ASGIReceiveEvent": + message = await receive() + logged_message = message_with_placeholders(message) + log_text = "%s [%d] Receive %s" + self.logger.trace( # type: ignore + log_text, prefix, task_counter, logged_message + ) + return message + + async def inner_send(message: "ASGISendEvent") -> None: + logged_message = message_with_placeholders(message) + log_text = "%s [%d] Send %s" + self.logger.trace( # type: ignore + log_text, prefix, task_counter, logged_message + ) + await send(message) + + logged_scope = message_with_placeholders(scope) + log_text = "%s [%d] Started scope=%s" + self.logger.trace(log_text, prefix, task_counter, logged_scope) # type: ignore + try: + await self.app(scope, inner_receive, inner_send) + except BaseException as exc: + log_text = "%s [%d] Raised exception" + self.logger.trace(log_text, prefix, task_counter) # type: ignore + raise exc from None + else: + log_text = "%s [%d] Completed" + self.logger.trace(log_text, prefix, task_counter) # type: ignore diff --git a/.venv/Lib/site-packages/uvicorn/middleware/proxy_headers.py b/.venv/Lib/site-packages/uvicorn/middleware/proxy_headers.py new file mode 100644 index 0000000000000000000000000000000000000000..ebd210c4381cb64192a2fca139f5434838d56df5 --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/middleware/proxy_headers.py @@ -0,0 +1,187 @@ +from __future__ import annotations + +import functools +import ipaddress + +from uvicorn._types import ASGI3Application, ASGIReceiveCallable, ASGISendCallable, Scope + + +class ProxyHeadersMiddleware: + """Middleware for handling known proxy headers + + This middleware can be used when a known proxy is fronting the application, + and is trusted to be properly setting the `X-Forwarded-Proto` and + `X-Forwarded-For` headers with the connecting client information. + + Modifies the `client` and `scheme` information so that they reference + the connecting client, rather that the connecting proxy. + + References: + - + - + """ + + def __init__(self, app: ASGI3Application, trusted_hosts: list[str] | str = "127.0.0.1") -> None: + self.app = app + self.trusted_hosts = _TrustedHosts(trusted_hosts) + + async def __call__(self, scope: Scope, receive: ASGIReceiveCallable, send: ASGISendCallable) -> None: + if scope["type"] == "lifespan": + return await self.app(scope, receive, send) + + client_addr = scope.get("client") + client_host = client_addr[0] if client_addr else None + + if client_host in self.trusted_hosts: + x_forwarded_proto_value: bytes | None = None + x_forwarded_for_values: list[bytes] = [] + for name, value in scope["headers"]: + if name == b"x-forwarded-proto": + x_forwarded_proto_value = value + elif name == b"x-forwarded-for": + x_forwarded_for_values.append(value) + + if x_forwarded_proto_value is not None: + x_forwarded_proto = x_forwarded_proto_value.decode("latin1").strip() + + if x_forwarded_proto in {"http", "https", "ws", "wss"}: + if scope["type"] == "websocket": + scope["scheme"] = x_forwarded_proto.replace("http", "ws") + else: + scope["scheme"] = x_forwarded_proto + + if x_forwarded_for_values: + x_forwarded_for = b", ".join(x_forwarded_for_values).decode("latin1") + host, port = self.trusted_hosts.get_trusted_client_address(x_forwarded_for) + + if host: + # If the x-forwarded-for header is empty then host is an empty string. + # Only set the client if we actually got something usable. + # See: https://github.com/Kludex/uvicorn/issues/1068 + scope["client"] = (host, port) + + return await self.app(scope, receive, send) + + +def _parse_raw_hosts(value: str) -> list[str]: + return [item.strip() for item in value.split(",")] + + +def _parse_host_port(value: str) -> tuple[str, int]: + """Parse a forwarded host value into host and optional port. + + Accepts bare IPs, IPv4 `host:port`, and bracketed IPv6 `[host]:port`. + Any unrecognized or malformed value is treated conservatively and returned + without a port so trust checks do not silently normalize arbitrary input. + """ + + if value.startswith("["): + bracket_end = value.find("]") + if bracket_end == -1: + return value, 0 + + host = value[1:bracket_end] + remainder = value[bracket_end + 1 :] + if not remainder: + return host, 0 + if not remainder.startswith(":"): + return value, 0 + + try: + return host, int(remainder[1:]) + except ValueError: + return host, 0 + + if value.count(":") == 1: + host, port = value.rsplit(":", 1) + try: + return host, int(port) + except ValueError: + return value, 0 + + return value, 0 + + +class _TrustedHosts: + """Container for trusted hosts and networks""" + + def __init__(self, trusted_hosts: list[str] | str) -> None: + self.always_trust: bool = trusted_hosts in ("*", ["*"]) + + self.trusted_literals: set[str] = set() + self.trusted_hosts: set[ipaddress.IPv4Address | ipaddress.IPv6Address] = set() + self.trusted_networks: set[ipaddress.IPv4Network | ipaddress.IPv6Network] = set() + + # Notes: + # - We separate hosts from literals as there are many ways to write + # an IPv6 Address so we need to compare by object. + # - We don't convert IP Address to single host networks (e.g. /32 / 128) as + # it more efficient to do an address lookup in a set than check for + # membership in each network. + # - We still allow literals as it might be possible that we receive a + # something that isn't an IP Address e.g. a unix socket. + + if not self.always_trust: + if isinstance(trusted_hosts, str): + trusted_hosts = _parse_raw_hosts(trusted_hosts) + + for host in trusted_hosts: + # Note: because we always convert invalid IP types to literals it + # is not possible for the user to know they provided a malformed IP + # type - this may lead to unexpected / difficult to debug behaviour. + + if "/" in host: + # Looks like a network + try: + self.trusted_networks.add(ipaddress.ip_network(host)) + except ValueError: + # Was not a valid IP Network + self.trusted_literals.add(host) + else: + try: + self.trusted_hosts.add(ipaddress.ip_address(host)) + except ValueError: + # Was not a valid IP Address + self.trusted_literals.add(host) + + self._trusts = functools.lru_cache(maxsize=4096)(self._compute_trust) + + def __contains__(self, host: str | None) -> bool: + if self.always_trust: + return True + + if not host: + return False + + # Don't cache hosts longer than a DNS name (253); they can't be trusted and would pin huge cache keys. + if len(host) > 253: + return self._compute_trust(host) # pragma: no cover + + return self._trusts(host) + + def _compute_trust(self, host: str) -> bool: + try: + ip = ipaddress.ip_address(host) + return ip in self.trusted_hosts or any(ip in net for net in self.trusted_networks) + except ValueError: + return host in self.trusted_literals + + def get_trusted_client_address(self, x_forwarded_for: str) -> tuple[str, int]: + """Extract the client address from x_forwarded_for header. + + In general this is the first "untrusted" host in the forwarded for list. + """ + x_forwarded_for_hosts = _parse_raw_hosts(x_forwarded_for) + + if self.always_trust: + return _parse_host_port(x_forwarded_for_hosts[0]) + + # Note: each proxy appends to the header list so check it in reverse order + for host_port in reversed(x_forwarded_for_hosts): + host, port = _parse_host_port(host_port) + if host not in self: + return host, port + + # All hosts are trusted meaning that the client was also a trusted proxy + # See https://github.com/Kludex/uvicorn/issues/1068#issuecomment-855371576 + return _parse_host_port(x_forwarded_for_hosts[0]) diff --git a/.venv/Lib/site-packages/uvicorn/middleware/wsgi.py b/.venv/Lib/site-packages/uvicorn/middleware/wsgi.py new file mode 100644 index 0000000000000000000000000000000000000000..b2e3cb77d421085947741430e8b5451821eb66c7 --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/middleware/wsgi.py @@ -0,0 +1,199 @@ +from __future__ import annotations + +import asyncio +import concurrent.futures +import io +import sys +import warnings +from collections import deque +from collections.abc import Iterable + +from uvicorn._types import ( + ASGIReceiveCallable, + ASGIReceiveEvent, + ASGISendCallable, + ASGISendEvent, + Environ, + ExcInfo, + HTTPRequestEvent, + HTTPResponseBodyEvent, + HTTPResponseStartEvent, + HTTPScope, + StartResponse, + WSGIApp, +) + + +def build_environ(scope: HTTPScope, message: ASGIReceiveEvent, body: io.BytesIO) -> Environ: + """ + Builds a scope and request message into a WSGI environ object. + """ + script_name = scope.get("root_path", "").encode("utf8").decode("latin1") + path_info = scope["path"].encode("utf8").decode("latin1") + if path_info.startswith(script_name): + path_info = path_info[len(script_name) :] + environ = { + "REQUEST_METHOD": scope["method"], + "SCRIPT_NAME": script_name, + "PATH_INFO": path_info, + "QUERY_STRING": scope["query_string"].decode("ascii"), + "SERVER_PROTOCOL": "HTTP/%s" % scope["http_version"], + "wsgi.version": (1, 0), + "wsgi.url_scheme": scope.get("scheme", "http"), + "wsgi.input": body, + "wsgi.errors": sys.stdout, + "wsgi.multithread": True, + "wsgi.multiprocess": True, + "wsgi.run_once": False, + } + + # Get server name and port - required in WSGI, not in ASGI + server = scope.get("server") + if server is None: + server = ("localhost", 80) + environ["SERVER_NAME"] = server[0] + environ["SERVER_PORT"] = server[1] + + # Get client IP address + client = scope.get("client") + if client is not None: + environ["REMOTE_ADDR"] = client[0] + + # Go through headers and make them into environ entries + for name, value in scope.get("headers", []): + name_str: str = name.decode("latin1") + if name_str == "content-length": + corrected_name = "CONTENT_LENGTH" + elif name_str == "content-type": + corrected_name = "CONTENT_TYPE" + else: + corrected_name = "HTTP_%s" % name_str.upper().replace("-", "_") + # HTTPbis say only ASCII chars are allowed in headers, but we latin1 + # just in case + value_str: str = value.decode("latin1") + if corrected_name in environ: + corrected_name_environ = environ[corrected_name] + assert isinstance(corrected_name_environ, str) + value_str = corrected_name_environ + "," + value_str + environ[corrected_name] = value_str + return environ + + +class _WSGIMiddleware: + def __init__(self, app: WSGIApp, workers: int = 10): + warnings.warn( + "Uvicorn's native WSGI implementation is deprecated, you should switch to a2wsgi (`pip install a2wsgi`).", + DeprecationWarning, + ) + self.app = app + self.executor = concurrent.futures.ThreadPoolExecutor(max_workers=workers) + + async def __call__( + self, + scope: HTTPScope, + receive: ASGIReceiveCallable, + send: ASGISendCallable, + ) -> None: + assert scope["type"] == "http" + instance = WSGIResponder(self.app, self.executor, scope) + await instance(receive, send) + + +class WSGIResponder: + def __init__( + self, + app: WSGIApp, + executor: concurrent.futures.ThreadPoolExecutor, + scope: HTTPScope, + ): + self.app = app + self.executor = executor + self.scope = scope + self.status = None + self.response_headers = None + self.send_event = asyncio.Event() + self.send_queue: deque[ASGISendEvent | None] = deque() + self.loop: asyncio.AbstractEventLoop = asyncio.get_event_loop() + self.response_started = False + self.exc_info: ExcInfo | None = None + + async def __call__(self, receive: ASGIReceiveCallable, send: ASGISendCallable) -> None: + message: HTTPRequestEvent = await receive() # type: ignore[assignment] + body = io.BytesIO(message.get("body", b"")) + more_body = message.get("more_body", False) + if more_body: + body.seek(0, io.SEEK_END) + while more_body: + body_message: HTTPRequestEvent = ( + await receive() # type: ignore[assignment] + ) + body.write(body_message.get("body", b"")) + more_body = body_message.get("more_body", False) + body.seek(0) + environ = build_environ(self.scope, message, body) + self.loop = asyncio.get_event_loop() + wsgi = self.loop.run_in_executor(self.executor, self.wsgi, environ, self.start_response) + sender = self.loop.create_task(self.sender(send)) + try: + await asyncio.wait_for(wsgi, None) + finally: + self.send_queue.append(None) + self.send_event.set() + await asyncio.wait_for(sender, None) + if self.exc_info is not None: + raise self.exc_info[0].with_traceback(self.exc_info[1], self.exc_info[2]) + + async def sender(self, send: ASGISendCallable) -> None: + while True: + if self.send_queue: + message = self.send_queue.popleft() + if message is None: + return + await send(message) + else: # pragma: no cover + await self.send_event.wait() + self.send_event.clear() + + def start_response( + self, + status: str, + response_headers: Iterable[tuple[str, str]], + exc_info: ExcInfo | None = None, + ) -> None: + self.exc_info = exc_info + if not self.response_started: + self.response_started = True + status_code_str, _ = status.split(" ", 1) + status_code = int(status_code_str) + headers = [(name.encode("ascii"), value.encode("ascii")) for name, value in response_headers] + http_response_start_event: HTTPResponseStartEvent = { + "type": "http.response.start", + "status": status_code, + "headers": headers, + } + self.send_queue.append(http_response_start_event) + self.loop.call_soon_threadsafe(self.send_event.set) + + def wsgi(self, environ: Environ, start_response: StartResponse) -> None: + for chunk in self.app(environ, start_response): # type: ignore + response_body: HTTPResponseBodyEvent = { + "type": "http.response.body", + "body": chunk, + "more_body": True, + } + self.send_queue.append(response_body) + self.loop.call_soon_threadsafe(self.send_event.set) + + empty_body: HTTPResponseBodyEvent = { + "type": "http.response.body", + "body": b"", + "more_body": False, + } + self.send_queue.append(empty_body) + self.loop.call_soon_threadsafe(self.send_event.set) + + +try: + from a2wsgi import WSGIMiddleware +except ModuleNotFoundError: # pragma: no cover + WSGIMiddleware = _WSGIMiddleware # type: ignore[misc, assignment] diff --git a/.venv/Lib/site-packages/uvicorn/protocols/__init__.py b/.venv/Lib/site-packages/uvicorn/protocols/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/.venv/Lib/site-packages/uvicorn/protocols/http/__init__.py b/.venv/Lib/site-packages/uvicorn/protocols/http/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/.venv/Lib/site-packages/uvicorn/protocols/http/auto.py b/.venv/Lib/site-packages/uvicorn/protocols/http/auto.py new file mode 100644 index 0000000000000000000000000000000000000000..a14bec144a97a5e3718a768abe3b6a9e7e93d2c1 --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/protocols/http/auto.py @@ -0,0 +1,15 @@ +from __future__ import annotations + +import asyncio + +AutoHTTPProtocol: type[asyncio.Protocol] +try: + import httptools # noqa +except ImportError: # pragma: no cover + from uvicorn.protocols.http.h11_impl import H11Protocol + + AutoHTTPProtocol = H11Protocol +else: # pragma: no cover + from uvicorn.protocols.http.httptools_impl import HttpToolsProtocol + + AutoHTTPProtocol = HttpToolsProtocol diff --git a/.venv/Lib/site-packages/uvicorn/protocols/http/flow_control.py b/.venv/Lib/site-packages/uvicorn/protocols/http/flow_control.py new file mode 100644 index 0000000000000000000000000000000000000000..2d1b5fa2d3366fd6584181a26c8569a0207900cc --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/protocols/http/flow_control.py @@ -0,0 +1,54 @@ +import asyncio + +from uvicorn._types import ASGIReceiveCallable, ASGISendCallable, Scope + +CLOSE_HEADER = (b"connection", b"close") + +HIGH_WATER_LIMIT = 65536 + + +class FlowControl: + def __init__(self, transport: asyncio.Transport) -> None: + self._transport = transport + self.read_paused = False + self.write_paused = False + self._is_writable_event = asyncio.Event() + self._is_writable_event.set() + + async def drain(self) -> None: + await self._is_writable_event.wait() # pragma: full coverage + + def pause_reading(self) -> None: + if not self.read_paused: + self.read_paused = True + self._transport.pause_reading() + + def resume_reading(self) -> None: + if self.read_paused: + self.read_paused = False + self._transport.resume_reading() + + def pause_writing(self) -> None: + if not self.write_paused: # pragma: full coverage + self.write_paused = True + self._is_writable_event.clear() + + def resume_writing(self) -> None: + if self.write_paused: # pragma: full coverage + self.write_paused = False + self._is_writable_event.set() + + +async def service_unavailable(scope: Scope, receive: ASGIReceiveCallable, send: ASGISendCallable) -> None: + await send( + { + "type": "http.response.start", + "status": 503, + "headers": [ + (b"content-type", b"text/plain; charset=utf-8"), + (b"content-length", b"19"), + (b"connection", b"close"), + ], + } + ) + await send({"type": "http.response.body", "body": b"Service Unavailable", "more_body": False}) diff --git a/.venv/Lib/site-packages/uvicorn/protocols/http/h11_impl.py b/.venv/Lib/site-packages/uvicorn/protocols/http/h11_impl.py new file mode 100644 index 0000000000000000000000000000000000000000..ed7951b8e8ee339dcd88f51ae294115cc79cb986 --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/protocols/http/h11_impl.py @@ -0,0 +1,545 @@ +from __future__ import annotations + +import asyncio +import contextvars +import http +import logging +import sys +from collections.abc import Callable +from typing import Any, Literal +from urllib.parse import unquote + +import h11 +from h11._connection import DEFAULT_MAX_INCOMPLETE_EVENT_SIZE + +from uvicorn._types import ( + ASGI3Application, + ASGIReceiveEvent, + ASGISendEvent, + HTTPRequestEvent, + HTTPResponseBodyEvent, + HTTPResponseStartEvent, + HTTPScope, +) +from uvicorn.config import Config +from uvicorn.logging import TRACE_LOG_LEVEL +from uvicorn.protocols.http.flow_control import CLOSE_HEADER, HIGH_WATER_LIMIT, FlowControl, service_unavailable +from uvicorn.protocols.utils import get_client_addr, get_local_addr, get_path_with_query_string, get_remote_addr, is_ssl +from uvicorn.server import ServerState + + +def _get_status_phrase(status_code: int) -> bytes: + try: + return http.HTTPStatus(status_code).phrase.encode() + except ValueError: + return b"" + + +STATUS_PHRASES = {status_code: _get_status_phrase(status_code) for status_code in range(100, 600)} + + +class H11Protocol(asyncio.Protocol): + def __init__( + self, + config: Config, + server_state: ServerState, + app_state: dict[str, Any], + _loop: asyncio.AbstractEventLoop | None = None, + ) -> None: + if not config.loaded: + config.load() + + self.config = config + self.app = config.loaded_app + self.loop = _loop or asyncio.get_event_loop() + self.logger = logging.getLogger("uvicorn.error") + self.access_logger = logging.getLogger("uvicorn.access") + self.access_log = self.access_logger.hasHandlers() + self.conn = h11.Connection( + h11.SERVER, + config.h11_max_incomplete_event_size + if config.h11_max_incomplete_event_size is not None + else DEFAULT_MAX_INCOMPLETE_EVENT_SIZE, + ) + self.ws_protocol_class = config.ws_protocol_class + self.root_path = config.root_path + self.asgi_version = config.asgi_version + self.limit_concurrency = config.limit_concurrency + self.app_state = app_state + + # Timeouts + self.timeout_keep_alive_task: asyncio.TimerHandle | None = None + self.timeout_keep_alive = config.timeout_keep_alive + + # Shared server state + self.server_state = server_state + self.connections = server_state.connections + self.tasks = server_state.tasks + + # Per-connection state + self.transport: asyncio.Transport = None # type: ignore[assignment] + self.flow: FlowControl = None # type: ignore[assignment] + self.server: tuple[str, int | None] | None = None + self.client: tuple[str, int] | None = None + self.scheme: Literal["http", "https"] | None = None + + # Per-request state + self.scope: HTTPScope = None # type: ignore[assignment] + self.headers: list[tuple[bytes, bytes]] = None # type: ignore[assignment] + self.cycle: RequestResponseCycle = None # type: ignore[assignment] + + # Protocol interface + def connection_made( # type: ignore[override] + self, transport: asyncio.Transport + ) -> None: + self.connections.add(self) + + self.transport = transport + self.flow = FlowControl(transport) + self.server = get_local_addr(transport) + self.client = get_remote_addr(transport) + self.scheme = "https" if is_ssl(transport) else "http" + + if self.logger.level <= TRACE_LOG_LEVEL: + prefix = "%s:%d - " % self.client if self.client else "" + self.logger.log(TRACE_LOG_LEVEL, "%sHTTP connection made", prefix) + + def connection_lost(self, exc: Exception | None) -> None: + self.connections.discard(self) + + if self.logger.level <= TRACE_LOG_LEVEL: + prefix = "%s:%d - " % self.client if self.client else "" + self.logger.log(TRACE_LOG_LEVEL, "%sHTTP connection lost", prefix) + + if self.cycle and not self.cycle.response_complete: + self.cycle.disconnected = True + if self.conn.our_state != h11.ERROR: + event = h11.ConnectionClosed() + try: + self.conn.send(event) + except h11.LocalProtocolError: + # Premature client disconnect + pass + + if self.cycle is not None: + self.cycle.message_event.set() + if self.flow is not None: + self.flow.resume_writing() + if exc is None: + self.transport.close() + self._unset_keepalive_if_required() + + def eof_received(self) -> None: + pass + + def _unset_keepalive_if_required(self) -> None: + if self.timeout_keep_alive_task is not None: + self.timeout_keep_alive_task.cancel() + self.timeout_keep_alive_task = None + + def _get_upgrade(self) -> bytes | None: + connection = [] + upgrade = None + for name, value in self.headers: + if name == b"connection": + connection = [token.lower().strip() for token in value.split(b",")] + if name == b"upgrade": + upgrade = value.lower() + if b"upgrade" in connection: + return upgrade + return None + + def _should_upgrade_to_ws(self) -> bool: + if self.ws_protocol_class is None: + return False + return True + + def _unsupported_upgrade_warning(self) -> None: + msg = "Unsupported upgrade request." + self.logger.warning(msg) + if not self._should_upgrade_to_ws(): + msg = "No supported WebSocket library detected. Please use \"pip install 'uvicorn[standard]'\", or install 'websockets' or 'wsproto' manually." # noqa: E501 + self.logger.warning(msg) + + def _should_upgrade(self) -> bool: + upgrade = self._get_upgrade() + if upgrade == b"websocket" and self._should_upgrade_to_ws(): + return True + if upgrade is not None: + self._unsupported_upgrade_warning() + return False + + def data_received(self, data: bytes) -> None: + self._unset_keepalive_if_required() + + self.conn.receive_data(data) + self.handle_events() + + def handle_events(self) -> None: + while True: + try: + event = self.conn.next_event() + except h11.RemoteProtocolError: + msg = "Invalid HTTP request received." + self.logger.warning(msg) + self.send_400_response(msg) + return + + if event is h11.NEED_DATA: + break + + elif event is h11.PAUSED: + # This case can occur in HTTP pipelining, so we need to + # stop reading any more data, and ensure that at the end + # of the active request/response cycle we handle any + # events that have been buffered up. + self.flow.pause_reading() + break + + elif isinstance(event, h11.Request): + self.headers = [(key.lower(), value) for key, value in event.headers] + raw_path, _, query_string = event.target.partition(b"?") + path = unquote(raw_path.decode("ascii")) + full_path = self.root_path + path + full_raw_path = self.root_path.encode("ascii") + raw_path + self.scope = { + "type": "http", + "asgi": {"version": self.asgi_version, "spec_version": "2.3"}, + "http_version": event.http_version.decode("ascii"), + "server": self.server, + "client": self.client, + "scheme": self.scheme, # type: ignore[typeddict-item] + "method": event.method.decode("ascii"), + "root_path": self.root_path, + "path": full_path, + "raw_path": full_raw_path, + "query_string": query_string, + "headers": self.headers, + "state": self.app_state.copy(), + } + if self._should_upgrade(): + self.handle_websocket_upgrade(event) + return + + # Handle 503 responses when 'limit_concurrency' is exceeded. + if self.limit_concurrency is not None and ( + len(self.connections) >= self.limit_concurrency or len(self.tasks) >= self.limit_concurrency + ): + app = service_unavailable + message = "Exceeded concurrency limit." + self.logger.warning(message) + else: + app = self.app + + # When starting to process a request, disable the keep-alive + # timeout. Normally we disable this when receiving data from + # client and set back when finishing processing its request. + # However, for pipelined requests processing finishes after + # already receiving the next request and thus the timer may + # be set here, which we don't want. + self._unset_keepalive_if_required() + + self.cycle = RequestResponseCycle( + scope=self.scope, + conn=self.conn, + transport=self.transport, + flow=self.flow, + logger=self.logger, + access_logger=self.access_logger, + access_log=self.access_log, + default_headers=self.server_state.default_headers, + message_event=asyncio.Event(), + on_response=self.on_response_complete, + ) + if self.config.reset_contextvars: + # Opt-in workaround for https://github.com/python/cpython/issues/140947: + # asyncio can leak context vars between tasks. Hides context set in the + # lifespan or by external instrumentation. + if sys.version_info >= (3, 11): # pragma: py-lt-311 + task = self.loop.create_task(self.cycle.run_asgi(app), context=contextvars.Context()) + else: # pragma: py-gte-311 + task = contextvars.Context().run(self.loop.create_task, self.cycle.run_asgi(app)) + else: + task = self.loop.create_task(self.cycle.run_asgi(app)) + task.add_done_callback(self.tasks.discard) + self.tasks.add(task) + + elif isinstance(event, h11.Data): + if self.conn.our_state is h11.DONE: + continue + self.cycle.body += event.data + if len(self.cycle.body) > HIGH_WATER_LIMIT: + self.flow.pause_reading() + self.cycle.message_event.set() + + elif isinstance(event, h11.EndOfMessage): + if self.conn.our_state is h11.DONE: + self.transport.resume_reading() + self.conn.start_next_cycle() + continue + self.cycle.more_body = False + self.cycle.message_event.set() + if self.conn.their_state == h11.MUST_CLOSE: + break + + def handle_websocket_upgrade(self, event: h11.Request) -> None: + if self.logger.level <= TRACE_LOG_LEVEL: # pragma: full coverage + prefix = "%s:%d - " % self.client if self.client else "" + self.logger.log(TRACE_LOG_LEVEL, "%sUpgrading to WebSocket", prefix) + + self.connections.discard(self) + output = [event.method, b" ", event.target, b" HTTP/1.1\r\n"] + for name, value in self.headers: + output += [name, b": ", value, b"\r\n"] + output.append(b"\r\n") + protocol = self.ws_protocol_class( # type: ignore[call-arg, misc] + config=self.config, + server_state=self.server_state, + app_state=self.app_state, + ) + protocol.connection_made(self.transport) + protocol.data_received(b"".join(output)) + self.transport.set_protocol(protocol) + + def send_400_response(self, msg: str) -> None: + reason = STATUS_PHRASES[400] + headers: list[tuple[bytes, bytes]] = [ + (b"content-type", b"text/plain; charset=utf-8"), + (b"connection", b"close"), + ] + event = h11.Response(status_code=400, headers=headers, reason=reason) + output = self.conn.send(event) + self.transport.write(output) + + output = self.conn.send(event=h11.Data(data=msg.encode("ascii"))) + self.transport.write(output) + + output = self.conn.send(event=h11.EndOfMessage()) + self.transport.write(output) + + self.transport.close() + + def on_response_complete(self) -> None: + self.server_state.total_requests += 1 + + if self.transport.is_closing(): + return + + # Set a short Keep-Alive timeout. + self._unset_keepalive_if_required() + + self.timeout_keep_alive_task = self.loop.call_later(self.timeout_keep_alive, self.timeout_keep_alive_handler) + + # Unpause data reads if needed. + self.flow.resume_reading() + + # Unblock any pipelined events. + if self.conn.our_state is h11.DONE and self.conn.their_state is h11.DONE: + self.conn.start_next_cycle() + self.handle_events() + + def shutdown(self) -> None: + """ + Called by the server to commence a graceful shutdown. + """ + if self.cycle is None or self.cycle.response_complete: + event = h11.ConnectionClosed() + self.conn.send(event) + self.transport.close() + else: + self.cycle.keep_alive = False + + def pause_writing(self) -> None: + """ + Called by the transport when the write buffer exceeds the high water mark. + """ + self.flow.pause_writing() # pragma: full coverage + + def resume_writing(self) -> None: + """ + Called by the transport when the write buffer drops below the low water mark. + """ + self.flow.resume_writing() # pragma: full coverage + + def timeout_keep_alive_handler(self) -> None: + """ + Called on a keep-alive connection if no new data is received after a short + delay. + """ + if not self.transport.is_closing(): + event = h11.ConnectionClosed() + self.conn.send(event) + self.transport.close() + + +class RequestResponseCycle: + def __init__( + self, + scope: HTTPScope, + conn: h11.Connection, + transport: asyncio.Transport, + flow: FlowControl, + logger: logging.Logger, + access_logger: logging.Logger, + access_log: bool, + default_headers: list[tuple[bytes, bytes]], + message_event: asyncio.Event, + on_response: Callable[..., None], + ) -> None: + self.scope = scope + self.conn = conn + self.transport = transport + self.flow = flow + self.logger = logger + self.access_logger = access_logger + self.access_log = access_log + self.default_headers = default_headers + self.message_event = message_event + self.on_response = on_response + + # Connection state + self.disconnected = False + self.keep_alive = True + self.waiting_for_100_continue = conn.they_are_waiting_for_100_continue + + # Request state + self.body = bytearray() + self.more_body = True + + # Response state + self.response_started = False + self.response_complete = False + + # ASGI exception wrapper + async def run_asgi(self, app: ASGI3Application) -> None: + try: + result = await app( # type: ignore[func-returns-value] + self.scope, self.receive, self.send + ) + except BaseException as exc: + msg = "Exception in ASGI application\n" + self.logger.error(msg, exc_info=exc) + if not self.response_started: + await self.send_500_response() + else: + self.transport.close() + else: + if result is not None: + msg = "ASGI callable should return None, but returned '%s'." + self.logger.error(msg, result) + self.transport.close() + elif not self.response_started and not self.disconnected: + msg = "ASGI callable returned without starting response." + self.logger.error(msg) + await self.send_500_response() + elif not self.response_complete and not self.disconnected: + msg = "ASGI callable returned without completing response." + self.logger.error(msg) + self.transport.close() + finally: + self.on_response = lambda: None + + async def send_500_response(self) -> None: + response_start_event: HTTPResponseStartEvent = { + "type": "http.response.start", + "status": 500, + "headers": [ + (b"content-type", b"text/plain; charset=utf-8"), + (b"connection", b"close"), + ], + } + await self.send(response_start_event) + response_body_event: HTTPResponseBodyEvent = { + "type": "http.response.body", + "body": b"Internal Server Error", + "more_body": False, + } + await self.send(response_body_event) + + # ASGI interface + async def send(self, message: ASGISendEvent) -> None: + if self.flow.write_paused and not self.disconnected: + await self.flow.drain() # pragma: full coverage + + if self.disconnected: + return # pragma: full coverage + + if not self.response_started: + # Sending response status line and headers + if message["type"] != "http.response.start": + raise RuntimeError(f"Expected ASGI message 'http.response.start', but got '{message['type']}'.") + + self.response_started = True + self.waiting_for_100_continue = False + + status = message["status"] + headers = self.default_headers + list(message.get("headers", [])) + + if CLOSE_HEADER in self.scope["headers"] and CLOSE_HEADER not in headers: + headers = headers + [CLOSE_HEADER] + + if self.access_log: + self.access_logger.info( + '%s - "%s %s HTTP/%s" %d', + get_client_addr(self.scope), + self.scope["method"], + get_path_with_query_string(self.scope), + self.scope["http_version"], + status, + ) + + # Write response status line and headers + reason = STATUS_PHRASES[status] + response = h11.Response(status_code=status, headers=headers, reason=reason) + output = self.conn.send(event=response) + self.transport.write(output) + + elif not self.response_complete: + # Sending response body + if message["type"] != "http.response.body": + raise RuntimeError(f"Expected ASGI message 'http.response.body', but got '{message['type']}'.") + + body = message.get("body", b"") + more_body = message.get("more_body", False) + + # Write response body + data = b"" if self.scope["method"] == "HEAD" else body + output = self.conn.send(event=h11.Data(data=data)) + self.transport.write(output) + + # Handle response completion + if not more_body: + self.response_complete = True + self.message_event.set() + output = self.conn.send(event=h11.EndOfMessage()) + self.transport.write(output) + + else: + # Response already sent + raise RuntimeError(f"Unexpected ASGI message '{message['type']}' sent, after response already completed.") + + if self.response_complete: + if self.conn.our_state is h11.MUST_CLOSE or not self.keep_alive: + self.conn.send(event=h11.ConnectionClosed()) + self.transport.close() + self.on_response() + + async def receive(self) -> ASGIReceiveEvent: + if self.waiting_for_100_continue and not self.transport.is_closing(): + headers: list[tuple[str, str]] = [] + event = h11.InformationalResponse(status_code=100, headers=headers, reason="Continue") + output = self.conn.send(event=event) + self.transport.write(output) + self.waiting_for_100_continue = False + + if not self.disconnected and not self.response_complete: + self.flow.resume_reading() + await self.message_event.wait() + self.message_event.clear() + + if self.disconnected or self.response_complete: + return {"type": "http.disconnect"} + + message: HTTPRequestEvent = {"type": "http.request", "body": bytes(self.body), "more_body": self.more_body} + self.body = bytearray() + return message diff --git a/.venv/Lib/site-packages/uvicorn/protocols/http/httptools_impl.py b/.venv/Lib/site-packages/uvicorn/protocols/http/httptools_impl.py new file mode 100644 index 0000000000000000000000000000000000000000..66ee6c0435d50c0435699dd1e3261848f4413028 --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/protocols/http/httptools_impl.py @@ -0,0 +1,577 @@ +from __future__ import annotations + +import asyncio +import contextvars +import http +import logging +import re +import sys +import urllib +from asyncio.events import TimerHandle +from collections import deque +from collections.abc import Callable +from typing import Any, Literal + +import httptools + +from uvicorn._types import ( + ASGI3Application, + ASGIReceiveEvent, + ASGISendEvent, + HTTPRequestEvent, + HTTPScope, +) +from uvicorn.config import Config +from uvicorn.logging import TRACE_LOG_LEVEL +from uvicorn.protocols.http.flow_control import CLOSE_HEADER, HIGH_WATER_LIMIT, FlowControl, service_unavailable +from uvicorn.protocols.utils import get_client_addr, get_local_addr, get_path_with_query_string, get_remote_addr, is_ssl +from uvicorn.server import ServerState + +HEADER_RE = re.compile(b'[\x00-\x1f\x7f()<>@,;:\\[\\]={} \t\\\\"]') +HEADER_VALUE_RE = re.compile(b"[\x00-\x08\x0a-\x1f\x7f]") + + +def _get_status_line(status_code: int) -> bytes: + try: + phrase = http.HTTPStatus(status_code).phrase.encode() + except ValueError: + phrase = b"" + return b"".join([b"HTTP/1.1 ", str(status_code).encode(), b" ", phrase, b"\r\n"]) + + +STATUS_LINE = {status_code: _get_status_line(status_code) for status_code in range(100, 600)} + + +class HttpToolsProtocol(asyncio.Protocol): + def __init__( + self, + config: Config, + server_state: ServerState, + app_state: dict[str, Any], + _loop: asyncio.AbstractEventLoop | None = None, + ) -> None: + if not config.loaded: + config.load() + + self.config = config + self.app = config.loaded_app + self.loop = _loop or asyncio.get_event_loop() + self.logger = logging.getLogger("uvicorn.error") + self.access_logger = logging.getLogger("uvicorn.access") + self.access_log = self.access_logger.hasHandlers() + self.parser = httptools.HttpRequestParser(self) + + try: + # Enable dangerous leniencies to allow server to a response on the first request from a pipelined request. + self.parser.set_dangerous_leniencies(lenient_data_after_close=True) + except AttributeError: # pragma: no cover + # httptools < 0.6.3 + pass + + self.ws_protocol_class = config.ws_protocol_class + self.root_path = config.root_path + self.asgi_version = config.asgi_version + self.limit_concurrency = config.limit_concurrency + self.app_state = app_state + + # Timeouts + self.timeout_keep_alive_task: TimerHandle | None = None + self.timeout_keep_alive = config.timeout_keep_alive + + # Global state + self.server_state = server_state + self.connections = server_state.connections + self.tasks = server_state.tasks + + # Per-connection state + self.transport: asyncio.Transport = None # type: ignore[assignment] + self.flow: FlowControl = None # type: ignore[assignment] + self.server: tuple[str, int | None] | None = None + self.client: tuple[str, int] | None = None + self.scheme: Literal["http", "https"] | None = None + self.pipeline: deque[tuple[RequestResponseCycle, ASGI3Application]] = deque() + + # Per-request state + self.scope: HTTPScope = None # type: ignore[assignment] + self.headers: list[tuple[bytes, bytes]] = None # type: ignore[assignment] + self.expect_100_continue = False + self.cycle: RequestResponseCycle = None # type: ignore[assignment] + + # Protocol interface + def connection_made( # type: ignore[override] + self, transport: asyncio.Transport + ) -> None: + self.connections.add(self) + + self.transport = transport + self.flow = FlowControl(transport) + self.server = get_local_addr(transport) + self.client = get_remote_addr(transport) + self.scheme = "https" if is_ssl(transport) else "http" + + if self.logger.level <= TRACE_LOG_LEVEL: + prefix = "%s:%d - " % self.client if self.client else "" + self.logger.log(TRACE_LOG_LEVEL, "%sHTTP connection made", prefix) + + def connection_lost(self, exc: Exception | None) -> None: + self.connections.discard(self) + + if self.logger.level <= TRACE_LOG_LEVEL: + prefix = "%s:%d - " % self.client if self.client else "" + self.logger.log(TRACE_LOG_LEVEL, "%sHTTP connection lost", prefix) + + if self.cycle and not self.cycle.response_complete: + self.cycle.disconnected = True + if self.cycle is not None: + self.cycle.message_event.set() + if self.flow is not None: + self.flow.resume_writing() + if exc is None: + self.transport.close() + self._unset_keepalive_if_required() + + self.parser = None # type: ignore[assignment] + + def eof_received(self) -> None: + pass + + def _unset_keepalive_if_required(self) -> None: + if self.timeout_keep_alive_task is not None: + self.timeout_keep_alive_task.cancel() + self.timeout_keep_alive_task = None + + def _get_upgrade(self) -> bytes | None: + connection = [] + upgrade = None + for name, value in self.headers: + if name == b"connection": + connection = [token.lower().strip() for token in value.split(b",")] + if name == b"upgrade": + upgrade = value.lower() + if b"upgrade" in connection: + return upgrade + return None # pragma: full coverage + + def _should_upgrade_to_ws(self) -> bool: + if self.ws_protocol_class is None: + return False + return True + + def _unsupported_upgrade_warning(self) -> None: + self.logger.warning("Unsupported upgrade request.") + if not self._should_upgrade_to_ws(): + msg = "No supported WebSocket library detected. Please use \"pip install 'uvicorn[standard]'\", or install 'websockets' or 'wsproto' manually." # noqa: E501 + self.logger.warning(msg) + + def _should_upgrade(self) -> bool: + upgrade = self._get_upgrade() + return upgrade == b"websocket" and self._should_upgrade_to_ws() + + def data_received(self, data: bytes) -> None: + self._unset_keepalive_if_required() + + try: + self.parser.feed_data(data) + except httptools.HttpParserError: + msg = "Invalid HTTP request received." + self.logger.warning(msg) + self.send_400_response(msg) + return + except httptools.HttpParserUpgrade: + if self._should_upgrade(): + self.handle_websocket_upgrade() + else: + self._unsupported_upgrade_warning() + + def handle_websocket_upgrade(self) -> None: + if self.logger.level <= TRACE_LOG_LEVEL: + prefix = "%s:%d - " % self.client if self.client else "" + self.logger.log(TRACE_LOG_LEVEL, "%sUpgrading to WebSocket", prefix) + + self.connections.discard(self) + method = self.scope["method"].encode() + output = [method, b" ", self.url, b" HTTP/1.1\r\n"] + for name, value in self.scope["headers"]: + output += [name, b": ", value, b"\r\n"] + output.append(b"\r\n") + protocol = self.ws_protocol_class( # type: ignore[call-arg, misc] + config=self.config, + server_state=self.server_state, + app_state=self.app_state, + ) + protocol.connection_made(self.transport) + protocol.data_received(b"".join(output)) + self.transport.set_protocol(protocol) + + def send_400_response(self, msg: str) -> None: + content = [STATUS_LINE[400]] + for name, value in self.server_state.default_headers: + content.extend([name, b": ", value, b"\r\n"]) # pragma: full coverage + content.extend( + [ + b"content-type: text/plain; charset=utf-8\r\n", + b"content-length: " + str(len(msg)).encode("ascii") + b"\r\n", + b"connection: close\r\n", + b"\r\n", + msg.encode("ascii"), + ] + ) + self.transport.write(b"".join(content)) + self.transport.close() + + def on_message_begin(self) -> None: + self.url = b"" + self.expect_100_continue = False + self.headers = [] + self.scope = { # type: ignore[typeddict-item] + "type": "http", + "asgi": {"version": self.asgi_version, "spec_version": "2.3"}, + "http_version": "1.1", + "server": self.server, + "client": self.client, + "scheme": self.scheme, # type: ignore[typeddict-item] + "root_path": self.root_path, + "headers": self.headers, + "state": self.app_state.copy(), + } + + # Parser callbacks + def on_url(self, url: bytes) -> None: + self.url += url + + def on_header(self, name: bytes, value: bytes) -> None: + name = name.lower() + if name == b"expect" and value.lower() == b"100-continue": + self.expect_100_continue = True + self.headers.append((name, value)) + + def on_headers_complete(self) -> None: + http_version = self.parser.get_http_version() + method = self.parser.get_method() + self.scope["method"] = method.decode("ascii") + if http_version != "1.1": + self.scope["http_version"] = http_version + if self.parser.should_upgrade() and self._should_upgrade(): + return + parsed_url = httptools.parse_url(self.url) + raw_path = parsed_url.path + path = raw_path.decode("ascii") + if "%" in path: + path = urllib.parse.unquote(path) + full_path = self.root_path + path + full_raw_path = self.root_path.encode("ascii") + raw_path + self.scope["path"] = full_path + self.scope["raw_path"] = full_raw_path + self.scope["query_string"] = parsed_url.query or b"" + + # Handle 503 responses when 'limit_concurrency' is exceeded. + if self.limit_concurrency is not None and ( + len(self.connections) >= self.limit_concurrency or len(self.tasks) >= self.limit_concurrency + ): + app = service_unavailable + message = "Exceeded concurrency limit." + self.logger.warning(message) + else: + app = self.app + + existing_cycle = self.cycle + self.cycle = RequestResponseCycle( + scope=self.scope, + transport=self.transport, + flow=self.flow, + logger=self.logger, + access_logger=self.access_logger, + access_log=self.access_log, + default_headers=self.server_state.default_headers, + message_event=asyncio.Event(), + expect_100_continue=self.expect_100_continue, + keep_alive=http_version != "1.0", + on_response=self.on_response_complete, + ) + if existing_cycle is None or existing_cycle.response_complete: + # Standard case - start processing the request. + self._start_asgi_task(self.cycle, app) + else: + # Pipelined HTTP requests need to be queued up. + self.flow.pause_reading() + self.pipeline.appendleft((self.cycle, app)) + + def _start_asgi_task(self, cycle: RequestResponseCycle, app: ASGI3Application) -> None: + if self.config.reset_contextvars: + # Opt-in workaround for https://github.com/python/cpython/issues/140947: + # asyncio can leak context vars between tasks. Hides context set in the + # lifespan or by external instrumentation. + if sys.version_info >= (3, 11): # pragma: py-lt-311 + task = self.loop.create_task(cycle.run_asgi(app), context=contextvars.Context()) + else: # pragma: py-gte-311 + task = contextvars.Context().run(self.loop.create_task, cycle.run_asgi(app)) + else: + task = self.loop.create_task(cycle.run_asgi(app)) + task.add_done_callback(self.tasks.discard) + self.tasks.add(task) + + def on_body(self, body: bytes) -> None: + if (self.parser.should_upgrade() and self._should_upgrade()) or self.cycle.response_complete: + return + self.cycle.body += body + if len(self.cycle.body) > HIGH_WATER_LIMIT: + self.flow.pause_reading() + self.cycle.message_event.set() + + def on_message_complete(self) -> None: + if (self.parser.should_upgrade() and self._should_upgrade()) or self.cycle.response_complete: + return + self.cycle.more_body = False + self.cycle.message_event.set() + + def on_response_complete(self) -> None: + # Callback for pipelined HTTP requests to be started. + self.server_state.total_requests += 1 + + if self.transport.is_closing(): + return + + self._unset_keepalive_if_required() + + # Unpause data reads if needed. + self.flow.resume_reading() + + # Unblock any pipelined events. If there are none, arm the + # Keep-Alive timeout instead. + if self.pipeline: + cycle, app = self.pipeline.pop() + self._start_asgi_task(cycle, app) + else: + self.timeout_keep_alive_task = self.loop.call_later( + self.timeout_keep_alive, self.timeout_keep_alive_handler + ) + + def shutdown(self) -> None: + """ + Called by the server to commence a graceful shutdown. + """ + if self.cycle is None or self.cycle.response_complete: + self.transport.close() + else: + self.cycle.keep_alive = False + + def pause_writing(self) -> None: + """ + Called by the transport when the write buffer exceeds the high water mark. + """ + self.flow.pause_writing() # pragma: full coverage + + def resume_writing(self) -> None: + """ + Called by the transport when the write buffer drops below the low water mark. + """ + self.flow.resume_writing() # pragma: full coverage + + def timeout_keep_alive_handler(self) -> None: + """ + Called on a keep-alive connection if no new data is received after a short + delay. + """ + if not self.transport.is_closing(): + self.transport.close() + + +class RequestResponseCycle: + def __init__( + self, + scope: HTTPScope, + transport: asyncio.Transport, + flow: FlowControl, + logger: logging.Logger, + access_logger: logging.Logger, + access_log: bool, + default_headers: list[tuple[bytes, bytes]], + message_event: asyncio.Event, + expect_100_continue: bool, + keep_alive: bool, + on_response: Callable[..., None], + ): + self.scope = scope + self.transport = transport + self.flow = flow + self.logger = logger + self.access_logger = access_logger + self.access_log = access_log + self.default_headers = default_headers + self.message_event = message_event + self.on_response = on_response + + # Connection state + self.disconnected = False + self.keep_alive = keep_alive + self.waiting_for_100_continue = expect_100_continue + + # Request state + self.body = bytearray() + self.more_body = True + + # Response state + self.response_started = False + self.response_complete = False + self.chunked_encoding: bool | None = None + self.expected_content_length = 0 + + # ASGI exception wrapper + async def run_asgi(self, app: ASGI3Application) -> None: + try: + result = await app( # type: ignore[func-returns-value] + self.scope, self.receive, self.send + ) + except BaseException as exc: + msg = "Exception in ASGI application\n" + self.logger.error(msg, exc_info=exc) + if not self.response_started: + await self.send_500_response() + else: + self.transport.close() + else: + if result is not None: + msg = "ASGI callable should return None, but returned '%s'." + self.logger.error(msg, result) + self.transport.close() + elif not self.response_started and not self.disconnected: + msg = "ASGI callable returned without starting response." + self.logger.error(msg) + await self.send_500_response() + elif not self.response_complete and not self.disconnected: + msg = "ASGI callable returned without completing response." + self.logger.error(msg) + self.transport.close() + finally: + self.on_response = lambda: None + + async def send_500_response(self) -> None: + await self.send( + { + "type": "http.response.start", + "status": 500, + "headers": [ + (b"content-type", b"text/plain; charset=utf-8"), + (b"content-length", b"21"), + (b"connection", b"close"), + ], + } + ) + await self.send({"type": "http.response.body", "body": b"Internal Server Error", "more_body": False}) + + # ASGI interface + async def send(self, message: ASGISendEvent) -> None: + if self.flow.write_paused and not self.disconnected: + await self.flow.drain() # pragma: full coverage + + if self.disconnected: + return # pragma: full coverage + + if not self.response_started: + # Sending response status line and headers + if message["type"] != "http.response.start": + raise RuntimeError(f"Expected ASGI message 'http.response.start', but got '{message['type']}'.") + + self.response_started = True + self.waiting_for_100_continue = False + + status_code = message["status"] + headers = self.default_headers + list(message.get("headers", [])) + + if CLOSE_HEADER in self.scope["headers"] and CLOSE_HEADER not in headers: + headers = headers + [CLOSE_HEADER] + + if self.access_log: + self.access_logger.info( + '%s - "%s %s HTTP/%s" %d', + get_client_addr(self.scope), + self.scope["method"], + get_path_with_query_string(self.scope), + self.scope["http_version"], + status_code, + ) + + # Write response status line and headers + content = [STATUS_LINE[status_code]] + + for name, value in headers: + if HEADER_RE.search(name): + raise RuntimeError("Invalid HTTP header name.") # pragma: full coverage + if HEADER_VALUE_RE.search(value): + raise RuntimeError("Invalid HTTP header value.") + + name = name.lower() + if name == b"content-length" and self.chunked_encoding is None: + self.expected_content_length = int(value.decode()) + self.chunked_encoding = False + elif name == b"transfer-encoding" and value.lower() == b"chunked": + self.expected_content_length = 0 + self.chunked_encoding = True + elif name == b"connection" and value.lower() == b"close": + self.keep_alive = False + content.extend([name, b": ", value, b"\r\n"]) + + if self.chunked_encoding is None and self.scope["method"] != "HEAD" and status_code not in (204, 304): + # Neither content-length nor transfer-encoding specified + self.chunked_encoding = True + content.append(b"transfer-encoding: chunked\r\n") + + content.append(b"\r\n") + self.transport.write(b"".join(content)) + + elif not self.response_complete: + # Sending response body + if message["type"] != "http.response.body": + raise RuntimeError(f"Expected ASGI message 'http.response.body', but got '{message['type']}'.") + + body = message.get("body", b"") + more_body = message.get("more_body", False) + + # Write response body + if self.scope["method"] == "HEAD": + self.expected_content_length = 0 + elif self.chunked_encoding: + if body: + content = [b"%x\r\n" % len(body), body, b"\r\n"] + else: + content = [] + if not more_body: + content.append(b"0\r\n\r\n") + self.transport.write(b"".join(content)) + else: + num_bytes = len(body) + if num_bytes > self.expected_content_length: + raise RuntimeError("Response content longer than Content-Length") + else: + self.expected_content_length -= num_bytes + self.transport.write(body) + + # Handle response completion + if not more_body: + if self.expected_content_length != 0: + raise RuntimeError("Response content shorter than Content-Length") + self.response_complete = True + self.message_event.set() + if not self.keep_alive: + self.transport.close() + self.on_response() + + else: + # Response already sent + raise RuntimeError(f"Unexpected ASGI message '{message['type']}' sent, after response already completed.") + + async def receive(self) -> ASGIReceiveEvent: + if self.waiting_for_100_continue and not self.transport.is_closing(): + self.transport.write(b"HTTP/1.1 100 Continue\r\n\r\n") + self.waiting_for_100_continue = False + + if not self.disconnected and not self.response_complete: + self.flow.resume_reading() + await self.message_event.wait() + self.message_event.clear() + + if self.disconnected or self.response_complete: + return {"type": "http.disconnect"} + message: HTTPRequestEvent = {"type": "http.request", "body": bytes(self.body), "more_body": self.more_body} + self.body = bytearray() + return message diff --git a/.venv/Lib/site-packages/uvicorn/protocols/utils.py b/.venv/Lib/site-packages/uvicorn/protocols/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..a9a89065c70d7a7905d4b44bc3c385a492cc0d70 --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/protocols/utils.py @@ -0,0 +1,62 @@ +from __future__ import annotations + +import asyncio +import socket +import urllib.parse + +from uvicorn._types import WWWScope + + +class ClientDisconnected(OSError): ... + + +def get_remote_addr(transport: asyncio.Transport) -> tuple[str, int] | None: + socket_info: socket.socket | None = transport.get_extra_info("socket") + if socket_info is not None: + try: + info = socket_info.getpeername() + return (str(info[0]), int(info[1])) if isinstance(info, tuple) else None + except OSError: # pragma: no cover + # This case appears to inconsistently occur with uvloop + # bound to a unix domain socket. + return None + + info = transport.get_extra_info("peername") + if info is not None and isinstance(info, list | tuple) and len(info) == 2: + return (str(info[0]), int(info[1])) + return None + + +def get_local_addr(transport: asyncio.Transport) -> tuple[str, int | None] | None: + socket_info: socket.socket | None = transport.get_extra_info("socket") + if socket_info is not None: + info = socket_info.getsockname() + if isinstance(info, tuple): + return (str(info[0]), int(info[1])) + if isinstance(info, str): + return (info, None) + return None + info = transport.get_extra_info("sockname") + if info is not None and isinstance(info, list | tuple) and len(info) == 2: + return (str(info[0]), int(info[1])) + if isinstance(info, str): + return (info, None) + return None + + +def is_ssl(transport: asyncio.Transport) -> bool: + return bool(transport.get_extra_info("sslcontext")) + + +def get_client_addr(scope: WWWScope) -> str: + client = scope.get("client") + if not client: + return "" + return "%s:%d" % client + + +def get_path_with_query_string(scope: WWWScope) -> str: + path_with_query_string = urllib.parse.quote(scope["path"]) + if scope["query_string"]: + path_with_query_string = "{}?{}".format(path_with_query_string, scope["query_string"].decode("ascii")) + return path_with_query_string diff --git a/.venv/Lib/site-packages/uvicorn/protocols/websockets/__init__.py b/.venv/Lib/site-packages/uvicorn/protocols/websockets/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/.venv/Lib/site-packages/uvicorn/protocols/websockets/auto.py b/.venv/Lib/site-packages/uvicorn/protocols/websockets/auto.py new file mode 100644 index 0000000000000000000000000000000000000000..23db3d081e8fa93638797e55d60b880f81ad87ba --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/protocols/websockets/auto.py @@ -0,0 +1,21 @@ +from __future__ import annotations + +import asyncio +from collections.abc import Callable + +AutoWebSocketsProtocol: Callable[..., asyncio.Protocol] | None +try: + import websockets # noqa +except ImportError: # pragma: no cover + try: + import wsproto # noqa + except ImportError: + AutoWebSocketsProtocol = None + else: + from uvicorn.protocols.websockets.wsproto_impl import WSProtocol + + AutoWebSocketsProtocol = WSProtocol +else: + from uvicorn.protocols.websockets.websockets_sansio_impl import WebSocketsSansIOProtocol + + AutoWebSocketsProtocol = WebSocketsSansIOProtocol diff --git a/.venv/Lib/site-packages/uvicorn/protocols/websockets/websockets_impl.py b/.venv/Lib/site-packages/uvicorn/protocols/websockets/websockets_impl.py new file mode 100644 index 0000000000000000000000000000000000000000..7e50e4eb041c95245bda6333ff94c142edbe47e2 --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/protocols/websockets/websockets_impl.py @@ -0,0 +1,380 @@ +from __future__ import annotations + +import asyncio +import http +import logging +import warnings +from collections.abc import Sequence +from typing import Any, Literal, cast +from urllib.parse import unquote + +import websockets +import websockets.legacy.handshake +from websockets.datastructures import Headers +from websockets.exceptions import ConnectionClosed +from websockets.extensions.base import ServerExtensionFactory +from websockets.extensions.permessage_deflate import ServerPerMessageDeflateFactory +from websockets.legacy.server import HTTPResponse, WebSocketServerProtocol +from websockets.typing import Subprotocol + +from uvicorn._types import ( + ASGI3Application, + ASGISendEvent, + WebSocketConnectEvent, + WebSocketDisconnectEvent, + WebSocketReceiveEvent, + WebSocketScope, +) +from uvicorn.config import Config, UvicornDeprecationWarning +from uvicorn.logging import TRACE_LOG_LEVEL +from uvicorn.protocols.utils import ( + ClientDisconnected, + get_client_addr, + get_local_addr, + get_path_with_query_string, + get_remote_addr, + is_ssl, +) +from uvicorn.server import ServerState + +warnings.warn( + "The `websockets` implementation is deprecated, and `--ws websockets` will point at the " + "`websockets-sansio` implementation in a future release. " + "Use `--ws websockets-sansio` or `--ws auto` to switch now.", + UvicornDeprecationWarning, +) + + +class Server: + closing = False + + def register(self, ws: WebSocketServerProtocol) -> None: + pass + + def unregister(self, ws: WebSocketServerProtocol) -> None: + pass + + def is_serving(self) -> bool: + return not self.closing + + +class WebSocketProtocol(WebSocketServerProtocol): + extra_headers: list[tuple[str, str]] + logger: logging.Logger | logging.LoggerAdapter[Any] + + def __init__( + self, + config: Config, + server_state: ServerState, + app_state: dict[str, Any], + _loop: asyncio.AbstractEventLoop | None = None, + ): + if not config.loaded: + config.load() + + self.config = config + self.app = cast(ASGI3Application, config.loaded_app) + self.loop = _loop or asyncio.get_event_loop() + self.root_path = config.root_path + self.asgi_version = config.asgi_version + self.app_state = app_state + + # Shared server state + self.connections = server_state.connections + self.tasks = server_state.tasks + + # Connection state + self.transport: asyncio.Transport = None # type: ignore[assignment] + self.server: tuple[str, int | None] | None = None + self.client: tuple[str, int] | None = None + self.scheme: Literal["wss", "ws"] = None # type: ignore[assignment] + + # Connection events + self.scope: WebSocketScope + self.handshake_started_event = asyncio.Event() + self.handshake_completed_event = asyncio.Event() + self.closed_event = asyncio.Event() + self.initial_response: HTTPResponse | None = None + self.connect_sent = False + self.lost_connection_before_handshake = False + self.accepted_subprotocol: Subprotocol | None = None + + self.ws_server: Server = Server() # type: ignore[assignment] + + extensions: list[ServerExtensionFactory] = [] + if self.config.ws_per_message_deflate: + extensions.append(ServerPerMessageDeflateFactory()) + + super().__init__( + ws_handler=self.ws_handler, + ws_server=self.ws_server, # type: ignore[arg-type] + max_size=self.config.ws_max_size, + max_queue=self.config.ws_max_queue, + ping_interval=self.config.ws_ping_interval, + ping_timeout=self.config.ws_ping_timeout, + extensions=extensions, + logger=logging.getLogger("uvicorn.error"), + ) + self.server_header = None + self.extra_headers = [ + (name.decode("latin-1"), value.decode("latin-1")) for name, value in server_state.default_headers + ] + + def connection_made( # type: ignore[override] + self, transport: asyncio.Transport + ) -> None: + self.connections.add(self) + self.transport = transport + self.server = get_local_addr(transport) + self.client = get_remote_addr(transport) + self.scheme = "wss" if is_ssl(transport) else "ws" + + if self.logger.isEnabledFor(TRACE_LOG_LEVEL): + prefix = "%s:%d - " % self.client if self.client else "" + self.logger.log(TRACE_LOG_LEVEL, "%sWebSocket connection made", prefix) + + super().connection_made(transport) + + def connection_lost(self, exc: Exception | None) -> None: + self.connections.remove(self) + + if self.logger.isEnabledFor(TRACE_LOG_LEVEL): + prefix = "%s:%d - " % self.client if self.client else "" + self.logger.log(TRACE_LOG_LEVEL, "%sWebSocket connection lost", prefix) + + self.lost_connection_before_handshake = not self.handshake_completed_event.is_set() + self.handshake_completed_event.set() + super().connection_lost(exc) + if exc is None: + self.transport.close() + + def shutdown(self) -> None: + self.ws_server.closing = True + if self.handshake_completed_event.is_set(): + self.fail_connection(1012) + else: + self.send_500_response() + self.transport.close() + + def on_task_complete(self, task: asyncio.Task[None]) -> None: + self.tasks.discard(task) + + async def process_request(self, path: str, request_headers: Headers) -> HTTPResponse | None: + """ + This hook is called to determine if the websocket should return + an HTTP response and close. + + Our behavior here is to start the ASGI application, and then wait + for either `accept` or `close` in order to determine if we should + close the connection. + """ + path_portion, _, query_string = path.partition("?") + + websockets.legacy.handshake.check_request(request_headers) + + subprotocols: list[str] = [] + for header in request_headers.get_all("Sec-WebSocket-Protocol"): + subprotocols.extend([token.strip() for token in header.split(",")]) + + asgi_headers = [ + (name.encode("ascii"), value.encode("ascii", errors="surrogateescape")) + for name, value in request_headers.raw_items() + ] + path = unquote(path_portion) + full_path = self.root_path + path + full_raw_path = self.root_path.encode("ascii") + path_portion.encode("ascii") + + self.scope = { + "type": "websocket", + "asgi": {"version": self.asgi_version, "spec_version": "2.4"}, + "http_version": "1.1", + "scheme": self.scheme, + "server": self.server, + "client": self.client, + "root_path": self.root_path, + "path": full_path, + "raw_path": full_raw_path, + "query_string": query_string.encode("ascii"), + "headers": asgi_headers, + "subprotocols": subprotocols, + "state": self.app_state.copy(), + "extensions": {"websocket.http.response": {}}, + } + task = self.loop.create_task(self.run_asgi()) + task.add_done_callback(self.on_task_complete) + self.tasks.add(task) + await self.handshake_started_event.wait() + return self.initial_response + + def process_subprotocol( + self, headers: Headers, available_subprotocols: Sequence[Subprotocol] | None + ) -> Subprotocol | None: + """ + We override the standard 'process_subprotocol' behavior here so that + we return whatever subprotocol is sent in the 'accept' message. + """ + return self.accepted_subprotocol + + def send_500_response(self) -> None: + msg = b"Internal Server Error" + content = [ + b"HTTP/1.1 500 Internal Server Error\r\ncontent-type: text/plain; charset=utf-8\r\n", + b"content-length: " + str(len(msg)).encode("ascii") + b"\r\n", + b"connection: close\r\n", + b"\r\n", + msg, + ] + self.transport.write(b"".join(content)) + # Allow handler task to terminate cleanly, as websockets doesn't cancel it by + # itself (see https://github.com/Kludex/uvicorn/issues/920) + self.handshake_started_event.set() + + async def ws_handler(self, protocol: WebSocketServerProtocol, path: str) -> Any: # type: ignore[override] + """ + This is the main handler function for the 'websockets' implementation + to call into. We just wait for close then return, and instead allow + 'send' and 'receive' events to drive the flow. + """ + self.handshake_completed_event.set() + await self.wait_closed() + + async def run_asgi(self) -> None: + """ + Wrapper around the ASGI callable, handling exceptions and unexpected + termination states. + """ + try: + result = await self.app(self.scope, self.asgi_receive, self.asgi_send) # type: ignore[func-returns-value] + except ClientDisconnected: # pragma: full coverage + self.closed_event.set() + except BaseException: + self.closed_event.set() + self.logger.exception("Exception in ASGI application\n") + if not self.handshake_started_event.is_set(): + self.send_500_response() + else: + await self.handshake_completed_event.wait() + else: + self.closed_event.set() + if not self.handshake_started_event.is_set(): + self.logger.error("ASGI callable returned without sending handshake.") + self.send_500_response() + elif result is not None: + self.logger.error("ASGI callable should return None, but returned '%s'.", result) + await self.handshake_completed_event.wait() + self.transport.close() + + async def asgi_send(self, message: ASGISendEvent) -> None: + if not self.handshake_started_event.is_set(): + if message["type"] == "websocket.accept": + self.logger.info( + '%s - "WebSocket %s" [accepted]', + get_client_addr(self.scope), + get_path_with_query_string(self.scope), + ) + self.initial_response = None + self.accepted_subprotocol = cast(Subprotocol | None, message.get("subprotocol")) + if "headers" in message: + self.extra_headers.extend( + # ASGI spec requires bytes + # But for compatibility we need to convert it to strings + (name.decode("latin-1"), value.decode("latin-1")) + for name, value in message["headers"] + ) + self.handshake_started_event.set() + + elif message["type"] == "websocket.close": + self.logger.info( + '%s - "WebSocket %s" 403', + get_client_addr(self.scope), + get_path_with_query_string(self.scope), + ) + self.initial_response = (http.HTTPStatus.FORBIDDEN, [], b"") + self.handshake_started_event.set() + self.closed_event.set() + + elif message["type"] == "websocket.http.response.start": + self.logger.info( + '%s - "WebSocket %s" %d', + get_client_addr(self.scope), + get_path_with_query_string(self.scope), + message["status"], + ) + # websockets requires the status to be an enum. look it up. + status = http.HTTPStatus(message["status"]) + headers = [ + (name.decode("latin-1"), value.decode("latin-1")) for name, value in message.get("headers", []) + ] + self.initial_response = (status, headers, b"") + self.handshake_started_event.set() + + else: + raise RuntimeError( + "Expected ASGI message 'websocket.accept', 'websocket.close', " + f"or 'websocket.http.response.start' but got '{message['type']}'." + ) + + elif not self.closed_event.is_set() and self.initial_response is None: + await self.handshake_completed_event.wait() + + try: + if message["type"] == "websocket.send": + bytes_data = message.get("bytes") + text_data = message.get("text") + data = text_data if bytes_data is None else bytes_data + await self.send(data) # type: ignore[arg-type] + + elif message["type"] == "websocket.close": + code = message.get("code", 1000) + reason = message.get("reason", "") or "" + await self.close(code, reason) + self.closed_event.set() + + else: + raise RuntimeError( + f"Expected ASGI message 'websocket.send' or 'websocket.close', but got '{message['type']}'." + ) + except ConnectionClosed as exc: + raise ClientDisconnected from exc + + elif self.initial_response is not None: + if message["type"] == "websocket.http.response.body": + body = self.initial_response[2] + message["body"] + self.initial_response = self.initial_response[:2] + (body,) + if not message.get("more_body", False): + self.closed_event.set() + else: + raise RuntimeError(f"Expected ASGI message 'websocket.http.response.body' but got '{message['type']}'.") + + else: + raise RuntimeError( + f"Unexpected ASGI message '{message['type']}', after sending 'websocket.close' " + "or response already completed." + ) + + async def asgi_receive(self) -> WebSocketDisconnectEvent | WebSocketConnectEvent | WebSocketReceiveEvent: + if not self.connect_sent: + self.connect_sent = True + return {"type": "websocket.connect"} + + await self.handshake_completed_event.wait() + + if self.lost_connection_before_handshake: + # If the handshake failed or the app closed before handshake completion, + # use 1006 Abnormal Closure. + return {"type": "websocket.disconnect", "code": 1006} + + if self.closed_event.is_set(): + return {"type": "websocket.disconnect", "code": 1005} + + try: + data = await self.recv() + except ConnectionClosed: + self.closed_event.set() + if self.ws_server.closing: + return {"type": "websocket.disconnect", "code": 1012} + return {"type": "websocket.disconnect", "code": self.close_code or 1005, "reason": self.close_reason} + + if isinstance(data, str): + return {"type": "websocket.receive", "text": data} + return {"type": "websocket.receive", "bytes": data} diff --git a/.venv/Lib/site-packages/uvicorn/protocols/websockets/websockets_sansio_impl.py b/.venv/Lib/site-packages/uvicorn/protocols/websockets/websockets_sansio_impl.py new file mode 100644 index 0000000000000000000000000000000000000000..efaa457f10a8915d9699b2c7c1f7034ca60cf135 --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/protocols/websockets/websockets_sansio_impl.py @@ -0,0 +1,484 @@ +from __future__ import annotations + +import asyncio +import logging +import random +import struct +import sys +from asyncio import TimerHandle +from asyncio.transports import BaseTransport, Transport +from http import HTTPStatus +from typing import Any, Literal, cast +from urllib.parse import unquote + +from websockets.exceptions import InvalidState +from websockets.extensions.permessage_deflate import ServerPerMessageDeflateFactory +from websockets.frames import Frame, Opcode +from websockets.http11 import Request +from websockets.server import ServerProtocol + +from uvicorn._types import ( + ASGIReceiveEvent, + ASGISendEvent, + WebSocketScope, +) +from uvicorn.config import Config +from uvicorn.logging import TRACE_LOG_LEVEL +from uvicorn.protocols.utils import ( + ClientDisconnected, + get_client_addr, + get_local_addr, + get_path_with_query_string, + get_remote_addr, + is_ssl, +) +from uvicorn.server import ServerState + +if sys.version_info >= (3, 11): # pragma: no cover + from typing import assert_never +else: # pragma: no cover + from typing_extensions import assert_never + + +class WebSocketsSansIOProtocol(asyncio.Protocol): + def __init__( + self, + config: Config, + server_state: ServerState, + app_state: dict[str, Any], + _loop: asyncio.AbstractEventLoop | None = None, + ) -> None: + if not config.loaded: + config.load() # pragma: no cover + + self.config = config + self.app = config.loaded_app + self.loop = _loop or asyncio.get_event_loop() + self.logger = logging.getLogger("uvicorn.error") + self.root_path = config.root_path + self.asgi_version = config.asgi_version + self.app_state = app_state + + # Shared server state + self.connections = server_state.connections + self.tasks = server_state.tasks + self.default_headers = server_state.default_headers + + # Connection state + self.transport: asyncio.Transport = None # type: ignore[assignment] + self.server: tuple[str, int | None] | None = None + self.client: tuple[str, int] | None = None + self.scheme: Literal["wss", "ws"] = None # type: ignore[assignment] + + # WebSocket state + self.queue: asyncio.Queue[ASGIReceiveEvent] = asyncio.Queue() + self.handshake_initiated = False + self.handshake_complete = False + self.close_sent = False + self.initial_response: tuple[int, list[tuple[str, str]], bytes] | None = None + + extensions = [] + if self.config.ws_per_message_deflate: + extensions = [ + ServerPerMessageDeflateFactory( + server_max_window_bits=12, + client_max_window_bits=12, + compress_settings={"memLevel": 5}, + ) + ] + self.conn = ServerProtocol( + extensions=extensions, + max_size=self.config.ws_max_size, + logger=logging.getLogger("uvicorn.error"), + ) + + self.read_paused = False + self.writable = asyncio.Event() + self.writable.set() + + # Keepalive state + self.ping_interval = config.ws_ping_interval + self.ping_timeout = config.ws_ping_timeout + self.ping_timer: TimerHandle | None = None + self.pong_timer: TimerHandle | None = None + self.pending_ping_payload: bytes | None = None + self.ping_sent_at: float = 0.0 + self.last_ping_rtt: float = 0.0 + + # Incoming message state + self.frames: list[bytes] = [] + self.curr_msg_data_type: Literal["text", "bytes"] = "bytes" + + def connection_made(self, transport: BaseTransport) -> None: + """Called when a connection is made.""" + transport = cast(Transport, transport) + self.connections.add(self) + self.transport = transport + self.server = get_local_addr(transport) + self.client = get_remote_addr(transport) + self.scheme = "wss" if is_ssl(transport) else "ws" + + if self.logger.level <= TRACE_LOG_LEVEL: + prefix = "%s:%d - " % self.client if self.client else "" + self.logger.log(TRACE_LOG_LEVEL, "%sWebSocket connection made", prefix) + + def connection_lost(self, exc: Exception | None) -> None: + self.stop_keepalive() + code = 1005 if self.handshake_complete else 1006 + self.queue.put_nowait({"type": "websocket.disconnect", "code": code}) + self.connections.remove(self) + + if self.logger.level <= TRACE_LOG_LEVEL: + prefix = "%s:%d - " % self.client if self.client else "" + self.logger.log(TRACE_LOG_LEVEL, "%sWebSocket connection lost", prefix) + + self.handshake_complete = True + if exc is None: + self.transport.close() + + def eof_received(self) -> None: + pass + + def shutdown(self) -> None: + self.stop_keepalive() + if self.handshake_complete: + self.queue.put_nowait({"type": "websocket.disconnect", "code": 1012}) + self.conn.send_close(1012) + output = self.conn.data_to_send() + self.transport.write(b"".join(output)) + else: + self.send_500_response() + self.transport.close() + + def data_received(self, data: bytes) -> None: + self.conn.receive_data(data) + if self.conn.parser_exc is not None: # pragma: no cover + self.handle_parser_exception() + return + self.handle_events() + + def handle_events(self) -> None: + for event in self.conn.events_received(): + if isinstance(event, Request): + self.handle_connect(event) + if isinstance(event, Frame): + if event.opcode == Opcode.CONT: + self.handle_cont(event) # pragma: no cover + elif event.opcode == Opcode.TEXT: + self.handle_text(event) + elif event.opcode == Opcode.BINARY: + self.handle_bytes(event) + elif event.opcode == Opcode.PING: + self.handle_ping() + elif event.opcode == Opcode.PONG: + self.handle_pong(event) + elif event.opcode == Opcode.CLOSE: + self.handle_close(event) + else: + assert_never(event.opcode) # pragma: no cover + + # Event handlers + + def handle_connect(self, event: Request) -> None: + self.request = event + self.response = self.conn.accept(event) + self.handshake_initiated = True + if self.response.status_code != 101: + self.handshake_complete = True + self.close_sent = True + self.conn.send_response(self.response) + output = self.conn.data_to_send() + self.transport.write(b"".join(output)) + self.transport.close() + return + + headers = [ + (key.encode("ascii"), value.encode("ascii", errors="surrogateescape")) + for key, value in event.headers.raw_items() + ] + raw_path, _, query_string = event.path.partition("?") + subprotocols: list[str] = [] + for header in event.headers.get_all("Sec-WebSocket-Protocol"): + subprotocols.extend([token.strip() for token in header.split(",")]) + self.scope: WebSocketScope = { + "type": "websocket", + "asgi": {"version": self.asgi_version, "spec_version": "2.4"}, + "http_version": "1.1", + "scheme": self.scheme, + "server": self.server, + "client": self.client, + "root_path": self.root_path, + "path": self.root_path + unquote(raw_path), + "raw_path": self.root_path.encode("ascii") + raw_path.encode("ascii"), + "query_string": query_string.encode("ascii"), + "headers": headers, + "subprotocols": subprotocols, + "state": self.app_state.copy(), + "extensions": {"websocket.http.response": {}}, + } + self.queue.put_nowait({"type": "websocket.connect"}) + task = self.loop.create_task(self.run_asgi()) + task.add_done_callback(self.on_task_complete) + self.tasks.add(task) + + def handle_cont(self, event: Frame) -> None: + self.frames.append(event.data) # type: ignore[arg-type] + if event.fin: + self.send_receive_event_to_app() + + def handle_text(self, event: Frame) -> None: + self.curr_msg_data_type = "text" + self.frames = [event.data] # type: ignore[list-item] + if event.fin: + self.send_receive_event_to_app() + + def handle_bytes(self, event: Frame) -> None: + self.curr_msg_data_type = "bytes" + self.frames = [event.data] # type: ignore[list-item] + if event.fin: + self.send_receive_event_to_app() + + def send_receive_event_to_app(self) -> None: + data = self.frames[0] if len(self.frames) == 1 else b"".join(self.frames) + self.frames = [] + if self.curr_msg_data_type == "text": + try: + self.queue.put_nowait({"type": "websocket.receive", "text": data.decode()}) + except UnicodeDecodeError: # pragma: no cover + self.logger.exception("Invalid UTF-8 sequence received from client.") + self.conn.send_close(1007) + self.handle_parser_exception() + return + else: + self.queue.put_nowait({"type": "websocket.receive", "bytes": data}) + if not self.read_paused: + self.read_paused = True + self.transport.pause_reading() + + def handle_ping(self) -> None: + output = self.conn.data_to_send() + self.transport.write(b"".join(output)) + + def handle_pong(self, event: Frame) -> None: + # Ignore unsolicited pongs and stale pongs whose payload doesn't match the ping currently in flight + if self.pending_ping_payload is None or bytes(event.data) != self.pending_ping_payload: + return # pragma: no cover + + self.last_ping_rtt = self.loop.time() - self.ping_sent_at + self.pending_ping_payload = None + # The peer answered in time; cancel the pong deadline and chain the next ping. This `schedule_ping()` call is + # what keeps the keepalive loop running when ping_timeout is set. When ping_timeout is None the next ping is + # already scheduled by `send_keepalive_ping`, so we must not schedule a duplicate here. + if self.pong_timer is not None: + self.pong_timer.cancel() + self.pong_timer = None + self.schedule_ping() + + def start_keepalive(self) -> None: + if self.ping_interval is not None and self.ping_interval > 0: + self.schedule_ping() + + def stop_keepalive(self) -> None: + if self.ping_timer is not None: + self.ping_timer.cancel() + self.ping_timer = None + if self.pong_timer is not None: # pragma: no cover + self.pong_timer.cancel() + self.pong_timer = None + self.pending_ping_payload = None + + def schedule_ping(self) -> None: + assert self.ping_interval is not None + delay = max(0.0, self.ping_interval - self.last_ping_rtt) + self.ping_timer = self.loop.call_later(delay, self.send_keepalive_ping) + + def send_keepalive_ping(self) -> None: + self.ping_timer = None + if self.close_sent or self.transport.is_closing(): # pragma: no cover + return + # Random 4-byte payload identifies this ping; `handle_pong` uses it to ignore stale or unsolicited pongs. + # See https://github.com/python-websockets/websockets/blob/4d229bf9f583d593aa103287aee0a77c9fbc3a79/src/websockets/asyncio/connection.py#L624 + self.pending_ping_payload = struct.pack("!I", random.getrandbits(32)) + self.ping_sent_at = self.loop.time() + self.conn.send_ping(self.pending_ping_payload) + self.transport.write(b"".join(self.conn.data_to_send())) + if self.ping_timeout is not None: + self.pong_timer = self.loop.call_later(self.ping_timeout, self.keepalive_timeout) + else: # pragma: no cover + self.schedule_ping() + + def keepalive_timeout(self) -> None: + self.pong_timer = None + self.pending_ping_payload = None + if self.close_sent or self.transport.is_closing(): # pragma: no cover + return + if self.logger.level <= TRACE_LOG_LEVEL: + prefix = "%s:%d - " % self.client if self.client else "" + self.logger.log(TRACE_LOG_LEVEL, "%sWebSocket keepalive ping timeout", prefix) + self.conn.fail(1011, "keepalive ping timeout") + self.transport.write(b"".join(self.conn.data_to_send())) + self.close_sent = True + self.transport.close() + + def handle_close(self, event: Frame) -> None: + if not self.close_sent and not self.transport.is_closing(): + assert self.conn.close_rcvd is not None + code = self.conn.close_rcvd.code + reason = self.conn.close_rcvd.reason + self.queue.put_nowait({"type": "websocket.disconnect", "code": code, "reason": reason}) + + output = self.conn.data_to_send() + self.transport.write(b"".join(output)) + self.transport.close() + + def handle_parser_exception(self) -> None: # pragma: no cover + assert self.conn.close_sent is not None + code = self.conn.close_sent.code + reason = self.conn.close_sent.reason + self.queue.put_nowait({"type": "websocket.disconnect", "code": code, "reason": reason}) + + output = self.conn.data_to_send() + self.transport.write(b"".join(output)) + self.close_sent = True + self.transport.close() + + def on_task_complete(self, task: asyncio.Task[None]) -> None: + self.tasks.discard(task) + + async def run_asgi(self) -> None: + try: + result = await self.app(self.scope, self.receive, self.send) + except ClientDisconnected: + pass # pragma: full coverage + except BaseException: + self.logger.exception("Exception in ASGI application\n") + self.send_500_response() + else: + if not self.handshake_complete: + self.logger.error("ASGI callable returned without completing handshake.") + self.send_500_response() + elif result is not None: + self.logger.error("ASGI callable should return None, but returned '%s'.", result) + self.transport.close() + + def send_500_response(self) -> None: + if self.initial_response or self.handshake_complete: + return + response = self.conn.reject(500, "Internal Server Error") + self.conn.send_response(response) + output = self.conn.data_to_send() + self.transport.write(b"".join(output)) + + async def send(self, message: ASGISendEvent) -> None: + await self.writable.wait() + + if not self.handshake_complete and self.initial_response is None: + if message["type"] == "websocket.accept": + self.logger.info( + '%s - "WebSocket %s" [accepted]', + get_client_addr(self.scope), + get_path_with_query_string(self.scope), + ) + headers = [ + (name.decode("latin-1").lower(), value.decode("latin-1")) + for name, value in (self.default_headers + list(message.get("headers", []))) + ] + accepted_subprotocol = message.get("subprotocol") + if accepted_subprotocol: + headers.append(("Sec-WebSocket-Protocol", accepted_subprotocol)) + self.response.headers.update(headers) + + if not self.transport.is_closing(): + self.handshake_complete = True + self.conn.send_response(self.response) + output = self.conn.data_to_send() + self.transport.write(b"".join(output)) + self.start_keepalive() + + elif message["type"] == "websocket.close": + self.queue.put_nowait({"type": "websocket.disconnect", "code": 1006}) + self.logger.info( + '%s - "WebSocket %s" 403', + get_client_addr(self.scope), + get_path_with_query_string(self.scope), + ) + response = self.conn.reject(HTTPStatus.FORBIDDEN, "") + self.conn.send_response(response) + output = self.conn.data_to_send() + self.close_sent = True + self.handshake_complete = True + self.transport.write(b"".join(output)) + self.transport.close() + elif message["type"] == "websocket.http.response.start" and self.initial_response is None: + if not (100 <= message["status"] < 600): + raise RuntimeError("Invalid HTTP status code '%d' in response." % message["status"]) + self.logger.info( + '%s - "WebSocket %s" %d', + get_client_addr(self.scope), + get_path_with_query_string(self.scope), + message["status"], + ) + headers = [ + (name.decode("latin-1"), value.decode("latin-1")) + for name, value in list(message.get("headers", [])) + ] + self.initial_response = (message["status"], headers, b"") + else: + raise RuntimeError( + "Expected ASGI message 'websocket.accept', 'websocket.close' " + f"or 'websocket.http.response.start' but got '{message['type']}'." + ) + + elif not self.close_sent and self.initial_response is None: + try: + if message["type"] == "websocket.send": + bytes_data = message.get("bytes") + text_data = message.get("text") + if bytes_data is not None: + self.conn.send_binary(bytes_data) + elif text_data is not None: + self.conn.send_text(text_data.encode()) + output = self.conn.data_to_send() + self.transport.write(b"".join(output)) + + elif message["type"] == "websocket.close": + if not self.transport.is_closing(): + code = message.get("code", 1000) + reason = message.get("reason", "") or "" + self.queue.put_nowait({"type": "websocket.disconnect", "code": code, "reason": reason}) + self.conn.send_close(code, reason) + output = self.conn.data_to_send() + self.transport.write(b"".join(output)) + self.close_sent = True + self.transport.close() + else: + raise RuntimeError( + f"Expected ASGI message 'websocket.send' or 'websocket.close', but got '{message['type']}'." + ) + except InvalidState: + raise ClientDisconnected() + elif self.initial_response is not None: + if message["type"] == "websocket.http.response.body": + body = self.initial_response[2] + message["body"] + self.initial_response = self.initial_response[:2] + (body,) + if not message.get("more_body", False): + response = self.conn.reject(self.initial_response[0], body.decode()) + response.headers.update(self.initial_response[1]) + self.queue.put_nowait({"type": "websocket.disconnect", "code": 1006}) + self.conn.send_response(response) + output = self.conn.data_to_send() + self.close_sent = True + self.transport.write(b"".join(output)) + self.transport.close() + else: # pragma: no cover + raise RuntimeError(f"Expected ASGI message 'websocket.http.response.body' but got '{message['type']}'.") + + else: + raise RuntimeError(f"Unexpected ASGI message '{message['type']}', after sending 'websocket.close'.") + + async def receive(self) -> ASGIReceiveEvent: + message = await self.queue.get() + if self.read_paused and self.queue.empty(): + self.read_paused = False + self.transport.resume_reading() + return message diff --git a/.venv/Lib/site-packages/uvicorn/protocols/websockets/wsproto_impl.py b/.venv/Lib/site-packages/uvicorn/protocols/websockets/wsproto_impl.py new file mode 100644 index 0000000000000000000000000000000000000000..b193efd12582b8e4a19f4c0fd4ffe7673d519f64 --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/protocols/websockets/wsproto_impl.py @@ -0,0 +1,469 @@ +from __future__ import annotations + +import asyncio +import logging +import random +import struct +from asyncio import TimerHandle +from io import BytesIO, StringIO +from typing import Any, Literal, cast +from urllib.parse import unquote + +import wsproto +from wsproto import ConnectionType, events +from wsproto.connection import ConnectionState +from wsproto.extensions import Extension, PerMessageDeflate +from wsproto.utilities import LocalProtocolError, RemoteProtocolError + +from uvicorn._types import ( + ASGI3Application, + ASGISendEvent, + WebSocketEvent, + WebSocketReceiveEvent, + WebSocketScope, +) +from uvicorn.config import Config +from uvicorn.logging import TRACE_LOG_LEVEL +from uvicorn.protocols.utils import ( + ClientDisconnected, + get_client_addr, + get_local_addr, + get_path_with_query_string, + get_remote_addr, + is_ssl, +) +from uvicorn.server import ServerState + + +class FrameTooLargeError(Exception): + """Raised when accumulated websocket message bytes exceed `ws_max_size`.""" + + +class WebsocketBuffer: + def __init__(self, max_length: int) -> None: + self.value: BytesIO | StringIO | None = None + self.length = 0 + self.max_length = max_length + + def extend(self, event: events.TextMessage | events.BytesMessage) -> None: + if self.value is None: + self.value = StringIO() if isinstance(event, events.TextMessage) else BytesIO() + self.value.write(event.data) # type: ignore[arg-type] + # `ws_max_size` is a byte budget, so count UTF-8 bytes for text. + self.length += len(event.data.encode()) if isinstance(event, events.TextMessage) else len(event.data) + if self.length > self.max_length: + raise FrameTooLargeError + + def clear(self) -> None: + self.value = None + self.length = 0 + + def to_message(self) -> WebSocketReceiveEvent: + if isinstance(self.value, StringIO): + return {"type": "websocket.receive", "text": self.value.getvalue()} + assert isinstance(self.value, BytesIO) + return {"type": "websocket.receive", "bytes": self.value.getvalue()} + + +class WSProtocol(asyncio.Protocol): + def __init__( + self, + config: Config, + server_state: ServerState, + app_state: dict[str, Any], + _loop: asyncio.AbstractEventLoop | None = None, + ) -> None: + if not config.loaded: + config.load() # pragma: full coverage + + self.config = config + self.app = cast(ASGI3Application, config.loaded_app) + self.loop = _loop or asyncio.get_event_loop() + self.logger = logging.getLogger("uvicorn.error") + self.root_path = config.root_path + self.asgi_version = config.asgi_version + self.app_state = app_state + + # Shared server state + self.connections = server_state.connections + self.tasks = server_state.tasks + self.default_headers = server_state.default_headers + + # Connection state + self.transport: asyncio.Transport = None # type: ignore[assignment] + self.server: tuple[str, int | None] | None = None + self.client: tuple[str, int] | None = None + self.scheme: Literal["wss", "ws"] = None # type: ignore[assignment] + + # WebSocket state + self.queue: asyncio.Queue[WebSocketEvent] = asyncio.Queue() + self.handshake_complete = False + self.close_sent = False + + # Rejection state + self.response_started = False + + self.conn = wsproto.WSConnection(connection_type=ConnectionType.SERVER) + + self.read_paused = False + self.writable = asyncio.Event() + self.writable.set() + + # Keepalive state + self.ping_interval = config.ws_ping_interval + self.ping_timeout = config.ws_ping_timeout + self.ping_timer: TimerHandle | None = None + self.pong_timer: TimerHandle | None = None + self.pending_ping_payload: bytes | None = None + self.ping_sent_at: float = 0.0 + self.last_ping_rtt: float = 0.0 + + # Buffer + self.buffer = WebsocketBuffer(self.config.ws_max_size) + + # Protocol interface + + def connection_made(self, transport: asyncio.Transport) -> None: # type: ignore[override] + self.connections.add(self) + self.transport = transport + self.server = get_local_addr(transport) + self.client = get_remote_addr(transport) + self.scheme = "wss" if is_ssl(transport) else "ws" + + if self.logger.level <= TRACE_LOG_LEVEL: + prefix = "%s:%d - " % self.client if self.client else "" + self.logger.log(TRACE_LOG_LEVEL, "%sWebSocket connection made", prefix) + + def connection_lost(self, exc: Exception | None) -> None: + self.stop_keepalive() + code = 1005 if self.handshake_complete else 1006 + self.queue.put_nowait({"type": "websocket.disconnect", "code": code}) + self.connections.remove(self) + + if self.logger.level <= TRACE_LOG_LEVEL: + prefix = "%s:%d - " % self.client if self.client else "" + self.logger.log(TRACE_LOG_LEVEL, "%sWebSocket connection lost", prefix) + + self.handshake_complete = True + if exc is None: + self.transport.close() + + def eof_received(self) -> None: + pass + + def data_received(self, data: bytes) -> None: + try: + self.conn.receive_data(data) + except RemoteProtocolError as err: + # TODO: Remove `type: ignore` when wsproto fixes the type annotation. + self.transport.write(self.conn.send(err.event_hint)) # type: ignore[arg-type] # noqa: E501 + self.transport.close() + except LocalProtocolError: + # Data received after the close handshake completed, e.g. a pong the client + # sent while the server's close was in flight. + self.transport.close() + else: + self.handle_events() + + def handle_events(self) -> None: + for event in self.conn.events(): + if self.close_sent: + return + if isinstance(event, events.Request): + self.handle_connect(event) + elif isinstance(event, (events.TextMessage, events.BytesMessage)): + self.handle_message(event) + elif isinstance(event, events.CloseConnection): + self.handle_close(event) + elif isinstance(event, events.Ping): + self.handle_ping(event) + elif isinstance(event, events.Pong): + self.handle_pong(event) + + def pause_writing(self) -> None: + """ + Called by the transport when the write buffer exceeds the high water mark. + """ + self.writable.clear() # pragma: full coverage + + def resume_writing(self) -> None: + """ + Called by the transport when the write buffer drops below the low water mark. + """ + self.writable.set() # pragma: full coverage + + def shutdown(self) -> None: + self.stop_keepalive() + if self.handshake_complete: + self.queue.put_nowait({"type": "websocket.disconnect", "code": 1012}) + output = self.conn.send(wsproto.events.CloseConnection(code=1012)) + self.transport.write(output) + else: + self.send_500_response() + self.transport.close() + + def on_task_complete(self, task: asyncio.Task[None]) -> None: + self.tasks.discard(task) + + # Event handlers + + def handle_connect(self, event: events.Request) -> None: + headers = [(b"host", event.host.encode())] + headers += [(key.lower(), value) for key, value in event.extra_headers] + raw_path, _, query_string = event.target.partition("?") + path = unquote(raw_path) + full_path = self.root_path + path + full_raw_path = self.root_path.encode("ascii") + raw_path.encode("ascii") + self.scope: WebSocketScope = { + "type": "websocket", + "asgi": {"version": self.asgi_version, "spec_version": "2.4"}, + "http_version": "1.1", + "scheme": self.scheme, + "server": self.server, + "client": self.client, + "root_path": self.root_path, + "path": full_path, + "raw_path": full_raw_path, + "query_string": query_string.encode("ascii"), + "headers": headers, + "subprotocols": event.subprotocols, + "state": self.app_state.copy(), + "extensions": {"websocket.http.response": {}}, + } + self.queue.put_nowait({"type": "websocket.connect"}) + task = self.loop.create_task(self.run_asgi()) + task.add_done_callback(self.on_task_complete) + self.tasks.add(task) + + def handle_message(self, event: events.TextMessage | events.BytesMessage) -> None: + try: + self.buffer.extend(event) + except FrameTooLargeError: + self.close_sent = True + reason = f"Message exceeds the maximum size ({self.config.ws_max_size} bytes)" + self.queue.put_nowait({"type": "websocket.disconnect", "code": 1009, "reason": reason}) + if not self.transport.is_closing(): + self.transport.write(self.conn.send(wsproto.events.CloseConnection(code=1009, reason=reason))) + self.transport.close() + return + if event.message_finished: + self.queue.put_nowait(self.buffer.to_message()) + self.buffer.clear() + if not self.read_paused: + self.read_paused = True + self.transport.pause_reading() + + def handle_close(self, event: events.CloseConnection) -> None: + if self.conn.state == ConnectionState.REMOTE_CLOSING: + self.transport.write(self.conn.send(event.response())) + self.queue.put_nowait({"type": "websocket.disconnect", "code": event.code, "reason": event.reason}) + self.transport.close() + + def handle_ping(self, event: events.Ping) -> None: + self.transport.write(self.conn.send(event.response())) + + def handle_pong(self, event: events.Pong) -> None: + # Ignore unsolicited pongs and stale pongs whose payload doesn't match the ping currently in flight. + if self.pending_ping_payload is None or bytes(event.payload) != self.pending_ping_payload: + return # pragma: no cover + + self.last_ping_rtt = self.loop.time() - self.ping_sent_at + self.pending_ping_payload = None + # The peer answered in time; cancel the pong deadline and chain the next ping. This `schedule_ping()` call is + # what keeps the keepalive loop running when ping_timeout is set. When ping_timeout is None the next ping is + # already scheduled by `send_keepalive_ping`, so we must not schedule a duplicate here. + if self.pong_timer is not None: + self.pong_timer.cancel() + self.pong_timer = None + self.schedule_ping() + + def start_keepalive(self) -> None: + if self.ping_interval is not None and self.ping_interval > 0: + self.schedule_ping() + + def stop_keepalive(self) -> None: + if self.ping_timer is not None: + self.ping_timer.cancel() + self.ping_timer = None + if self.pong_timer is not None: # pragma: no cover + self.pong_timer.cancel() + self.pong_timer = None + self.pending_ping_payload = None + + def schedule_ping(self) -> None: + assert self.ping_interval is not None + delay = max(0.0, self.ping_interval - self.last_ping_rtt) + self.ping_timer = self.loop.call_later(delay, self.send_keepalive_ping) + + def send_keepalive_ping(self) -> None: + self.ping_timer = None + if self.close_sent or self.transport.is_closing(): # pragma: no cover + return + # Random 4-byte payload identifies this ping; `handle_pong` uses it to ignore stale or unsolicited pongs. + self.pending_ping_payload = struct.pack("!I", random.getrandbits(32)) + self.ping_sent_at = self.loop.time() + self.transport.write(self.conn.send(wsproto.events.Ping(payload=self.pending_ping_payload))) + if self.ping_timeout is not None: + self.pong_timer = self.loop.call_later(self.ping_timeout, self.keepalive_timeout) + else: # pragma: no cover + self.schedule_ping() + + def keepalive_timeout(self) -> None: + self.pong_timer = None + self.pending_ping_payload = None + if self.close_sent or self.transport.is_closing(): # pragma: no cover + return + if self.logger.level <= TRACE_LOG_LEVEL: + prefix = "%s:%d - " % self.client if self.client else "" + self.logger.log(TRACE_LOG_LEVEL, "%sWebSocket keepalive ping timeout", prefix) + reason = "keepalive ping timeout" + self.transport.write(self.conn.send(wsproto.events.CloseConnection(code=1011, reason=reason))) + self.close_sent = True + self.transport.close() + + def send_500_response(self) -> None: + if self.response_started or self.handshake_complete: + return # we cannot send responses anymore + headers: list[tuple[bytes, bytes]] = [ + (b"content-type", b"text/plain; charset=utf-8"), + (b"connection", b"close"), + (b"content-length", b"21"), + ] + output = self.conn.send(wsproto.events.RejectConnection(status_code=500, headers=headers, has_body=True)) + output += self.conn.send(wsproto.events.RejectData(data=b"Internal Server Error")) + self.transport.write(output) + + async def run_asgi(self) -> None: + try: + result = await self.app(self.scope, self.receive, self.send) # type: ignore[func-returns-value] + except ClientDisconnected: + pass # pragma: full coverage + except BaseException: + self.logger.exception("Exception in ASGI application\n") + self.send_500_response() + else: + if not self.handshake_complete: + self.logger.error("ASGI callable returned without completing handshake.") + self.send_500_response() + elif result is not None: + self.logger.error("ASGI callable should return None, but returned '%s'.", result) + self.transport.close() + + async def send(self, message: ASGISendEvent) -> None: + await self.writable.wait() + + if not self.handshake_complete: + if message["type"] == "websocket.accept": + self.logger.info( + '%s - "WebSocket %s" [accepted]', + get_client_addr(self.scope), + get_path_with_query_string(self.scope), + ) + subprotocol = message.get("subprotocol") + extra_headers = self.default_headers + list(message.get("headers", [])) + extensions: list[Extension] = [] + if self.config.ws_per_message_deflate: + extensions.append(PerMessageDeflate()) + if not self.transport.is_closing(): + self.handshake_complete = True + output = self.conn.send( + wsproto.events.AcceptConnection( + subprotocol=subprotocol, + extensions=extensions, + extra_headers=extra_headers, + ) + ) + self.transport.write(output) + self.start_keepalive() + + elif message["type"] == "websocket.close": + self.queue.put_nowait({"type": "websocket.disconnect", "code": 1006}) + self.logger.info( + '%s - "WebSocket %s" 403', + get_client_addr(self.scope), + get_path_with_query_string(self.scope), + ) + self.handshake_complete = True + self.close_sent = True + event = events.RejectConnection(status_code=403, headers=[]) + output = self.conn.send(event) + self.transport.write(output) + self.transport.close() + + elif message["type"] == "websocket.http.response.start": + # ensure status code is in the valid range + if not (100 <= message["status"] < 600): + msg = "Invalid HTTP status code '%d' in response." + raise RuntimeError(msg % message["status"]) + self.logger.info( + '%s - "WebSocket %s" %d', + get_client_addr(self.scope), + get_path_with_query_string(self.scope), + message["status"], + ) + self.handshake_complete = True + event = events.RejectConnection( + status_code=message["status"], + headers=list(message["headers"]), + has_body=True, + ) + output = self.conn.send(event) + self.transport.write(output) + self.response_started = True + + else: + raise RuntimeError( + "Expected ASGI message 'websocket.accept', 'websocket.close' " + f"or 'websocket.http.response.start' but got '{message['type']}'." + ) + + elif not self.close_sent and not self.response_started: + try: + if message["type"] == "websocket.send": + bytes_data = message.get("bytes") + text_data = message.get("text") + data = text_data if bytes_data is None else bytes_data + output = self.conn.send(wsproto.events.Message(data=data)) # type: ignore + if not self.transport.is_closing(): + self.transport.write(output) + + elif message["type"] == "websocket.close": + self.close_sent = True + code = message.get("code", 1000) + reason = message.get("reason", "") or "" + self.queue.put_nowait({"type": "websocket.disconnect", "code": code, "reason": reason}) + output = self.conn.send(wsproto.events.CloseConnection(code=code, reason=reason)) + if not self.transport.is_closing(): + self.transport.write(output) + self.transport.close() + + else: + raise RuntimeError( + f"Expected ASGI message 'websocket.send' or 'websocket.close', but got '{message['type']}'." + ) + except LocalProtocolError as exc: + raise ClientDisconnected from exc + elif self.response_started: + if message["type"] == "websocket.http.response.body": + body_finished = not message.get("more_body", False) + reject_data = events.RejectData(data=message["body"], body_finished=body_finished) + output = self.conn.send(reject_data) + self.transport.write(output) + + if body_finished: + self.queue.put_nowait({"type": "websocket.disconnect", "code": 1006}) + self.close_sent = True + self.transport.close() + + else: + raise RuntimeError(f"Expected ASGI message 'websocket.http.response.body' but got '{message['type']}'.") + + else: + raise RuntimeError(f"Unexpected ASGI message '{message['type']}', after sending 'websocket.close'.") + + async def receive(self) -> WebSocketEvent: + message = await self.queue.get() + if self.read_paused and self.queue.empty(): + self.read_paused = False + self.transport.resume_reading() + return message diff --git a/.venv/Lib/site-packages/uvicorn/py.typed b/.venv/Lib/site-packages/uvicorn/py.typed new file mode 100644 index 0000000000000000000000000000000000000000..8b137891791fe96927ad78e64b0aad7bded08bdc --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/py.typed @@ -0,0 +1 @@ + diff --git a/.venv/Lib/site-packages/uvicorn/server.py b/.venv/Lib/site-packages/uvicorn/server.py new file mode 100644 index 0000000000000000000000000000000000000000..a4794c0dc9f7da07eeecc8687849038a07ce5816 --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/server.py @@ -0,0 +1,344 @@ +from __future__ import annotations + +import asyncio +import contextlib +import functools +import logging +import os +import platform +import random +import signal +import socket +import sys +import threading +import time +from collections.abc import Generator, Sequence +from email.utils import formatdate +from types import FrameType +from typing import TYPE_CHECKING, TypeAlias + +from uvicorn._ansi import style +from uvicorn._compat import asyncio_run +from uvicorn.config import STARTUP_FAILURE, Config + +if TYPE_CHECKING: + from uvicorn.protocols.http.h11_impl import H11Protocol + from uvicorn.protocols.http.httptools_impl import HttpToolsProtocol + from uvicorn.protocols.websockets.websockets_impl import WebSocketProtocol + from uvicorn.protocols.websockets.websockets_sansio_impl import WebSocketsSansIOProtocol + from uvicorn.protocols.websockets.wsproto_impl import WSProtocol + + Protocols: TypeAlias = H11Protocol | HttpToolsProtocol | WSProtocol | WebSocketProtocol | WebSocketsSansIOProtocol + +HANDLED_SIGNALS = ( + signal.SIGINT, # Unix signal 2. Sent by Ctrl+C. + signal.SIGTERM, # Unix signal 15. Sent by `kill `. +) +if sys.platform == "win32": # pragma: py-not-win32 + HANDLED_SIGNALS += (signal.SIGBREAK,) # Windows signal 21. Sent by Ctrl+Break. + +logger = logging.getLogger("uvicorn.error") + + +class ServerState: + """ + Shared servers state that is available between all protocol instances. + """ + + def __init__(self) -> None: + self.total_requests = 0 + self.connections: set[Protocols] = set() + self.tasks: set[asyncio.Task[None]] = set() + self.default_headers: list[tuple[bytes, bytes]] = [] + + +class Server: + def __init__(self, config: Config) -> None: + self.config = config + self.server_state = ServerState() + + self.started = False + self.should_exit = False + self.force_exit = False + self.last_notified = 0.0 + + self._captured_signals: list[int] = [] + + @functools.cached_property + def limit_max_requests(self) -> int | None: + if self.config.limit_max_requests is None: + return None + return self.config.limit_max_requests + random.randint(0, self.config.limit_max_requests_jitter) + + def run(self, sockets: list[socket.socket] | None = None) -> None: + return asyncio_run(self.serve(sockets=sockets), loop_factory=self.config.get_loop_factory()) + + async def serve(self, sockets: list[socket.socket] | None = None) -> None: + with self.capture_signals(): + await self._serve(sockets) + + async def _serve(self, sockets: list[socket.socket] | None = None) -> None: + process_id = os.getpid() + + config = self.config + if not config.loaded: + config.load() + + self.lifespan = config.lifespan_class(config) + + message = "Started server process [%d]" + color_message = "Started server process [" + style("%d", fg="cyan") + "]" + logger.info(message, process_id, extra={"color_message": color_message}) + + await self.startup(sockets=sockets) + if not self.should_exit: + await self.main_loop() + if self.started: + await self.shutdown(sockets=sockets) + + message = "Finished server process [%d]" + color_message = "Finished server process [" + style("%d", fg="cyan") + "]" + logger.info(message, process_id, extra={"color_message": color_message}) + + async def startup(self, sockets: list[socket.socket] | None = None) -> None: + await self.lifespan.startup() + if self.lifespan.should_exit: + sys.exit(STARTUP_FAILURE) + + config = self.config + + def create_protocol( + _loop: asyncio.AbstractEventLoop | None = None, + ) -> asyncio.Protocol: + return config.http_protocol_class( # type: ignore[call-arg] + config=config, + server_state=self.server_state, + app_state=self.lifespan.state, + _loop=_loop, + ) + + loop = asyncio.get_running_loop() + + listeners: Sequence[socket.SocketType] + if sockets is not None: # pragma: full coverage + # Explicitly passed a list of open sockets. + # We use this when the server is run from a Gunicorn worker. + + def _share_socket( + sock: socket.SocketType, + ) -> socket.SocketType: # pragma py-not-win32 + # Windows requires the socket be explicitly shared across + # multiple workers (processes). + from socket import fromshare # type: ignore[attr-defined] + + sock_data = sock.share(os.getpid()) # type: ignore[attr-defined] + return fromshare(sock_data) + + self.servers: list[asyncio.base_events.Server] = [] + for sock in sockets: + is_windows = platform.system() == "Windows" + if config.workers > 1 and is_windows: # pragma: py-not-win32 + sock = _share_socket(sock) # type: ignore[assignment] + server = await loop.create_server(create_protocol, sock=sock, ssl=config.ssl, backlog=config.backlog) + self.servers.append(server) + listeners = sockets + + elif config.fd is not None: # pragma: py-win32 + # Use an existing socket, from a file descriptor. + sock = socket.fromfd(config.fd, socket.AF_UNIX, socket.SOCK_STREAM) + server = await loop.create_server(create_protocol, sock=sock, ssl=config.ssl, backlog=config.backlog) + assert server.sockets is not None # mypy + listeners = server.sockets + self.servers = [server] + + elif config.uds is not None: # pragma: py-win32 + # Create a socket using UNIX domain socket. + uds_perms = 0o666 + if os.path.exists(config.uds): + uds_perms = os.stat(config.uds).st_mode # pragma: full coverage + server = await loop.create_unix_server( + create_protocol, path=config.uds, ssl=config.ssl, backlog=config.backlog + ) + os.chmod(config.uds, uds_perms) + assert server.sockets is not None # mypy + listeners = server.sockets + self.servers = [server] + + else: + # Standard case. Create a socket from a host/port pair. + try: + server = await loop.create_server( + create_protocol, + host=config.host, + port=config.port, + ssl=config.ssl, + backlog=config.backlog, + ) + except OSError as exc: + logger.error(exc) + await self.lifespan.shutdown() + sys.exit(STARTUP_FAILURE) + + assert server.sockets is not None + listeners = server.sockets + self.servers = [server] + + if sockets is None: + self._log_started_message(listeners) + else: + # We're most likely running multiple workers, so a message has already been + # logged by `config.bind_socket()`. + pass # pragma: full coverage + + self.started = True + + def _log_started_message(self, listeners: Sequence[socket.SocketType]) -> None: + config = self.config + + if config.fd is not None: # pragma: py-win32 + sock = listeners[0] + logger.info( + "Uvicorn running on socket %s (Press CTRL+C to quit)", + sock.getsockname(), + ) + + elif config.uds is not None: # pragma: py-win32 + logger.info("Uvicorn running on unix socket %s (Press CTRL+C to quit)", config.uds) + + else: + addr_format = "%s://%s:%d" + host = "0.0.0.0" if config.host is None else config.host + if ":" in host: + # It's an IPv6 address. + addr_format = "%s://[%s]:%d" + + port = config.port + if port == 0: + port = listeners[0].getsockname()[1] + + protocol_name = "https" if config.ssl else "http" + message = f"Uvicorn running on {addr_format} (Press CTRL+C to quit)" + color_message = "Uvicorn running on " + style(addr_format, bold=True) + " (Press CTRL+C to quit)" + logger.info( + message, + protocol_name, + host, + port, + extra={"color_message": color_message}, + ) + + async def main_loop(self) -> None: + counter = 0 + should_exit = await self.on_tick(counter) + while not should_exit: + counter += 1 + counter = counter % 864000 + await asyncio.sleep(0.1) + should_exit = await self.on_tick(counter) + + async def on_tick(self, counter: int) -> bool: + # Update the default headers, once per second. + if counter % 10 == 0: + current_time = time.time() + current_date = formatdate(current_time, usegmt=True).encode() + + if self.config.date_header: + date_header = [(b"date", current_date)] + else: + date_header = [] + + self.server_state.default_headers = date_header + self.config.encoded_headers + + # Callback to `callback_notify` once every `timeout_notify` seconds. + if self.config.callback_notify is not None: + if current_time - self.last_notified > self.config.timeout_notify: # pragma: full coverage + self.last_notified = current_time + await self.config.callback_notify() + + # Determine if we should exit. + if self.should_exit: + return True + + max_requests = self.limit_max_requests + if max_requests is not None and self.server_state.total_requests >= max_requests: + logger.info("Maximum request limit of %d exceeded. Terminating process.", max_requests) + return True + + return False + + async def shutdown(self, sockets: list[socket.socket] | None = None) -> None: + logger.info("Shutting down") + + # Stop accepting new connections. + for server in self.servers: + server.close() + for sock in sockets or []: + sock.close() # pragma: full coverage + + # Request shutdown on all existing connections. + for connection in list(self.server_state.connections): + connection.shutdown() + await asyncio.sleep(0.1) + + # When 3.10 is not supported anymore, use `async with asyncio.timeout(...):`. + try: + await asyncio.wait_for( + self._wait_tasks_to_complete(), + timeout=self.config.timeout_graceful_shutdown, + ) + except asyncio.TimeoutError: + logger.error( + "Cancel %s running task(s), timeout graceful shutdown exceeded", + len(self.server_state.tasks), + ) + for t in self.server_state.tasks: + t.cancel(msg="Task cancelled, timeout graceful shutdown exceeded") + + # Send the lifespan shutdown event, and wait for application shutdown. + if not self.force_exit: + await self.lifespan.shutdown() + + async def _wait_tasks_to_complete(self) -> None: + # Wait for existing connections to finish sending responses. + if self.server_state.connections and not self.force_exit: + msg = "Waiting for connections to close. (CTRL+C to force quit)" + logger.info(msg) + while self.server_state.connections and not self.force_exit: + await asyncio.sleep(0.1) + + # Wait for existing tasks to complete. + if self.server_state.tasks and not self.force_exit: + msg = "Waiting for background tasks to complete. (CTRL+C to force quit)" + logger.info(msg) + while self.server_state.tasks and not self.force_exit: + await asyncio.sleep(0.1) + + for server in self.servers: + await server.wait_closed() + + @contextlib.contextmanager + def capture_signals(self) -> Generator[None, None, None]: + # Signals can only be listened to from the main thread. + if threading.current_thread() is not threading.main_thread(): + yield + return + # always use signal.signal, even if loop.add_signal_handler is available + # this allows to restore previous signal handlers later on + original_handlers = {sig: signal.signal(sig, self.handle_exit) for sig in HANDLED_SIGNALS} + try: + yield + finally: + for sig, handler in original_handlers.items(): + signal.signal(sig, handler) + # If we did gracefully shut down due to a signal, try to + # trigger the expected behaviour now; multiple signals would be + # done LIFO, see https://stackoverflow.com/questions/48434964 + for captured_signal in reversed(self._captured_signals): + signal.raise_signal(captured_signal) + + def handle_exit(self, sig: int, frame: FrameType | None) -> None: + self._captured_signals.append(sig) + if self.should_exit and sig == signal.SIGINT: + self.force_exit = True # pragma: full coverage + else: + self.should_exit = True diff --git a/.venv/Lib/site-packages/uvicorn/supervisors/__init__.py b/.venv/Lib/site-packages/uvicorn/supervisors/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..cfceb6b94ce36dad006b1f81b816d45ce70ab3d6 --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/supervisors/__init__.py @@ -0,0 +1,16 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +from uvicorn.supervisors.basereload import BaseReload +from uvicorn.supervisors.multiprocess import Multiprocess + +if TYPE_CHECKING: + ChangeReload: type[BaseReload] +else: + try: + from uvicorn.supervisors.watchfilesreload import WatchFilesReload as ChangeReload + except ImportError: # pragma: no cover + from uvicorn.supervisors.statreload import StatReload as ChangeReload + +__all__ = ["Multiprocess", "ChangeReload"] diff --git a/.venv/Lib/site-packages/uvicorn/supervisors/basereload.py b/.venv/Lib/site-packages/uvicorn/supervisors/basereload.py new file mode 100644 index 0000000000000000000000000000000000000000..d8cb4771a380ac490cf217be48e868a25979ef5d --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/supervisors/basereload.py @@ -0,0 +1,124 @@ +from __future__ import annotations + +import logging +import os +import signal +import sys +import threading +from collections.abc import Callable, Iterator +from pathlib import Path +from socket import socket +from types import FrameType + +from uvicorn._ansi import style +from uvicorn._subprocess import get_subprocess +from uvicorn.config import Config + +HANDLED_SIGNALS = ( + signal.SIGINT, # Unix signal 2. Sent by Ctrl+C. + signal.SIGTERM, # Unix signal 15. Sent by `kill `. +) + +logger = logging.getLogger("uvicorn.error") + + +class BaseReload: + def __init__( + self, + config: Config, + target: Callable[[list[socket] | None], None], + sockets: list[socket], + ) -> None: + self.config = config + self.target = target + self.sockets = sockets + self.should_exit = threading.Event() + self.pid = os.getpid() + self.is_restarting = False + self.reloader_name: str | None = None + + def signal_handler(self, sig: int, frame: FrameType | None) -> None: # pragma: full coverage + """ + A signal handler that is registered with the parent process. + """ + if sys.platform == "win32" and self.is_restarting: + self.is_restarting = False + else: + self.should_exit.set() + + def run(self) -> None: + self.startup() + for changes in self: + if changes: + logger.warning( + "%s detected changes in %s. Reloading...", + self.reloader_name, + ", ".join(map(_display_path, changes)), + ) + self.restart() + + self.shutdown() + + def pause(self) -> None: + if self.should_exit.wait(self.config.reload_delay): + raise StopIteration() + + def __iter__(self) -> Iterator[list[Path] | None]: + return self + + def __next__(self) -> list[Path] | None: + return self.should_restart() + + def startup(self) -> None: + message = f"Started reloader process [{self.pid}] using {self.reloader_name}" + color_message = "Started reloader process [{}] using {}".format( + style(str(self.pid), fg="cyan", bold=True), + style(str(self.reloader_name), fg="cyan", bold=True), + ) + logger.info(message, extra={"color_message": color_message}) + + for sig in HANDLED_SIGNALS: + signal.signal(sig, self.signal_handler) + + self.process = get_subprocess(config=self.config, target=self.target, sockets=self.sockets) + self.process.start() + + def restart(self) -> None: + if sys.platform == "win32": # pragma: py-not-win32 + self.is_restarting = True + assert self.process.pid is not None + os.kill(self.process.pid, signal.CTRL_C_EVENT) + + # This is a workaround to ensure the Ctrl+C event is processed + sys.stdout.write(" ") # This has to be a non-empty string + sys.stdout.flush() + else: # pragma: py-win32 + self.process.terminate() + self.process.join() + + self.process = get_subprocess(config=self.config, target=self.target, sockets=self.sockets) + self.process.start() + + def shutdown(self) -> None: + if sys.platform == "win32": + self.should_exit.set() # pragma: py-not-win32 + else: + self.process.terminate() # pragma: py-win32 + self.process.join() + + for sock in self.sockets: + sock.close() + + message = f"Stopping reloader process [{str(self.pid)}]" + color_message = "Stopping reloader process [{}]".format(style(str(self.pid), fg="cyan", bold=True)) + logger.info(message, extra={"color_message": color_message}) + + def should_restart(self) -> list[Path] | None: + raise NotImplementedError("Reload strategies should override should_restart()") + + +def _display_path(path: Path) -> str: + try: + return f"'{path.relative_to(Path.cwd())}'" + except ValueError: + return f"'{path}'" diff --git a/.venv/Lib/site-packages/uvicorn/supervisors/multiprocess.py b/.venv/Lib/site-packages/uvicorn/supervisors/multiprocess.py new file mode 100644 index 0000000000000000000000000000000000000000..ef2dd2d246521c1afc91990293f0e2d84c3e284c --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/supervisors/multiprocess.py @@ -0,0 +1,282 @@ +from __future__ import annotations + +import logging +import os +import pickle +import signal +import threading +import time +from multiprocessing import Pipe +from socket import socket + +from uvicorn._ansi import style +from uvicorn._subprocess import get_subprocess +from uvicorn.config import STARTUP_FAILURE, Config +from uvicorn.server import Server + +SIGNALS = { + getattr(signal, f"SIG{x}"): x + for x in "INT TERM BREAK HUP QUIT TTIN TTOU USR1 USR2 WINCH".split() + if hasattr(signal, f"SIG{x}") +} + +logger = logging.getLogger("uvicorn.error") + + +class Process: + def __init__( + self, + config: Config, + sockets: list[socket], + ) -> None: + self.config = config + self._server: Server | None = None + + self.parent_conn, self.child_conn = Pipe() + self.process = get_subprocess(config, self.target, sockets) + + def _healthcheck(self, timeout: float) -> bool | None: + """Receives a timeout and returns the worker's startup flag, or None if it does not answer in time.""" + try: + self.parent_conn.send(b"ping") + if self.parent_conn.poll(timeout): + started: bool = self.parent_conn.recv() + return started + return None + except (OSError, EOFError, pickle.UnpicklingError): + return None + + def ping(self, timeout: float = 5) -> bool: + """Receives a timeout and returns True if the worker answers a healthcheck in time.""" + return self._healthcheck(timeout) is not None + + def is_ready(self, timeout: float = 5) -> bool: + """Receives a timeout and returns True if the worker answers and its server has finished startup.""" + return self._healthcheck(timeout) is True + + def pong(self) -> None: + """Receives one healthcheck ping and replies with whether the server has finished startup.""" + self.child_conn.recv() + self.child_conn.send(self.server.started) + + def always_pong(self) -> None: + while True: + self.pong() + + def target(self, sockets: list[socket] | None = None) -> None: # pragma: no cover + if os.name == "nt": # pragma: py-not-win32 + # Windows doesn't support SIGTERM, so we use SIGBREAK instead. + # And then we raise SIGTERM when SIGBREAK is received. + # https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/reference/signal?view=msvc-170 + signal.signal( + signal.SIGBREAK, # type: ignore[attr-defined] + lambda sig, frame: signal.raise_signal(signal.SIGTERM), + ) + + threading.Thread(target=self.always_pong, daemon=True).start() + self.server.run(sockets) + + def is_alive(self, timeout: float = 5) -> bool: + if not self.process.is_alive(): + return False # pragma: full coverage + + return self.ping(timeout) + + def wait_until_ready(self, timeout: float, should_exit: threading.Event | None = None) -> bool: + """Receives a timeout and returns True if the worker starts serving, or False on exit, shutdown, or timeout.""" + deadline = time.monotonic() + timeout + while time.monotonic() < deadline: + if should_exit is not None and should_exit.is_set(): + return False + if not self.process.is_alive(): + return False + if self.is_ready(timeout=1): + return True + time.sleep(0.1) + return False + + def start(self) -> None: + self.process.start() + + def terminate(self) -> None: + if self.process.exitcode is None: # Process is still running + assert self.process.pid is not None + if os.name == "nt": # pragma: py-not-win32 + # Windows doesn't support SIGTERM. + # So send SIGBREAK, and then in process raise SIGTERM. + os.kill(self.process.pid, signal.CTRL_BREAK_EVENT) # type: ignore[attr-defined] + else: + os.kill(self.process.pid, signal.SIGTERM) + logger.info(f"Terminated child process [{self.process.pid}]") + + self.parent_conn.close() + self.child_conn.close() + + def kill(self) -> None: + # In Windows, the method will call `TerminateProcess` to kill the process. + # In Unix, the method will send SIGKILL to the process. + self.process.kill() + self.parent_conn.close() + self.child_conn.close() + + def join(self) -> None: + logger.info(f"Waiting for child process [{self.process.pid}]") + self.process.join() + + @property + def server(self) -> Server: + if self._server is None: + self._server = Server(config=self.config) + return self._server + + @property + def pid(self) -> int | None: + return self.process.pid + + @property + def exitcode(self) -> int | None: + return self.process.exitcode + + +class Multiprocess: + def __init__( + self, + config: Config, + sockets: list[socket], + ) -> None: + self.config = config + self.sockets = sockets + + self.processes_num = config.workers + self.processes: list[Process] = [] + + self.should_exit = threading.Event() + + self.signal_queue: list[int] = [] + for sig in SIGNALS: + signal.signal(sig, lambda sig, frame: self.signal_queue.append(sig)) + + def init_processes(self) -> None: + for _ in range(self.processes_num): + process = Process(self.config, self.sockets) + process.start() + self.processes.append(process) + + def terminate_all(self) -> None: + for process in self.processes: + process.terminate() + + def join_all(self) -> None: + for process in self.processes: + process.join() + + def restart_all(self) -> None: + """Replaces each worker, bringing its replacement into service before retiring the old worker.""" + for idx, old_process in enumerate(self.processes): + if self.should_exit.is_set(): + return + + new_process = Process(self.config, self.sockets) + new_process.start() + + if not new_process.wait_until_ready(self.config.timeout_worker_healthcheck, self.should_exit): + new_process.kill() + new_process.join() + if not self.should_exit.is_set(): + logger.error( + f"New child process [{new_process.pid}] was not ready in time; " + f"keeping worker [{old_process.pid}] and aborting the restart." + ) + return + + old_process.terminate() + old_process.join() + self.processes[idx] = new_process + + def run(self) -> None: + message = f"Started parent process [{os.getpid()}]" + color_message = "Started parent process [{}]".format(style(str(os.getpid()), fg="cyan", bold=True)) + logger.info(message, extra={"color_message": color_message}) + + self.init_processes() + + while not self.should_exit.wait(0.5): + self.handle_signals() + self.keep_subprocess_alive() + + self.terminate_all() + self.join_all() + + message = f"Stopping parent process [{os.getpid()}]" + color_message = "Stopping parent process [{}]".format(style(str(os.getpid()), fg="cyan", bold=True)) + logger.info(message, extra={"color_message": color_message}) + + def keep_subprocess_alive(self) -> None: + if self.should_exit.is_set(): + return # parent process is exiting, no need to keep subprocess alive + + for idx, process in enumerate(self.processes): + if process.is_alive(timeout=self.config.timeout_worker_healthcheck): + continue + + process.kill() # process is hung, kill it + process.join() + + if process.exitcode == STARTUP_FAILURE: + # The worker failed before it started serving, so the app, TLS or socket + # bind is broken and would fail the same way on every restart. + # See https://github.com/encode/uvicorn/discussions/2440. + logger.error(f"Child process [{process.pid}] failed to start, stopping the parent process.") + self.should_exit.set() + return + + if self.should_exit.is_set(): + return # pragma: full coverage + + logger.info(f"Child process [{process.pid}] died") + process = Process(self.config, self.sockets) + process.start() + self.processes[idx] = process + + def handle_signals(self) -> None: + for sig in tuple(self.signal_queue): + self.signal_queue.remove(sig) + sig_name = SIGNALS[sig] + sig_handler = getattr(self, f"handle_{sig_name.lower()}", None) + if sig_handler is not None: + sig_handler() + else: # pragma: no cover + logger.debug(f"Received signal {sig_name}, but no handler is defined for it.") + + def handle_int(self) -> None: + logger.info("Received SIGINT, exiting.") + self.should_exit.set() + + def handle_term(self) -> None: + logger.info("Received SIGTERM, exiting.") + self.should_exit.set() + + def handle_break(self) -> None: # pragma: py-not-win32 + logger.info("Received SIGBREAK, exiting.") + self.should_exit.set() + + def handle_hup(self) -> None: # pragma: py-win32 + logger.info("Received SIGHUP, restarting processes.") + self.restart_all() + + def handle_ttin(self) -> None: # pragma: py-win32 + logger.info("Received SIGTTIN, increasing the number of processes.") + self.processes_num += 1 + process = Process(self.config, self.sockets) + process.start() + self.processes.append(process) + + def handle_ttou(self) -> None: # pragma: py-win32 + logger.info("Received SIGTTOU, decreasing number of processes.") + if self.processes_num <= 1: + logger.info("Already reached one process, cannot decrease the number of processes anymore.") + return + self.processes_num -= 1 + process = self.processes.pop() + process.terminate() + process.join() diff --git a/.venv/Lib/site-packages/uvicorn/supervisors/statreload.py b/.venv/Lib/site-packages/uvicorn/supervisors/statreload.py new file mode 100644 index 0000000000000000000000000000000000000000..28693f9cc6d14ed8ea98518a78162e8c84f51c72 --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/supervisors/statreload.py @@ -0,0 +1,52 @@ +from __future__ import annotations + +import logging +from collections.abc import Callable, Iterator +from pathlib import Path +from socket import socket + +from uvicorn.config import Config +from uvicorn.supervisors.basereload import BaseReload + +logger = logging.getLogger("uvicorn.error") + + +class StatReload(BaseReload): + def __init__( + self, + config: Config, + target: Callable[[list[socket] | None], None], + sockets: list[socket], + ) -> None: + super().__init__(config, target, sockets) + self.reloader_name = "StatReload" + self.mtimes: dict[Path, float] = {} + + if config.reload_excludes or config.reload_includes: + logger.warning("--reload-include and --reload-exclude have no effect unless watchfiles is installed.") + + def should_restart(self) -> list[Path] | None: + self.pause() + + for file in self.iter_py_files(): + try: + mtime = file.stat().st_mtime + except OSError: # pragma: nocover + continue + + old_time = self.mtimes.get(file) + if old_time is None: + self.mtimes[file] = mtime + continue + elif mtime > old_time: + return [file] + return None + + def restart(self) -> None: + self.mtimes = {} + return super().restart() + + def iter_py_files(self) -> Iterator[Path]: + for reload_dir in self.config.reload_dirs: + for path in list(reload_dir.rglob("*.py")): + yield path.resolve() diff --git a/.venv/Lib/site-packages/uvicorn/supervisors/watchfilesreload.py b/.venv/Lib/site-packages/uvicorn/supervisors/watchfilesreload.py new file mode 100644 index 0000000000000000000000000000000000000000..600990595274dbc649176247c0c15840e59e0105 --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/supervisors/watchfilesreload.py @@ -0,0 +1,86 @@ +from __future__ import annotations + +from collections.abc import Callable +from pathlib import Path +from socket import socket + +from watchfiles import watch + +from uvicorn.config import Config +from uvicorn.supervisors.basereload import BaseReload + + +class FileFilter: + def __init__(self, config: Config): + default_includes = ["*.py"] + self.includes = [default for default in default_includes if default not in config.reload_excludes] + self.includes.extend(config.reload_includes) + self.includes = list(set(self.includes)) + + default_excludes = [".*", ".py[cod]", ".sw.*", "~*"] + self.excludes = [default for default in default_excludes if default not in config.reload_includes] + self.exclude_dirs = [] + for e in config.reload_excludes: + p = Path(e) + try: + is_dir = p.is_dir() + except OSError: # pragma: no cover + # gets raised on Windows for values like "*.py" + is_dir = False + + if is_dir: + self.exclude_dirs.append(p) + else: + self.excludes.append(e) # pragma: full coverage + self.excludes = list(set(self.excludes)) + + def __call__(self, path: Path) -> bool: + for include_pattern in self.includes: + if path.match(include_pattern): + if str(path).endswith(include_pattern): + return True # pragma: full coverage + + for exclude_dir in self.exclude_dirs: + if exclude_dir in path.parents: + return False + + for exclude_pattern in self.excludes: + if path.match(exclude_pattern): + return False # pragma: full coverage + + return True + return False + + +class WatchFilesReload(BaseReload): + def __init__( + self, + config: Config, + target: Callable[[list[socket] | None], None], + sockets: list[socket], + ) -> None: + super().__init__(config, target, sockets) + self.reloader_name = "WatchFiles" + self.reload_dirs: list[Path] = [] + for directory in config.reload_dirs: + self.reload_dirs.append(directory) + + self.watch_filter = FileFilter(config) + self.watcher = watch( + *self.reload_dirs, + watch_filter=None, + stop_event=self.should_exit, + # using yield_on_timeout here mostly to make sure tests don't + # hang forever, won't affect the class's behavior + yield_on_timeout=True, + ignore_permission_denied=True, + ) + + def should_restart(self) -> list[Path] | None: + self.pause() + + changes = next(self.watcher) + if changes: + unique_paths = {Path(c[1]) for c in changes} + return [p for p in unique_paths if self.watch_filter(p)] + return None diff --git a/.venv/Lib/site-packages/uvicorn/workers.py b/.venv/Lib/site-packages/uvicorn/workers.py new file mode 100644 index 0000000000000000000000000000000000000000..827d091c0f1693a43ae030b55e6ff79f7a552192 --- /dev/null +++ b/.venv/Lib/site-packages/uvicorn/workers.py @@ -0,0 +1,111 @@ +from __future__ import annotations + +import asyncio +import logging +import signal +import sys +import warnings +from typing import Any + +from gunicorn.arbiter import Arbiter +from gunicorn.workers.base import Worker + +from uvicorn._compat import asyncio_run +from uvicorn.config import Config +from uvicorn.server import Server + +warnings.warn( + "The `uvicorn.workers` module is deprecated. Please use `uvicorn-worker` package instead.\n" + "For more details, see https://github.com/Kludex/uvicorn-worker.", + DeprecationWarning, +) + + +class UvicornWorker(Worker): + """ + A worker class for Gunicorn that interfaces with an ASGI consumer callable, + rather than a WSGI callable. + """ + + CONFIG_KWARGS: dict[str, Any] = {"loop": "auto", "http": "auto"} + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + + logger = logging.getLogger("uvicorn.error") + logger.handlers = self.log.error_log.handlers + logger.setLevel(self.log.error_log.level) + logger.propagate = False + + logger = logging.getLogger("uvicorn.access") + logger.handlers = self.log.access_log.handlers + logger.setLevel(self.log.access_log.level) + logger.propagate = False + + config_kwargs: dict = { + "app": None, + "log_config": None, + "timeout_keep_alive": self.cfg.keepalive, + "timeout_notify": self.timeout, + "callback_notify": self.callback_notify, + "limit_max_requests": self.max_requests, + "forwarded_allow_ips": self.cfg.forwarded_allow_ips, + } + + if self.cfg.is_ssl: + ssl_kwargs = { + "ssl_keyfile": self.cfg.ssl_options.get("keyfile"), + "ssl_certfile": self.cfg.ssl_options.get("certfile"), + "ssl_keyfile_password": self.cfg.ssl_options.get("password"), + "ssl_version": self.cfg.ssl_options.get("ssl_version"), + "ssl_cert_reqs": self.cfg.ssl_options.get("cert_reqs"), + "ssl_ca_certs": self.cfg.ssl_options.get("ca_certs"), + "ssl_ciphers": self.cfg.ssl_options.get("ciphers"), + } + config_kwargs.update(ssl_kwargs) + + if self.cfg.settings["backlog"].value: + config_kwargs["backlog"] = self.cfg.settings["backlog"].value + + config_kwargs.update(self.CONFIG_KWARGS) + + self.config = Config(**config_kwargs) + + def init_signals(self) -> None: + # Reset signals so Gunicorn doesn't swallow subprocess return codes + # other signals are set up by Server.install_signal_handlers() + # See: https://github.com/Kludex/uvicorn/issues/894 + for s in self.SIGNALS: + signal.signal(s, signal.SIG_DFL) + + signal.signal(signal.SIGUSR1, self.handle_usr1) + # Don't let SIGUSR1 disturb active requests by interrupting system calls + signal.siginterrupt(signal.SIGUSR1, False) + + def _install_sigquit_handler(self) -> None: + """Install a SIGQUIT handler on workers. + + - https://github.com/Kludex/uvicorn/issues/1116 + - https://github.com/benoitc/gunicorn/issues/2604 + """ + + loop = asyncio.get_running_loop() + loop.add_signal_handler(signal.SIGQUIT, self.handle_exit, signal.SIGQUIT, None) + + async def _serve(self) -> None: + self.config.app = self.wsgi + server = Server(config=self.config) + self._install_sigquit_handler() + await server.serve(sockets=self.sockets) + if not server.started: + sys.exit(Arbiter.WORKER_BOOT_ERROR) + + def run(self) -> None: + return asyncio_run(self._serve(), loop_factory=self.config.get_loop_factory()) + + async def callback_notify(self) -> None: + self.notify() + + +class UvicornH11Worker(UvicornWorker): + CONFIG_KWARGS = {"loop": "asyncio", "http": "h11"} diff --git a/.venv/Lib/site-packages/watchdog-6.0.0.dist-info/AUTHORS b/.venv/Lib/site-packages/watchdog-6.0.0.dist-info/AUTHORS new file mode 100644 index 0000000000000000000000000000000000000000..8c3fed3232160b1d6e47313b0f3244b94e87ddcd --- /dev/null +++ b/.venv/Lib/site-packages/watchdog-6.0.0.dist-info/AUTHORS @@ -0,0 +1,73 @@ +Original Project Lead: +---------------------- +Yesudeep Mangalapilly + +Current Project Lead: +--------------------- +MickaΓ«l Schoentgen + +Contributors in alphabetical order: +----------------------------------- +Adrian Tejn Kern +Andrew Schaaf +Danilo de Jesus da Silva Bellini +David LaPalomento +dvogel +Filip Noetzel +Gary van der Merwe +gfxmonk +Gora Khargosh +Hannu Valtonen +Jesse Printz +Kurt McKee +LΓ©a Klein +Luke McCarthy +LukΓ‘Ε‘ LalinskΓ½ +Malthe Borch +Martin Kreichgauer +Martin Kreichgauer +Mike Lundy +Nicholas Hairs +Raymond Hettinger +Roman Ovchinnikov +Rotem Yaari +Ryan Kelly +Senko Rasic +Senko RaΕ‘iΔ‡ +Shane Hathaway +Simon Pantzare +Simon Pantzare +Steven Samuel Cole +StΓ©phane Klein +Thomas Guest +Thomas Heller +Tim Cuthbertson +Todd Whiteman +Will McGugan +Yesudeep Mangalapilly +Yesudeep Mangalapilly + +We would like to thank these individuals for ideas: +--------------------------------------------------- +Tim Golden +Sebastien Martini + +Initially we used the flask theme for the documentation which was written by +---------------------------------------------------------------------------- +Armin Ronacher + + +Watchdog also includes open source libraries or adapted code +from the following projects: + +- MacFSEvents - https://github.com/malthe/macfsevents +- watch_directory.py - http://timgolden.me.uk/python/downloads/watch_directory.py +- pyinotify - https://github.com/seb-m/pyinotify +- fsmonitor - https://github.com/shaurz/fsmonitor +- echo - http://wordaligned.org/articles/echo +- LukΓ‘Ε‘ LalinskΓ½'s ordered set queue implementation: + https://stackoverflow.com/questions/1581895/how-check-if-a-task-is-already-in-python-queue +- Armin Ronacher's flask-sphinx-themes for the documentation: + https://github.com/mitsuhiko/flask-sphinx-themes +- pyfilesystem - https://github.com/PyFilesystem/pyfilesystem +- get_FILE_NOTIFY_INFORMATION - http://blog.gmane.org/gmane.comp.python.ctypes/month=20070901 diff --git a/.venv/Lib/site-packages/watchdog-6.0.0.dist-info/COPYING b/.venv/Lib/site-packages/watchdog-6.0.0.dist-info/COPYING new file mode 100644 index 0000000000000000000000000000000000000000..b84e0b3c8468ff4672c6f1c5a88cb28c3eb067d7 --- /dev/null +++ b/.venv/Lib/site-packages/watchdog-6.0.0.dist-info/COPYING @@ -0,0 +1,16 @@ +Copyright 2018-2024 MickaΓ«l Schoentgen & contributors +Copyright 2014-2018 Thomas Amland & contributors +Copyright 2012-2014 Google, Inc. +Copyright 2011-2012 Yesudeep Mangalapilly + +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. diff --git a/.venv/Lib/site-packages/watchdog-6.0.0.dist-info/INSTALLER b/.venv/Lib/site-packages/watchdog-6.0.0.dist-info/INSTALLER new file mode 100644 index 0000000000000000000000000000000000000000..a1b589e38a32041e49332e5e81c2d363dc418d68 --- /dev/null +++ b/.venv/Lib/site-packages/watchdog-6.0.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/Lib/site-packages/watchdog-6.0.0.dist-info/LICENSE b/.venv/Lib/site-packages/watchdog-6.0.0.dist-info/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..d645695673349e3947e8e5ae42332d0ac3164cd7 --- /dev/null +++ b/.venv/Lib/site-packages/watchdog-6.0.0.dist-info/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/.venv/Lib/site-packages/watchdog-6.0.0.dist-info/METADATA b/.venv/Lib/site-packages/watchdog-6.0.0.dist-info/METADATA new file mode 100644 index 0000000000000000000000000000000000000000..c07e04826b72f772da0ceeaf4205567cba500183 --- /dev/null +++ b/.venv/Lib/site-packages/watchdog-6.0.0.dist-info/METADATA @@ -0,0 +1,878 @@ +Metadata-Version: 2.1 +Name: watchdog +Version: 6.0.0 +Summary: Filesystem events monitoring +Home-page: https://github.com/gorakhargosh/watchdog +Author: MickaΓ«l Schoentgen +Author-email: contact@tiger-222.fr +License: Apache-2.0 +Project-URL: Documentation, https://python-watchdog.readthedocs.io/en/stable/ +Project-URL: Source, https://github.com/gorakhargosh/watchdog/ +Project-URL: Issues, https://github.com/gorakhargosh/watchdog/issues +Project-URL: Changelog, https://github.com/gorakhargosh/watchdog/blob/master/changelog.rst +Keywords: python filesystem monitoring monitor FSEvents kqueue inotify ReadDirectoryChangesW polling DirectorySnapshot +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Console +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: System Administrators +Classifier: License :: OSI Approved :: Apache Software License +Classifier: Natural Language :: English +Classifier: Operating System :: POSIX :: Linux +Classifier: Operating System :: MacOS :: MacOS X +Classifier: Operating System :: POSIX :: BSD +Classifier: Operating System :: Microsoft :: Windows :: Windows Vista +Classifier: Operating System :: Microsoft :: Windows :: Windows 7 +Classifier: Operating System :: Microsoft :: Windows :: Windows 8 +Classifier: Operating System :: Microsoft :: Windows :: Windows 8.1 +Classifier: Operating System :: Microsoft :: Windows :: Windows 10 +Classifier: Operating System :: Microsoft :: Windows :: Windows 11 +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3 :: Only +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Classifier: Programming Language :: C +Classifier: Topic :: Software Development :: Libraries +Classifier: Topic :: System :: Monitoring +Classifier: Topic :: System :: Filesystems +Classifier: Topic :: Utilities +Requires-Python: >=3.9 +Description-Content-Type: text/x-rst +License-File: LICENSE +License-File: COPYING +License-File: AUTHORS +Provides-Extra: watchmedo +Requires-Dist: PyYAML>=3.10; extra == "watchmedo" + +Watchdog +======== + +|PyPI Version| +|PyPI Status| +|PyPI Python Versions| +|GitHub Build Status| +|GitHub License| + +Python API and shell utilities to monitor file system events. + +Works on 3.9+. + +Example API Usage +----------------- + +A simple program that uses watchdog to monitor directories specified +as command-line arguments and logs events generated: + +.. code-block:: python + + import time + + from watchdog.events import FileSystemEvent, FileSystemEventHandler + from watchdog.observers import Observer + + + class MyEventHandler(FileSystemEventHandler): + def on_any_event(self, event: FileSystemEvent) -> None: + print(event) + + + event_handler = MyEventHandler() + observer = Observer() + observer.schedule(event_handler, ".", recursive=True) + observer.start() + try: + while True: + time.sleep(1) + finally: + observer.stop() + observer.join() + + +Shell Utilities +--------------- + +Watchdog comes with an *optional* utility script called ``watchmedo``. +Please type ``watchmedo --help`` at the shell prompt to +know more about this tool. + +Here is how you can log the current directory recursively +for events related only to ``*.py`` and ``*.txt`` files while +ignoring all directory events: + +.. code-block:: bash + + watchmedo log \ + --patterns='*.py;*.txt' \ + --ignore-directories \ + --recursive \ + --verbose \ + . + +You can use the ``shell-command`` subcommand to execute shell commands in +response to events: + +.. code-block:: bash + + watchmedo shell-command \ + --patterns='*.py;*.txt' \ + --recursive \ + --command='echo "${watch_src_path}"' \ + . + +Please see the help information for these commands by typing: + +.. code-block:: bash + + watchmedo [command] --help + + +About ``watchmedo`` Tricks +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``watchmedo`` can read ``tricks.yaml`` files and execute tricks within them in +response to file system events. Tricks are actually event handlers that +subclass ``watchdog.tricks.Trick`` and are written by plugin authors. Trick +classes are augmented with a few additional features that regular event handlers +don't need. + +An example ``tricks.yaml`` file: + +.. code-block:: yaml + + tricks: + - watchdog.tricks.LoggerTrick: + patterns: ["*.py", "*.js"] + - watchmedo_webtricks.GoogleClosureTrick: + patterns: ['*.js'] + hash_names: true + mappings_format: json # json|yaml|python + mappings_module: app/javascript_mappings + suffix: .min.js + compilation_level: advanced # simple|advanced + source_directory: app/static/js/ + destination_directory: app/public/js/ + files: + index-page: + - app/static/js/vendor/jquery*.js + - app/static/js/base.js + - app/static/js/index-page.js + about-page: + - app/static/js/vendor/jquery*.js + - app/static/js/base.js + - app/static/js/about-page/**/*.js + +The directory containing the ``tricks.yaml`` file will be monitored. Each trick +class is initialized with its corresponding keys in the ``tricks.yaml`` file as +arguments and events are fed to an instance of this class as they arrive. + +Installation +------------ +Install from PyPI using ``pip``: + +.. code-block:: bash + + $ python -m pip install -U watchdog + + # or to install the watchmedo utility: + $ python -m pip install -U 'watchdog[watchmedo]' + +Install from source: + +.. code-block:: bash + + $ python -m pip install -e . + + # or to install the watchmedo utility: + $ python -m pip install -e '.[watchmedo]' + + +Documentation +------------- + +You can browse the latest release documentation_ online. + +Contribute +---------- + +Fork the `repository`_ on GitHub and send a pull request, or file an issue +ticket at the `issue tracker`_. For general help and questions use +`stackoverflow`_ with tag `python-watchdog`. + +Create and activate your virtual environment, then:: + + python -m pip install tox + python -m tox [-q] [-e ENV] + +If you are making a substantial change, add an entry to the "Unreleased" section +of the `changelog`_. + +Supported Platforms +------------------- + +* Linux 2.6 (inotify) +* macOS (FSEvents, kqueue) +* FreeBSD/BSD (kqueue) +* Windows (ReadDirectoryChangesW with I/O completion ports; + ReadDirectoryChangesW worker threads) +* OS-independent (polling the disk for directory snapshots and comparing them + periodically; slow and not recommended) + +Note that when using watchdog with kqueue, you need the +number of file descriptors allowed to be opened by programs +running on your system to be increased to more than the +number of files that you will be monitoring. The easiest way +to do that is to edit your ``~/.profile`` file and add +a line similar to:: + + ulimit -n 1024 + +This is an inherent problem with kqueue because it uses +file descriptors to monitor files. That plus the enormous +amount of bookkeeping that watchdog needs to do in order +to monitor file descriptors just makes this a painful way +to monitor files and directories. In essence, kqueue is +not a very scalable way to monitor a deeply nested +directory of files and directories with a large number of +files. + +About using watchdog with editors like Vim +------------------------------------------ + +Vim does not modify files unless directed to do so. +It creates backup files and then swaps them in to replace +the files you are editing on the disk. This means that +if you use Vim to edit your files, the on-modified events +for those files will not be triggered by watchdog. +You may need to configure Vim appropriately to disable +this feature. + + +About using watchdog with CIFS +------------------------------ + +When you want to watch changes in CIFS, you need to explicitly tell watchdog to +use ``PollingObserver``, that is, instead of letting watchdog decide an +appropriate observer like in the example above, do:: + + from watchdog.observers.polling import PollingObserver as Observer + + +Dependencies +------------ + +1. Python 3.9 or above. +2. XCode_ (only on macOS when installing from sources) +3. PyYAML_ (only for ``watchmedo``) + +Licensing +--------- + +Watchdog is licensed under the terms of the `Apache License, version 2.0`_. + +- Copyright 2018-2024 MickaΓ«l Schoentgen & contributors +- Copyright 2014-2018 Thomas Amland & contributors +- Copyright 2012-2014 Google, Inc. +- Copyright 2011-2012 Yesudeep Mangalapilly + +Project `source code`_ is available at Github. Please report bugs and file +enhancement requests at the `issue tracker`_. + +Why Watchdog? +------------- + +Too many people tried to do the same thing and none did what I needed Python +to do: + +* pnotify_ +* `unison fsmonitor`_ +* fsmonitor_ +* guard_ +* pyinotify_ +* `inotify-tools`_ +* jnotify_ +* treewatcher_ +* `file.monitor`_ +* pyfilesystem_ + +.. links: +.. _Yesudeep Mangalapilly: yesudeep@gmail.com +.. _source code: https://github.com/gorakhargosh/watchdog +.. _issue tracker: https://github.com/gorakhargosh/watchdog/issues +.. _Apache License, version 2.0: https://www.apache.org/licenses/LICENSE-2.0 +.. _documentation: https://python-watchdog.readthedocs.io/ +.. _stackoverflow: https://stackoverflow.com/questions/tagged/python-watchdog +.. _repository: https://github.com/gorakhargosh/watchdog +.. _issue tracker: https://github.com/gorakhargosh/watchdog/issues +.. _changelog: https://github.com/gorakhargosh/watchdog/blob/master/changelog.rst + +.. _PyYAML: https://www.pyyaml.org/ +.. _XCode: https://developer.apple.com/technologies/tools/xcode.html + +.. _pnotify: http://mark.heily.com/pnotify +.. _unison fsmonitor: https://webdav.seas.upenn.edu/viewvc/unison/trunk/src/fsmonitor.py?view=markup&pathrev=471 +.. _fsmonitor: https://github.com/shaurz/fsmonitor +.. _guard: https://github.com/guard/guard +.. _pyinotify: https://github.com/seb-m/pyinotify +.. _inotify-tools: https://github.com/rvoicilas/inotify-tools +.. _jnotify: http://jnotify.sourceforge.net/ +.. _treewatcher: https://github.com/jbd/treewatcher +.. _file.monitor: https://github.com/pke/file.monitor +.. _pyfilesystem: https://github.com/PyFilesystem/pyfilesystem + +.. |PyPI Version| image:: https://img.shields.io/pypi/v/watchdog.svg + :target: https://pypi.python.org/pypi/watchdog/ +.. |PyPI Status| image:: https://img.shields.io/pypi/status/watchdog.svg + :target: https://pypi.python.org/pypi/watchdog/ +.. |PyPI Python Versions| image:: https://img.shields.io/pypi/pyversions/watchdog.svg + :target: https://pypi.python.org/pypi/watchdog/ +.. |Github Build Status| image:: https://github.com/gorakhargosh/watchdog/workflows/Tests/badge.svg + :target: https://github.com/gorakhargosh/watchdog/actions?query=workflow%3ATests +.. |GitHub License| image:: https://img.shields.io/github/license/gorakhargosh/watchdog.svg + :target: https://github.com/gorakhargosh/watchdog/blob/master/LICENSE + + +.. :changelog: + +Changelog +--------- + +6.0.0 +~~~~~ + +2024-11-01 β€’ `full history `__ + +- Pin test dependecies. +- [docs] Add typing info to quick start. (`#1082 `__) +- [inotify] Use of ``select.poll()`` instead of deprecated ``select.select()``, if available. (`#1078 `__) +- [inotify] Fix reading inotify file descriptor after closing it. (`#1081 `__) +- [utils] The ``stop_signal`` keyword-argument type of the ``AutoRestartTrick`` class can now be either a ``signal.Signals`` or an ``int``. +- [utils] Added the ``__repr__()`` method to the ``Trick`` class. +- [utils] Removed the unused ``echo_class()`` function from the ``echo`` module. +- [utils] Removed the unused ``echo_instancemethod()`` function from the ``echo`` module. +- [utils] Removed the unused ``echo_module()`` function from the ``echo`` module. +- [utils] Removed the unused ``is_class_private_name()`` function from the ``echo`` module. +- [utils] Removed the unused ``is_classmethod()`` function from the ``echo`` module. +- [utils] Removed the unused ``ic_method(met()`` function from the ``echo`` module. +- [utils] Removed the unused ``method_name()`` function from the ``echo`` module. +- [utils] Removed the unused ``name()`` function from the ``echo`` module. +- [watchmedo] Fixed Mypy issues. +- [watchmedo] Added the ``__repr__()`` method to the ``HelpFormatter`` class. +- [watchmedo] Removed the ``--trace`` CLI argument from the ``watchmedo log`` command, useless since events are logged by default at the ``LoggerTrick`` class level. +- [windows] Fixed Mypy issues. +- Thanks to our beloved contributors: @BoboTiG, @g-pichlern, @ethan-vanderheijden, @nhairs + +5.0.3 +~~~~~ + +2024-09-27 β€’ `full history `__ + +- [inotify] Improve cleaning up ``Inotify`` threads, and add ``eventlet`` test cases (`#1070 `__) +- Thanks to our beloved contributors: @BoboTiG, @ethan-vanderheijden + +5.0.2 +~~~~~ + +2024-09-03 β€’ `full history `__ + +- Enable OS specific Mypy checks (`#1064 `__) +- [watchmedo] Fix ``tricks`` argument type of ``schedule_tricks()`` (`#1063 `__) +- Thanks to our beloved contributors: @gnought, @BoboTiG + +5.0.1 +~~~~~ + +2024-09-02 β€’ `full history `__ + +- [kqueue] Fix ``TypeError: kqueue.control() only accepts positional parameters`` (`#1062 `__) +- Thanks to our beloved contributors: @apoirier, @BoboTiG + +5.0.0 +~~~~~ + +2024-08-26 β€’ `full history `__ + +**Breaking Changes** + +- Drop support for Python 3.8 (`#1055 `__) +- [core] Enforced usage of proper keyword-arguments (`#1057 `__) +- [core] Renamed the ``BaseObserverSubclassCallable`` class to ``ObserverType`` (`#1055 `__) +- [inotify] Renamed the ``inotify_event_struct`` class to ``InotifyEventStruct`` (`#1055 `__) +- [inotify] Renamed the ``UnsupportedLibc`` exception to ``UnsupportedLibcError`` (`#1057 `__) +- [inotify] Removed the ``InotifyConstants.IN_CLOSE`` constant (`#1046 `__) +- [watchmedo] Renamed the ``LogLevelException`` exception to ``LogLevelError`` (`#1057 `__) +- [watchmedo] Renamed the ``WatchdogShutdown`` exception to ``WatchdogShutdownError`` (`#1057 `__) +- [windows] Renamed the ``FILE_NOTIFY_INFORMATION`` class to ``FileNotifyInformation`` (`#1055 `__) +- [windows] Removed the unused ``WATCHDOG_TRAVERSE_MOVED_DIR_DELAY`` constant (`#1057 `__) + +**Other Changes** + +- [core] Enable ``disallow_untyped_calls`` Mypy rule (`#1055 `__) +- [core] Enable ``disallow_untyped_defs`` Mypy rule (`#1060 `__) +- [core] Improve typing references for events (`#1040 `__) +- [inotify] Add support for ``IN_CLOSE_NOWRITE`` events. A ``FileClosedNoWriteEvent`` event will be fired, and its ``on_closed_no_write()`` dispatcher has been introduced (`#1046 `__) +- Thanks to our beloved contributors: @BoboTiG + +4.0.2 +~~~~~ + +2024-08-11 β€’ `full history `__ + +- Add support for Python 3.13 (`#1052 `__) +- [core] Run ``ruff``, apply several fixes (`#1033 `__) +- [core] Remove execution rights from ``events.py`` +- [documentation] Update ``PatternMatchingEventHandler`` docstrings (`#1048 `__) +- [documentation] Simplify the quickstart example (`#1047 `__) +- [fsevents] Add missing ``event_filter`` keyword-argument to ``FSEventsObserver.schedule()`` (`#1049 `__) +- [utils] Fix a possible race condition in ``AutoRestartTrick`` (`#1002 `__) +- [watchmedo] Remove execution rights from ``watchmedo.py`` +- Thanks to our beloved contributors: @BoboTiG, @nbelakovski, @ivg + +4.0.1 +~~~~~ + +2024-05-23 β€’ `full history `__ + +- [inotify] Fix missing ``event_filter`` for the full emitter (`#1032 `__) +- Thanks to our beloved contributors: @mraspaud, @BoboTiG + +4.0.0 +~~~~~ + +2024-02-06 β€’ `full history `__ + +- Drop support for Python 3.7. +- Add support for Python 3.12. +- [snapshot] Add typing to ``dirsnapshot`` (`#1012 `__) +- [snapshot] Added ``DirectorySnapshotDiff.ContextManager`` (`#1011 `__) +- [events] ``FileSystemEvent``, and subclasses, are now ``dataclass``es, and their ``repr()`` has changed +- [windows] ``WinAPINativeEvent`` is now a ``dataclass``, and its ``repr()`` has changed +- [events] Log ``FileOpenedEvent``, and ``FileClosedEvent``, events in ``LoggingEventHandler`` +- [tests] Improve ``FileSystemEvent`` coverage +- [watchmedo] Log all events in ``LoggerTrick`` +- [windows] The ``observers.read_directory_changes.WATCHDOG_TRAVERSE_MOVED_DIR_DELAY`` hack was removed. The constant will be kept to prevent breaking other softwares. +- Thanks to our beloved contributors: @BoboTiG, @msabramo + +3.0.0 +~~~~~ + +2023-03-20 β€’ `full history `__ + +- Drop support for Python 3.6. +- ``watchdog`` is now PEP 561 compatible, and tested with ``mypy`` +- Fix missing ``>`` in ``FileSystemEvent.__repr__()`` (`#980 `__) +- [ci] Lots of improvements +- [inotify] Return from ``InotifyEmitter.queue_events()`` if not launched when thread is inactive (`#963 `__) +- [tests] Stability improvements +- [utils] Remove handling of ``threading.Event.isSet`` spelling (`#962 `__) +- [watchmedo] Fixed tricks YAML generation (`#965 `__) +- Thanks to our beloved contributors: @kurtmckee, @altendky, @agroszer, @BoboTiG + +2.3.1 +~~~~~ + +2023-02-28 β€’ `full history `__ + +- Run ``black`` on the entire source code +- Bundle the ``requirements-tests.txt`` file in the source distribution (`#939 `__) +- [watchmedo] Exclude ``FileOpenedEvent`` events from ``AutoRestartTrick``, and ``ShellCommandTrick``, to restore watchdog < 2.3.0 behavior. A better solution should be found in the future. (`#949 `__) +- [watchmedo] Log ``FileOpenedEvent``, and ``FileClosedEvent``, events in ``LoggerTrick`` +- Thanks to our beloved contributors: @BoboTiG + +2.3.0 +~~~~~ + +2023-02-23 β€’ `full history `__ + +- [inotify] Add support for ``IN_OPEN`` events: a ``FileOpenedEvent`` event will be fired (`#941 `__) +- [watchmedo] Add optional event debouncing for ``auto-restart``, only restarting once if many events happen in quick succession (``--debounce-interval``) (`#940 `__) +- [watchmedo] Exit gracefully on ``KeyboardInterrupt`` exception (Ctrl+C) (`#945 `__) +- [watchmedo] Add option to not auto-restart the command after it exits (``--no-restart-on-command-exit``) (`#946 `__) +- Thanks to our beloved contributors: @BoboTiG, @dstaple, @taleinat, @cernekj + +2.2.1 +~~~~~ + +2023-01-01 β€’ `full history `__ + +- Enable ``mypy`` to discover type hints as specified in PEP 561 (`#933 `__) +- [ci] Set the expected Python version when building release files +- [ci] Update actions versions in use +- [watchmedo] [regression] Fix usage of missing ``signal.SIGHUP`` attribute on non-Unix OSes (`#935 `__) +- Thanks to our beloved contributors: @BoboTiG, @simon04, @piotrpdev + +2.2.0 +~~~~~ + +2022-12-05 β€’ `full history `__ + +- [build] Wheels are now available for Python 3.11 (`#932 `__) +- [documentation] HTML documentation builds are now tested for errors (`#902 `__) +- [documentation] Fix typos here, and there (`#910 `__) +- [fsevents2] The ``fsevents2`` observer is now deprecated (`#909 `__) +- [tests] The error message returned by musl libc for error code ``-1`` is now allowed (`#923 `__) +- [utils] Remove unnecessary code in ``dirsnapshot.py`` (`#930 `__) +- [watchmedo] Handle shutdown events from ``SIGHUP`` (`#912 `__) +- Thanks to our beloved contributors: @kurtmckee, @babymastodon, @QuantumEnergyE, @timgates42, @BoboTiG + +2.1.9 +~~~~~ + +2022-06-10 β€’ `full history `__ + +- [fsevents] Fix flakey test to assert that there are no errors when stopping the emitter. +- [inotify] Suppress occasional ``OSError: [Errno 9] Bad file descriptor`` at shutdown. (`#805 `__) +- [watchmedo] Make ``auto-restart`` restart the sub-process if it terminates. (`#896 `__) +- [watchmedo] Avoid zombie sub-processes when running ``shell-command`` without ``--wait``. (`#405 `__) +- Thanks to our beloved contributors: @samschott, @taleinat, @altendky, @BoboTiG + +2.1.8 +~~~~~ + +2022-05-15 β€’ `full history `__ + +- Fix adding failed emitters on observer schedule. (`#872 `__) +- [inotify] Fix hang when unscheduling watch on a path in an unmounted filesystem. (`#869 `__) +- [watchmedo] Fix broken parsing of ``--kill-after`` argument for the ``auto-restart`` command. (`#870 `__) +- [watchmedo] Fix broken parsing of boolean arguments. (`#887 `__) +- [watchmedo] Fix broken parsing of commands from ``auto-restart``, and ``shell-command``. (`#888 `__) +- [watchmedo] Support setting verbosity level via ``-q/--quiet`` and ``-v/--verbose`` arguments. (`#889 `__) +- Thanks to our beloved contributors: @taleinat, @kianmeng, @palfrey, @IlayRosenberg, @BoboTiG + +2.1.7 +~~~~~ + +2022-03-25 β€’ `full history `__ + +- Eliminate timeout in waiting on event queue. (`#861 `__) +- [inotify] Fix ``not`` equality implementation for ``InotifyEvent``. (`#848 `__) +- [watchmedo] Fix calling commands from within a Python script. (`#879 `__) +- [watchmedo] ``PyYAML`` is loaded only when strictly necessary. Simple usages of ``watchmedo`` are possible without the module being installed. (`#847 `__) +- Thanks to our beloved contributors: @sattlerc, @JanzenLiu, @BoboTiG + +2.1.6 +~~~~~ + +2021-10-01 β€’ `full history `__ + +- [bsd] Fixed returned paths in ``kqueue.py`` and restored the overall results of the test suite. (`#842 `__) +- [bsd] Updated FreeBSD CI support .(`#841 `__) +- [watchmedo] Removed the ``argh`` dependency in favor of the builtin ``argparse`` module. (`#836 `__) +- [watchmedo] Removed unexistant ``WindowsApiAsyncObserver`` references and ``--debug-force-winapi-async`` arguments. +- [watchmedo] Improved the help output. +- Thanks to our beloved contributors: @knobix, @AndreaRe9, @BoboTiG + +2.1.5 +~~~~~ + +2021-08-23 β€’ `full history `__ + +- Fix regression introduced in 2.1.4 (reverted "Allow overriding or adding custom event handlers to event dispatch map. (`#814 `__)"). (`#830 `__) +- Convert regexes of type ``str`` to ``list``. (`831 `__) +- Thanks to our beloved contributors: @unique1o1, @BoboTiG + +2.1.4 +~~~~~ + +2021-08-19 β€’ `full history `__ + +- [watchmedo] Fix usage of ``os.setsid()`` and ``os.killpg()`` Unix-only functions. (`#809 `__) +- [mac] Fix missing ``FileModifiedEvent`` on permission or ownership changes of a file. (`#815 `__) +- [mac] Convert absolute watch path in ``FSEeventsEmitter`` with ``os.path.realpath()``. (`#822 `__) +- Fix a possible ``AttributeError`` in ``SkipRepeatsQueue._put()``. (`#818 `__) +- Allow overriding or adding custom event handlers to event dispatch map. (`#814 `__) +- Fix tests on big endian platforms. (`#828 `__) +- Thanks to our beloved contributors: @replabrobin, @BoboTiG, @SamSchott, @AndreiB97, @NiklasRosenstein, @ikokollari, @mgorny + +2.1.3 +~~~~~ + +2021-06-26 β€’ `full history `__ + +- Publish macOS ``arm64`` and ``universal2`` wheels. (`#740 `__) +- Thanks to our beloved contributors: @kainjow, @BoboTiG + +2.1.2 +~~~~~ + +2021-05-19 β€’ `full history `__ + +- [mac] Fix relative path handling for non-recursive watch. (`#797 `__) +- [windows] On PyPy, events happening right after ``start()`` were missed. Add a workaround for that. (`#796 `__) +- Thanks to our beloved contributors: @oprypin, @CCP-Aporia, @BoboTiG + +2.1.1 +~~~~~ + +2021-05-10 β€’ `full history `__ + +- [mac] Fix callback exceptions when the watcher is deleted but still receiving events (`#786 `__) +- Thanks to our beloved contributors: @rom1win, @BoboTiG, @CCP-Aporia + + +2.1.0 +~~~~~ + +2021-05-04 β€’ `full history `__ + +- [inotify] Simplify ``libc`` loading (`#776 `__) +- [mac] Add support for non-recursive watches in ``FSEventsEmitter`` (`#779 `__) +- [watchmedo] Add support for ``--debug-force-*`` arguments to ``tricks`` (`#781 `__) +- Thanks to our beloved contributors: @CCP-Aporia, @aodj, @UnitedMarsupials, @BoboTiG + + +2.0.3 +~~~~~ + +2021-04-22 β€’ `full history `__ + +- [mac] Use ``logger.debug()`` instead of ``logger.info()`` (`#774 `__) +- Updated documentation links (`#777 `__) +- Thanks to our beloved contributors: @globau, @imba-tjd, @BoboTiG + + +2.0.2 +~~~~~ + +2021-02-22 β€’ `full history `__ + +- [mac] Add missing exception objects (`#766 `__) +- Thanks to our beloved contributors: @CCP-Aporia, @BoboTiG + + +2.0.1 +~~~~~ + +2021-02-17 β€’ `full history `__ + +- [mac] Fix a segmentation fault when dealing with unicode paths (`#763 `__) +- Moved the CI from Travis-CI to GitHub Actions (`#764 `__) +- Thanks to our beloved contributors: @SamSchott, @BoboTiG + + +2.0.0 +~~~~~ + +2021-02-11 β€’ `full history `__ + +- Avoid deprecated ``PyEval_InitThreads`` on Python 3.7+ (`#746 `__) +- [inotify] Add support for ``IN_CLOSE_WRITE`` events. A ``FileCloseEvent`` event will be fired. Note that ``IN_CLOSE_NOWRITE`` events are not handled to prevent much noise. (`#184 `__, `#245 `__, `#280 `__, `#313 `__, `#690 `__) +- [inotify] Allow to stop the emitter multiple times (`#760 `__) +- [mac] Support coalesced filesystem events (`#734 `__) +- [mac] Drop support for macOS 10.12 and earlier (`#750 `__) +- [mac] Fix an issue when renaming an item changes only the casing (`#750 `__) +- Thanks to our beloved contributors: @bstaletic, @lukassup, @ysard, @SamSchott, @CCP-Aporia, @BoboTiG + + +1.0.2 +~~~~~ + +2020-12-18 β€’ `full history `__ + +- Wheels are published for GNU/Linux, macOS and Windows (`#739 `__) +- [mac] Fix missing ``event_id`` attribute in ``fsevents`` (`#721 `__) +- [mac] Return byte paths if a byte path was given in ``fsevents`` (`#726 `__) +- [mac] Add compatibility with old macOS versions (`#733 `__) +- Uniformize event for deletion of watched dir (`#727 `__) +- Thanks to our beloved contributors: @SamSchott, @CCP-Aporia, @di, @BoboTiG + + +1.0.1 +~~~~~ + +2020-12-10 β€’ Fix version with good metadatas. + + +1.0.0 +~~~~~ + +2020-12-10 β€’ `full history `__ + +- Versioning is now following the `semver `__ +- Drop support for Python 2.7, 3.4 and 3.5 +- [mac] Regression fixes for native ``fsevents`` (`#717 `__) +- [windows] ``winapi.BUFFER_SIZE`` now defaults to ``64000`` (instead of ``2048``) (`#700 `__) +- [windows] Introduced ``winapi.PATH_BUFFER_SIZE`` (defaults to ``2048``) to keep the old behavior with path-realted functions (`#700 `__) +- Use ``pathlib`` from the standard library, instead of pathtools (`#556 `__) +- Allow file paths on Unix that don't follow the file system encoding (`#703 `__) +- Removed the long-time deprecated ``events.LoggingFileSystemEventHandler`` class, use ``LoggingEventHandler`` instead +- Thanks to our beloved contributors: @SamSchott, @bstaletic, @BoboTiG, @CCP-Aporia + + +0.10.4 +~~~~~~ + +2020-11-21 β€’ `full history `__ + +- Add ``logger`` parameter for the ``LoggingEventHandler`` (`#676 `__) +- Replace mutable default arguments with ``if None`` implementation (`#677 `__) +- Expand tests to Python 2.7 and 3.5-3.10 for GNU/Linux, macOS and Windows +- [mac] Performance improvements for the ``fsevents`` module (`#680 `__) +- [mac] Prevent compilation of ``watchdog_fsevents.c`` on non-macOS machines (`#687 `__) +- [watchmedo] Handle shutdown events from ``SIGTERM`` and ``SIGINT`` more reliably (`#693 `__) +- Thanks to our beloved contributors: @Sraw, @CCP-Aporia, @BoboTiG, @maybe-sybr + + +0.10.3 +~~~~~~ + +2020-06-25 β€’ `full history `__ + +- Ensure ``ObservedWatch.path`` is a string (`#651 `__) +- [inotify] Allow to monitor single file (`#655 `__) +- [inotify] Prevent raising an exception when a file in a monitored folder has no permissions (`#669 `__, `#670 `__) +- Thanks to our beloved contributors: @brant-ruan, @rec, @andfoy, @BoboTiG + + +0.10.2 +~~~~~~ + +2020-02-08 β€’ `full history `__ + +- Fixed the ``build_ext`` command on macOS Catalina (`#628 `__) +- Fixed the installation of macOS requirements on non-macOS OSes (`#635 `__) +- Refactored ``dispatch()`` method of ``FileSystemEventHandler``, + ``PatternMatchingEventHandler`` and ``RegexMatchingEventHandler`` +- [bsd] Improved tests support on non Windows/Linux platforms (`#633 `__, `#639 `__) +- [bsd] Added FreeBSD CI support (`#532 `__) +- [bsd] Restored full support (`#638 `__, `#641 `__) +- Thanks to our beloved contributors: @BoboTiG, @evilham, @danilobellini + + +0.10.1 +~~~~~~ + +2020-01-30 β€’ `full history `__ + +- Fixed Python 2.7 to 3.6 installation when the OS locale is set to POSIX (`#615 `__) +- Fixed the ``build_ext`` command on macOS (`#618 `__, `#620 `__) +- Moved requirements to ``setup.cfg`` (`#617 `__) +- [mac] Removed old C code for Python 2.5 in the `fsevents` C implementation +- [snapshot] Added ``EmptyDirectorySnapshot`` (`#613 `__) +- Thanks to our beloved contributors: @Ajordat, @tehkirill, @BoboTiG + + +0.10.0 +~~~~~~ + +2020-01-26 β€’ `full history `__ + +**Breaking Changes** + +- Dropped support for Python 2.6, 3.2 and 3.3 +- Emitters that failed to start are now removed +- [snapshot] Removed the deprecated ``walker_callback`` argument, + use ``stat`` instead +- [watchmedo] The utility is no more installed by default but via the extra + ``watchdog[watchmedo]`` + +**Other Changes** + +- Fixed several Python 3 warnings +- Identify synthesized events with ``is_synthetic`` attribute (`#369 `__) +- Use ``os.scandir()`` to improve memory usage (`#503 `__) +- [bsd] Fixed flavors of FreeBSD detection (`#529 `__) +- [bsd] Skip unprocessable socket files (`#509 `__) +- [inotify] Fixed events containing non-ASCII characters (`#516 `__) +- [inotify] Fixed the way ``OSError`` are re-raised (`#377 `__) +- [inotify] Fixed wrong source path after renaming a top level folder (`#515 `__) +- [inotify] Removed delay from non-move events (`#477 `__) +- [mac] Fixed a bug when calling ``FSEventsEmitter.stop()`` twice (`#466 `__) +- [mac] Support for unscheduling deleted watch (`#541 `__) +- [mac] Fixed missing field initializers and unused parameters in + ``watchdog_fsevents.c`` +- [snapshot] Don't walk directories without read permissions (`#408 `__) +- [snapshot] Fixed a race condition crash when a directory is swapped for a file (`#513 `__) +- [snasphot] Fixed an ``AttributeError`` about forgotten ``path_for_inode`` attr (`#436 `__) +- [snasphot] Added the ``ignore_device=False`` parameter to the ctor (`597 `__) +- [watchmedo] Fixed the path separator used (`#478 `__) +- [watchmedo] Fixed the use of ``yaml.load()`` for ``yaml.safe_load()`` (`#453 `__) +- [watchmedo] Handle all available signals (`#549 `__) +- [watchmedo] Added the ``--debug-force-polling`` argument (`#404 `__) +- [windows] Fixed issues when the observed directory is deleted (`#570 `__ and `#601 `__) +- [windows] ``WindowsApiEmitter`` made easier to subclass (`#344 `__) +- [windows] Use separate ctypes DLL instances +- [windows] Generate sub created events only if ``recursive=True`` (`#454 `__) +- Thanks to our beloved contributors: @BoboTiG, @LKleinNux, @rrzaripov, + @wildmichael, @TauPan, @segevfiner, @petrblahos, @QuantumEnergyE, + @jeffwidman, @kapsh, @nickoala, @petrblahos, @julianolf, @tonybaloney, + @mbakiev, @pR0Ps, javaguirre, @skurfer, @exarkun, @joshuaskelly, + @danilobellini, @Ajordat + + +0.9.0 +~~~~~ + +2018-08-28 β€’ `full history `__ + +- Deleting the observed directory now emits a ``DirDeletedEvent`` event +- [bsd] Improved the platform detection (`#378 `__) +- [inotify] Fixed a crash when the root directory being watched by was deleted (`#374 `__) +- [inotify] Handle systems providing uClibc +- [linux] Fixed a possible ``DirDeletedEvent`` duplication when + deleting a directory +- [mac] Fixed unicode path handling ``fsevents2.py`` (`#298 `__) +- [watchmedo] Added the ``--debug-force-polling`` argument (`#336 `__) +- [windows] Fixed the ``FILE_LIST_DIRECTORY`` constant (`#376 `__) +- Thanks to our beloved contributors: @vulpeszerda, @hpk42, @tamland, @senden9, + @gorakhargosh, @nolsto, @mafrosis, @DonyorM, @anthrotype, @danilobellini, + @pierregr, @ShinNoNoir, @adrpar, @gforcada, @pR0Ps, @yegorich, @dhke + + +0.8.3 +~~~~~ + +2015-02-11 β€’ `full history `__ + +- Fixed the use of the root logger (`#274 `__) +- [inotify] Refactored libc loading and improved error handling in + ``inotify_c.py`` +- [inotify] Fixed a possible unbound local error in ``inotify_c.py`` +- Thanks to our beloved contributors: @mmorearty, @tamland, @tony, + @gorakhargosh + + +0.8.2 +~~~~~ + +2014-10-29 β€’ `full history `__ + +- Event emitters are no longer started on schedule if ``Observer`` is not + already running +- [mac] Fixed usued arguments to pass clang compilation (`#265 `__) +- [snapshot] Fixed a possible race condition crash on directory deletion (`#281 `__) +- [windows] Fixed an error when watching the same folder again (`#270 `__) +- Thanks to our beloved contributors: @tamland, @apetrone, @Falldog, + @theospears + + +0.8.1 +~~~~~ + +2014-07-28 β€’ `full history `__ + +- Fixed ``anon_inode`` descriptors leakage (`#249 `__) +- [inotify] Fixed thread stop dead lock (`#250 `__) +- Thanks to our beloved contributors: @Witos, @adiroiban, @tamland + + +0.8.0 +~~~~~ + +2014-07-02 β€’ `full history `__ + +- Fixed ``argh`` deprecation warnings (`#242 `__) +- [snapshot] Methods returning internal stats info were replaced by + ``mtime()``, ``inode()`` and ``path()`` methods +- [snapshot] Deprecated the ``walker_callback`` argument +- [watchmedo] Fixed ``auto-restart`` to terminate all children processes (`#225 `__) +- [watchmedo] Added the ``--no-parallel`` argument (`#227 `__) +- [windows] Fixed the value of ``INVALID_HANDLE_VALUE`` (`#123 `__) +- [windows] Fixed octal usages to work with Python 3 as well (`#223 `__) +- Thanks to our beloved contributors: @tamland, @Ormod, @berdario, @cro, + @BernieSumption, @pypingou, @gotcha, @tommorris, @frewsxcv diff --git a/.venv/Lib/site-packages/watchdog-6.0.0.dist-info/RECORD b/.venv/Lib/site-packages/watchdog-6.0.0.dist-info/RECORD new file mode 100644 index 0000000000000000000000000000000000000000..11dbaffacec6c2dac1e25893a03d08fae00a0363 --- /dev/null +++ b/.venv/Lib/site-packages/watchdog-6.0.0.dist-info/RECORD @@ -0,0 +1,61 @@ +../../Scripts/watchmedo.exe,sha256=EUMairu0pfc7YQ6hZJAmY4xa5maGpB3Mx8ktVEhHh6A,108468 +watchdog-6.0.0.dist-info/AUTHORS,sha256=JT4CdfYRf1V0Mg9RbNaaGK6LyP9pztEsJR6bQ-MfaG8,2928 +watchdog-6.0.0.dist-info/COPYING,sha256=OfCBgo22-UxwEj-k-zDBvOPiFaj97OU6SZkf4HamnAg,703 +watchdog-6.0.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +watchdog-6.0.0.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358 +watchdog-6.0.0.dist-info/METADATA,sha256=7P3gIwR-d2Hc4G1EiKvO3onjmDmZYaBS8vzLObAB4nk,44292 +watchdog-6.0.0.dist-info/RECORD,, +watchdog-6.0.0.dist-info/WHEEL,sha256=mRFVR6BIY-4AcY-di6Z_WejDvSiiVIG1lUb-30eywqM,97 +watchdog-6.0.0.dist-info/entry_points.txt,sha256=qt_Oe2U5Zlfz7LNA3PHipn3_1zlfRTp9dk3wTS3Ivb8,66 +watchdog-6.0.0.dist-info/top_level.txt,sha256=OVdR7GkPGZako8sRtVuM0Nis-ZIElx3he3hKFPYnTGg,9 +watchdog/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +watchdog/__pycache__/__init__.cpython-312.pyc,, +watchdog/__pycache__/events.cpython-312.pyc,, +watchdog/__pycache__/version.cpython-312.pyc,, +watchdog/__pycache__/watchmedo.cpython-312.pyc,, +watchdog/events.py,sha256=ig4oCNcm-mSe6rK5LPsIUcMO3dfq9EKegfM9I4SwVv8,16323 +watchdog/observers/__init__.py,sha256=BmXKL1WXWnJP8-WRrhP4kmGK04gNADh1ifJezeZs4hs,3256 +watchdog/observers/__pycache__/__init__.cpython-312.pyc,, +watchdog/observers/__pycache__/api.cpython-312.pyc,, +watchdog/observers/__pycache__/fsevents.cpython-312.pyc,, +watchdog/observers/__pycache__/fsevents2.cpython-312.pyc,, +watchdog/observers/__pycache__/inotify.cpython-312.pyc,, +watchdog/observers/__pycache__/inotify_buffer.cpython-312.pyc,, +watchdog/observers/__pycache__/inotify_c.cpython-312.pyc,, +watchdog/observers/__pycache__/kqueue.cpython-312.pyc,, +watchdog/observers/__pycache__/polling.cpython-312.pyc,, +watchdog/observers/__pycache__/read_directory_changes.cpython-312.pyc,, +watchdog/observers/__pycache__/winapi.cpython-312.pyc,, +watchdog/observers/api.py,sha256=tyPhqDhzh2pveEkCVRR2B51SaXlDsrcpl8W6oidQuUs,13802 +watchdog/observers/fsevents.py,sha256=6ho3sgBQt6hsq_1F6eJgtor5CjZV09TaoT01xeHNgd4,14284 +watchdog/observers/fsevents2.py,sha256=fZ8O7zomltBgvucDBlUHZIWKREFn4MKB30T5iEisPsc,9439 +watchdog/observers/inotify.py,sha256=i075APHIwIUdiFrfdocpbYsedUvh_u3AtLqU3bqlgFE,10649 +watchdog/observers/inotify_buffer.py,sha256=VWWuleFQRaJL_ZM0jbcAGjGdj1kZUWmUigC4WSbPmyQ,4434 +watchdog/observers/inotify_c.py,sha256=ys6NrVEbw2bPZQUkzshY5lGlfDZT4nz58Vmn4A49emU,21129 +watchdog/observers/kqueue.py,sha256=HYARzdF_Nlu72vTaIBbIvh5e_N7ROd33VDtZc1Ab2oc,24425 +watchdog/observers/polling.py,sha256=B8gyEtzkRiHmSSf8dcY_0P-Bu0U5i-VWQanBqIVxTs0,4932 +watchdog/observers/read_directory_changes.py,sha256=mKHZIfUopCAU0ae7oE9Ttkggk7LfTb8lwgcMJHmOW5E,4167 +watchdog/observers/winapi.py,sha256=q2nTZ2JYnbuEUiByTcSmpbw4iiKhtNQ6UQg9CWPIUxY,11635 +watchdog/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +watchdog/tricks/__init__.py,sha256=zLFpZfXN_A3jXlH00Ok0SpbtWxP2WwwsxG7w2PXkxP8,9492 +watchdog/tricks/__pycache__/__init__.cpython-312.pyc,, +watchdog/utils/__init__.py,sha256=9q7wEZW7yl81Db1CcLBQJ33xZ2YrGwyzsK2gzNCC-lE,3513 +watchdog/utils/__pycache__/__init__.cpython-312.pyc,, +watchdog/utils/__pycache__/bricks.cpython-312.pyc,, +watchdog/utils/__pycache__/delayed_queue.cpython-312.pyc,, +watchdog/utils/__pycache__/dirsnapshot.cpython-312.pyc,, +watchdog/utils/__pycache__/echo.cpython-312.pyc,, +watchdog/utils/__pycache__/event_debouncer.cpython-312.pyc,, +watchdog/utils/__pycache__/patterns.cpython-312.pyc,, +watchdog/utils/__pycache__/platform.cpython-312.pyc,, +watchdog/utils/__pycache__/process_watcher.cpython-312.pyc,, +watchdog/utils/bricks.py,sha256=cZCA4T9e1iWvr3yY4FOGuOzIpdP4c4Nhx0ipfgyhBno,2545 +watchdog/utils/delayed_queue.py,sha256=Xv-Rco10b62Vt4LnLEmZxlpr93MeBV2ZX-U2--nHS5A,2615 +watchdog/utils/dirsnapshot.py,sha256=SaGnxq0miZbxLZcpJcSOj5sE8ihunqjb5-m8ww9F1aA,14740 +watchdog/utils/echo.py,sha256=GALgUot9zXVAMxMwLN5CkHRIdjmio1X3vppVS14P-eM,2210 +watchdog/utils/event_debouncer.py,sha256=oVifdt50PjOiV4n-0W1OZOCNO4j689BRRVgCGrJvH0E,2079 +watchdog/utils/patterns.py,sha256=fjy8h_XaUuRkoh46uFLv37JzgjmmK2Vzt1ZVbMNa0cE,3672 +watchdog/utils/platform.py,sha256=VSN45Y2kA0NS1Nzlmr5SHB4Ct0xqK2KRly9jlx7DHSg,885 +watchdog/utils/process_watcher.py,sha256=qgLtEZLhYLjpL-GZawIEjV-p_PnMka_hBGH_1vxX-gk,925 +watchdog/version.py,sha256=guvQM7983CuZ2S52zEtdhsS_dkqhbY3mp-GQvVM4DR0,349 +watchdog/watchmedo.py,sha256=AMTUpNSlQmAqxf5EhtfKKh5eYiPZoDYgUm1Gf8xD3-g,25452 diff --git a/.venv/Lib/site-packages/watchdog-6.0.0.dist-info/WHEEL b/.venv/Lib/site-packages/watchdog-6.0.0.dist-info/WHEEL new file mode 100644 index 0000000000000000000000000000000000000000..fda522209df07920ac82383e5a408ec341ea0309 --- /dev/null +++ b/.venv/Lib/site-packages/watchdog-6.0.0.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: setuptools (75.3.0) +Root-Is-Purelib: true +Tag: py3-none-win_amd64 + diff --git a/.venv/Lib/site-packages/watchdog-6.0.0.dist-info/entry_points.txt b/.venv/Lib/site-packages/watchdog-6.0.0.dist-info/entry_points.txt new file mode 100644 index 0000000000000000000000000000000000000000..b05809e4e163ed58b9d01b5d5f5321486d19fe27 --- /dev/null +++ b/.venv/Lib/site-packages/watchdog-6.0.0.dist-info/entry_points.txt @@ -0,0 +1,2 @@ +[console_scripts] +watchmedo = watchdog.watchmedo:main [watchmedo] diff --git a/.venv/Lib/site-packages/watchdog-6.0.0.dist-info/top_level.txt b/.venv/Lib/site-packages/watchdog-6.0.0.dist-info/top_level.txt new file mode 100644 index 0000000000000000000000000000000000000000..e59495eee06b72aaf42ba877daa7f944ede675ce --- /dev/null +++ b/.venv/Lib/site-packages/watchdog-6.0.0.dist-info/top_level.txt @@ -0,0 +1 @@ +watchdog diff --git a/.venv/Lib/site-packages/watchdog/__init__.py b/.venv/Lib/site-packages/watchdog/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/.venv/Lib/site-packages/watchdog/events.py b/.venv/Lib/site-packages/watchdog/events.py new file mode 100644 index 0000000000000000000000000000000000000000..db430235088d2b35fbb84303d1818bce2bb80f23 --- /dev/null +++ b/.venv/Lib/site-packages/watchdog/events.py @@ -0,0 +1,542 @@ +""":module: watchdog.events +:synopsis: File system events and event handlers. +:author: yesudeep@google.com (Yesudeep Mangalapilly) +:author: contact@tiger-222.fr (MickaΓ«l Schoentgen) + +Event Classes +------------- +.. autoclass:: FileSystemEvent + :members: + :show-inheritance: + :inherited-members: + +.. autoclass:: FileSystemMovedEvent + :members: + :show-inheritance: + +.. autoclass:: FileMovedEvent + :members: + :show-inheritance: + +.. autoclass:: DirMovedEvent + :members: + :show-inheritance: + +.. autoclass:: FileModifiedEvent + :members: + :show-inheritance: + +.. autoclass:: DirModifiedEvent + :members: + :show-inheritance: + +.. autoclass:: FileCreatedEvent + :members: + :show-inheritance: + +.. autoclass:: FileClosedEvent + :members: + :show-inheritance: + +.. autoclass:: FileClosedNoWriteEvent + :members: + :show-inheritance: + +.. autoclass:: FileOpenedEvent + :members: + :show-inheritance: + +.. autoclass:: DirCreatedEvent + :members: + :show-inheritance: + +.. autoclass:: FileDeletedEvent + :members: + :show-inheritance: + +.. autoclass:: DirDeletedEvent + :members: + :show-inheritance: + + +Event Handler Classes +--------------------- +.. autoclass:: FileSystemEventHandler + :members: + :show-inheritance: + +.. autoclass:: PatternMatchingEventHandler + :members: + :show-inheritance: + +.. autoclass:: RegexMatchingEventHandler + :members: + :show-inheritance: + +.. autoclass:: LoggingEventHandler + :members: + :show-inheritance: + +""" + +from __future__ import annotations + +import logging +import os.path +import re +from dataclasses import dataclass, field +from typing import TYPE_CHECKING + +from watchdog.utils.patterns import match_any_paths + +if TYPE_CHECKING: + from collections.abc import Generator + +EVENT_TYPE_MOVED = "moved" +EVENT_TYPE_DELETED = "deleted" +EVENT_TYPE_CREATED = "created" +EVENT_TYPE_MODIFIED = "modified" +EVENT_TYPE_CLOSED = "closed" +EVENT_TYPE_CLOSED_NO_WRITE = "closed_no_write" +EVENT_TYPE_OPENED = "opened" + + +@dataclass(unsafe_hash=True) +class FileSystemEvent: + """Immutable type that represents a file system event that is triggered + when a change occurs on the monitored file system. + + All FileSystemEvent objects are required to be immutable and hence + can be used as keys in dictionaries or be added to sets. + """ + + src_path: bytes | str + dest_path: bytes | str = "" + event_type: str = field(default="", init=False) + is_directory: bool = field(default=False, init=False) + + """ + True if event was synthesized; False otherwise. + These are events that weren't actually broadcast by the OS, but + are presumed to have happened based on other, actual events. + """ + is_synthetic: bool = field(default=False) + + +class FileSystemMovedEvent(FileSystemEvent): + """File system event representing any kind of file system movement.""" + + event_type = EVENT_TYPE_MOVED + + +# File events. + + +class FileDeletedEvent(FileSystemEvent): + """File system event representing file deletion on the file system.""" + + event_type = EVENT_TYPE_DELETED + + +class FileModifiedEvent(FileSystemEvent): + """File system event representing file modification on the file system.""" + + event_type = EVENT_TYPE_MODIFIED + + +class FileCreatedEvent(FileSystemEvent): + """File system event representing file creation on the file system.""" + + event_type = EVENT_TYPE_CREATED + + +class FileMovedEvent(FileSystemMovedEvent): + """File system event representing file movement on the file system.""" + + +class FileClosedEvent(FileSystemEvent): + """File system event representing file close on the file system.""" + + event_type = EVENT_TYPE_CLOSED + + +class FileClosedNoWriteEvent(FileSystemEvent): + """File system event representing an unmodified file close on the file system.""" + + event_type = EVENT_TYPE_CLOSED_NO_WRITE + + +class FileOpenedEvent(FileSystemEvent): + """File system event representing file close on the file system.""" + + event_type = EVENT_TYPE_OPENED + + +# Directory events. + + +class DirDeletedEvent(FileSystemEvent): + """File system event representing directory deletion on the file system.""" + + event_type = EVENT_TYPE_DELETED + is_directory = True + + +class DirModifiedEvent(FileSystemEvent): + """File system event representing directory modification on the file system.""" + + event_type = EVENT_TYPE_MODIFIED + is_directory = True + + +class DirCreatedEvent(FileSystemEvent): + """File system event representing directory creation on the file system.""" + + event_type = EVENT_TYPE_CREATED + is_directory = True + + +class DirMovedEvent(FileSystemMovedEvent): + """File system event representing directory movement on the file system.""" + + is_directory = True + + +class FileSystemEventHandler: + """Base file system event handler that you can override methods from.""" + + def dispatch(self, event: FileSystemEvent) -> None: + """Dispatches events to the appropriate methods. + + :param event: + The event object representing the file system event. + :type event: + :class:`FileSystemEvent` + """ + self.on_any_event(event) + getattr(self, f"on_{event.event_type}")(event) + + def on_any_event(self, event: FileSystemEvent) -> None: + """Catch-all event handler. + + :param event: + The event object representing the file system event. + :type event: + :class:`FileSystemEvent` + """ + + def on_moved(self, event: DirMovedEvent | FileMovedEvent) -> None: + """Called when a file or a directory is moved or renamed. + + :param event: + Event representing file/directory movement. + :type event: + :class:`DirMovedEvent` or :class:`FileMovedEvent` + """ + + def on_created(self, event: DirCreatedEvent | FileCreatedEvent) -> None: + """Called when a file or directory is created. + + :param event: + Event representing file/directory creation. + :type event: + :class:`DirCreatedEvent` or :class:`FileCreatedEvent` + """ + + def on_deleted(self, event: DirDeletedEvent | FileDeletedEvent) -> None: + """Called when a file or directory is deleted. + + :param event: + Event representing file/directory deletion. + :type event: + :class:`DirDeletedEvent` or :class:`FileDeletedEvent` + """ + + def on_modified(self, event: DirModifiedEvent | FileModifiedEvent) -> None: + """Called when a file or directory is modified. + + :param event: + Event representing file/directory modification. + :type event: + :class:`DirModifiedEvent` or :class:`FileModifiedEvent` + """ + + def on_closed(self, event: FileClosedEvent) -> None: + """Called when a file opened for writing is closed. + + :param event: + Event representing file closing. + :type event: + :class:`FileClosedEvent` + """ + + def on_closed_no_write(self, event: FileClosedNoWriteEvent) -> None: + """Called when a file opened for reading is closed. + + :param event: + Event representing file closing. + :type event: + :class:`FileClosedNoWriteEvent` + """ + + def on_opened(self, event: FileOpenedEvent) -> None: + """Called when a file is opened. + + :param event: + Event representing file opening. + :type event: + :class:`FileOpenedEvent` + """ + + +class PatternMatchingEventHandler(FileSystemEventHandler): + """Matches given patterns with file paths associated with occurring events. + Uses pathlib's `PurePath.match()` method. `patterns` and `ignore_patterns` + are expected to be a list of strings. + """ + + def __init__( + self, + *, + patterns: list[str] | None = None, + ignore_patterns: list[str] | None = None, + ignore_directories: bool = False, + case_sensitive: bool = False, + ): + super().__init__() + + self._patterns = patterns + self._ignore_patterns = ignore_patterns + self._ignore_directories = ignore_directories + self._case_sensitive = case_sensitive + + @property + def patterns(self) -> list[str] | None: + """(Read-only) + Patterns to allow matching event paths. + """ + return self._patterns + + @property + def ignore_patterns(self) -> list[str] | None: + """(Read-only) + Patterns to ignore matching event paths. + """ + return self._ignore_patterns + + @property + def ignore_directories(self) -> bool: + """(Read-only) + ``True`` if directories should be ignored; ``False`` otherwise. + """ + return self._ignore_directories + + @property + def case_sensitive(self) -> bool: + """(Read-only) + ``True`` if path names should be matched sensitive to case; ``False`` + otherwise. + """ + return self._case_sensitive + + def dispatch(self, event: FileSystemEvent) -> None: + """Dispatches events to the appropriate methods. + + :param event: + The event object representing the file system event. + :type event: + :class:`FileSystemEvent` + """ + if self.ignore_directories and event.is_directory: + return + + paths = [] + if hasattr(event, "dest_path"): + paths.append(os.fsdecode(event.dest_path)) + if event.src_path: + paths.append(os.fsdecode(event.src_path)) + + if match_any_paths( + paths, + included_patterns=self.patterns, + excluded_patterns=self.ignore_patterns, + case_sensitive=self.case_sensitive, + ): + super().dispatch(event) + + +class RegexMatchingEventHandler(FileSystemEventHandler): + """Matches given regexes with file paths associated with occurring events. + Uses the `re` module. + """ + + def __init__( + self, + *, + regexes: list[str] | None = None, + ignore_regexes: list[str] | None = None, + ignore_directories: bool = False, + case_sensitive: bool = False, + ): + super().__init__() + + if regexes is None: + regexes = [r".*"] + elif isinstance(regexes, str): + regexes = [regexes] + if ignore_regexes is None: + ignore_regexes = [] + if case_sensitive: + self._regexes = [re.compile(r) for r in regexes] + self._ignore_regexes = [re.compile(r) for r in ignore_regexes] + else: + self._regexes = [re.compile(r, re.IGNORECASE) for r in regexes] + self._ignore_regexes = [re.compile(r, re.IGNORECASE) for r in ignore_regexes] + self._ignore_directories = ignore_directories + self._case_sensitive = case_sensitive + + @property + def regexes(self) -> list[re.Pattern[str]]: + """(Read-only) + Regexes to allow matching event paths. + """ + return self._regexes + + @property + def ignore_regexes(self) -> list[re.Pattern[str]]: + """(Read-only) + Regexes to ignore matching event paths. + """ + return self._ignore_regexes + + @property + def ignore_directories(self) -> bool: + """(Read-only) + ``True`` if directories should be ignored; ``False`` otherwise. + """ + return self._ignore_directories + + @property + def case_sensitive(self) -> bool: + """(Read-only) + ``True`` if path names should be matched sensitive to case; ``False`` + otherwise. + """ + return self._case_sensitive + + def dispatch(self, event: FileSystemEvent) -> None: + """Dispatches events to the appropriate methods. + + :param event: + The event object representing the file system event. + :type event: + :class:`FileSystemEvent` + """ + if self.ignore_directories and event.is_directory: + return + + paths = [] + if hasattr(event, "dest_path"): + paths.append(os.fsdecode(event.dest_path)) + if event.src_path: + paths.append(os.fsdecode(event.src_path)) + + if any(r.match(p) for r in self.ignore_regexes for p in paths): + return + + if any(r.match(p) for r in self.regexes for p in paths): + super().dispatch(event) + + +class LoggingEventHandler(FileSystemEventHandler): + """Logs all the events captured.""" + + def __init__(self, *, logger: logging.Logger | None = None) -> None: + super().__init__() + self.logger = logger or logging.root + + def on_moved(self, event: DirMovedEvent | FileMovedEvent) -> None: + super().on_moved(event) + + what = "directory" if event.is_directory else "file" + self.logger.info("Moved %s: from %s to %s", what, event.src_path, event.dest_path) + + def on_created(self, event: DirCreatedEvent | FileCreatedEvent) -> None: + super().on_created(event) + + what = "directory" if event.is_directory else "file" + self.logger.info("Created %s: %s", what, event.src_path) + + def on_deleted(self, event: DirDeletedEvent | FileDeletedEvent) -> None: + super().on_deleted(event) + + what = "directory" if event.is_directory else "file" + self.logger.info("Deleted %s: %s", what, event.src_path) + + def on_modified(self, event: DirModifiedEvent | FileModifiedEvent) -> None: + super().on_modified(event) + + what = "directory" if event.is_directory else "file" + self.logger.info("Modified %s: %s", what, event.src_path) + + def on_closed(self, event: FileClosedEvent) -> None: + super().on_closed(event) + + self.logger.info("Closed modified file: %s", event.src_path) + + def on_closed_no_write(self, event: FileClosedNoWriteEvent) -> None: + super().on_closed_no_write(event) + + self.logger.info("Closed read file: %s", event.src_path) + + def on_opened(self, event: FileOpenedEvent) -> None: + super().on_opened(event) + + self.logger.info("Opened file: %s", event.src_path) + + +def generate_sub_moved_events( + src_dir_path: bytes | str, + dest_dir_path: bytes | str, +) -> Generator[DirMovedEvent | FileMovedEvent]: + """Generates an event list of :class:`DirMovedEvent` and + :class:`FileMovedEvent` objects for all the files and directories within + the given moved directory that were moved along with the directory. + + :param src_dir_path: + The source path of the moved directory. + :param dest_dir_path: + The destination path of the moved directory. + :returns: + An iterable of file system events of type :class:`DirMovedEvent` and + :class:`FileMovedEvent`. + """ + for root, directories, filenames in os.walk(dest_dir_path): # type: ignore[type-var] + for directory in directories: + full_path = os.path.join(root, directory) # type: ignore[call-overload] + renamed_path = full_path.replace(dest_dir_path, src_dir_path) if src_dir_path else "" + yield DirMovedEvent(renamed_path, full_path, is_synthetic=True) + for filename in filenames: + full_path = os.path.join(root, filename) # type: ignore[call-overload] + renamed_path = full_path.replace(dest_dir_path, src_dir_path) if src_dir_path else "" + yield FileMovedEvent(renamed_path, full_path, is_synthetic=True) + + +def generate_sub_created_events(src_dir_path: bytes | str) -> Generator[DirCreatedEvent | FileCreatedEvent]: + """Generates an event list of :class:`DirCreatedEvent` and + :class:`FileCreatedEvent` objects for all the files and directories within + the given moved directory that were moved along with the directory. + + :param src_dir_path: + The source path of the created directory. + :returns: + An iterable of file system events of type :class:`DirCreatedEvent` and + :class:`FileCreatedEvent`. + """ + for root, directories, filenames in os.walk(src_dir_path): # type: ignore[type-var] + for directory in directories: + full_path = os.path.join(root, directory) # type: ignore[call-overload] + yield DirCreatedEvent(full_path, is_synthetic=True) + for filename in filenames: + full_path = os.path.join(root, filename) # type: ignore[call-overload] + yield FileCreatedEvent(full_path, is_synthetic=True) diff --git a/.venv/Lib/site-packages/watchdog/observers/__init__.py b/.venv/Lib/site-packages/watchdog/observers/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ce3957418de5fbbd7bb4c731d6ef5031bab4abaa --- /dev/null +++ b/.venv/Lib/site-packages/watchdog/observers/__init__.py @@ -0,0 +1,91 @@ +""":module: watchdog.observers +:synopsis: Observer that picks a native implementation if available. +:author: yesudeep@google.com (Yesudeep Mangalapilly) +:author: contact@tiger-222.fr (MickaΓ«l Schoentgen) + +Classes +======= +.. autoclass:: Observer + :members: + :show-inheritance: + :inherited-members: + +Observer thread that schedules watching directories and dispatches +calls to event handlers. + +You can also import platform specific classes directly and use it instead +of :class:`Observer`. Here is a list of implemented observer classes.: + +============== ================================ ============================== +Class Platforms Note +============== ================================ ============================== +|Inotify| Linux 2.6.13+ ``inotify(7)`` based observer +|FSEvents| macOS FSEvents based observer +|Kqueue| macOS and BSD with kqueue(2) ``kqueue(2)`` based observer +|WinApi| Microsoft Windows Windows API-based observer +|Polling| Any fallback implementation +============== ================================ ============================== + +.. |Inotify| replace:: :class:`.inotify.InotifyObserver` +.. |FSEvents| replace:: :class:`.fsevents.FSEventsObserver` +.. |Kqueue| replace:: :class:`.kqueue.KqueueObserver` +.. |WinApi| replace:: :class:`.read_directory_changes.WindowsApiObserver` +.. |Polling| replace:: :class:`.polling.PollingObserver` + +""" + +from __future__ import annotations + +import contextlib +import warnings +from typing import TYPE_CHECKING, Protocol + +from watchdog.utils import UnsupportedLibcError, platform + +if TYPE_CHECKING: + from watchdog.observers.api import BaseObserver + + +class ObserverType(Protocol): + def __call__(self, *, timeout: float = ...) -> BaseObserver: ... + + +def _get_observer_cls() -> ObserverType: + if platform.is_linux(): + with contextlib.suppress(UnsupportedLibcError): + from watchdog.observers.inotify import InotifyObserver + + return InotifyObserver + elif platform.is_darwin(): + try: + from watchdog.observers.fsevents import FSEventsObserver + except Exception: + try: + from watchdog.observers.kqueue import KqueueObserver + except Exception: + warnings.warn("Failed to import fsevents and kqueue. Fall back to polling.", stacklevel=1) + else: + warnings.warn("Failed to import fsevents. Fall back to kqueue", stacklevel=1) + return KqueueObserver + else: + return FSEventsObserver + elif platform.is_windows(): + try: + from watchdog.observers.read_directory_changes import WindowsApiObserver + except Exception: + warnings.warn("Failed to import `read_directory_changes`. Fall back to polling.", stacklevel=1) + else: + return WindowsApiObserver + elif platform.is_bsd(): + from watchdog.observers.kqueue import KqueueObserver + + return KqueueObserver + + from watchdog.observers.polling import PollingObserver + + return PollingObserver + + +Observer = _get_observer_cls() + +__all__ = ["Observer"] diff --git a/.venv/Lib/site-packages/watchdog/observers/api.py b/.venv/Lib/site-packages/watchdog/observers/api.py new file mode 100644 index 0000000000000000000000000000000000000000..30cb21caff9c686e11c6420064d039f37eb1ff02 --- /dev/null +++ b/.venv/Lib/site-packages/watchdog/observers/api.py @@ -0,0 +1,392 @@ +from __future__ import annotations + +import contextlib +import queue +import threading +from collections import defaultdict +from pathlib import Path +from typing import TYPE_CHECKING + +from watchdog.utils import BaseThread +from watchdog.utils.bricks import SkipRepeatsQueue + +if TYPE_CHECKING: + from watchdog.events import FileSystemEvent, FileSystemEventHandler + +DEFAULT_EMITTER_TIMEOUT = 1.0 # in seconds +DEFAULT_OBSERVER_TIMEOUT = 1.0 # in seconds + + +class EventQueue(SkipRepeatsQueue): + """Thread-safe event queue based on a special queue that skips adding + the same event (:class:`FileSystemEvent`) multiple times consecutively. + Thus avoiding dispatching multiple event handling + calls when multiple identical events are produced quicker than an observer + can consume them. + """ + + +class ObservedWatch: + """An scheduled watch. + + :param path: + Path string. + :param recursive: + ``True`` if watch is recursive; ``False`` otherwise. + :param event_filter: + Optional collection of :class:`watchdog.events.FileSystemEvent` to watch + """ + + def __init__(self, path: str | Path, *, recursive: bool, event_filter: list[type[FileSystemEvent]] | None = None): + self._path = str(path) if isinstance(path, Path) else path + self._is_recursive = recursive + self._event_filter = frozenset(event_filter) if event_filter is not None else None + + @property + def path(self) -> str: + """The path that this watch monitors.""" + return self._path + + @property + def is_recursive(self) -> bool: + """Determines whether subdirectories are watched for the path.""" + return self._is_recursive + + @property + def event_filter(self) -> frozenset[type[FileSystemEvent]] | None: + """Collection of event types watched for the path""" + return self._event_filter + + @property + def key(self) -> tuple[str, bool, frozenset[type[FileSystemEvent]] | None]: + return self.path, self.is_recursive, self.event_filter + + def __eq__(self, watch: object) -> bool: + if not isinstance(watch, ObservedWatch): + return NotImplemented + return self.key == watch.key + + def __ne__(self, watch: object) -> bool: + if not isinstance(watch, ObservedWatch): + return NotImplemented + return self.key != watch.key + + def __hash__(self) -> int: + return hash(self.key) + + def __repr__(self) -> str: + if self.event_filter is not None: + event_filter_str = "|".join(sorted(_cls.__name__ for _cls in self.event_filter)) + event_filter_str = f", event_filter={event_filter_str}" + else: + event_filter_str = "" + return f"<{type(self).__name__}: path={self.path!r}, is_recursive={self.is_recursive}{event_filter_str}>" + + +# Observer classes +class EventEmitter(BaseThread): + """Producer thread base class subclassed by event emitters + that generate events and populate a queue with them. + + :param event_queue: + The event queue to populate with generated events. + :type event_queue: + :class:`watchdog.events.EventQueue` + :param watch: + The watch to observe and produce events for. + :type watch: + :class:`ObservedWatch` + :param timeout: + Timeout (in seconds) between successive attempts at reading events. + :type timeout: + ``float`` + :param event_filter: + Collection of event types to emit, or None for no filtering (default). + :type event_filter: + Iterable[:class:`watchdog.events.FileSystemEvent`] | None + """ + + def __init__( + self, + event_queue: EventQueue, + watch: ObservedWatch, + *, + timeout: float = DEFAULT_EMITTER_TIMEOUT, + event_filter: list[type[FileSystemEvent]] | None = None, + ) -> None: + super().__init__() + self._event_queue = event_queue + self._watch = watch + self._timeout = timeout + self._event_filter = frozenset(event_filter) if event_filter is not None else None + + @property + def timeout(self) -> float: + """Blocking timeout for reading events.""" + return self._timeout + + @property + def watch(self) -> ObservedWatch: + """The watch associated with this emitter.""" + return self._watch + + def queue_event(self, event: FileSystemEvent) -> None: + """Queues a single event. + + :param event: + Event to be queued. + :type event: + An instance of :class:`watchdog.events.FileSystemEvent` + or a subclass. + """ + if self._event_filter is None or any(isinstance(event, cls) for cls in self._event_filter): + self._event_queue.put((event, self.watch)) + + def queue_events(self, timeout: float) -> None: + """Override this method to populate the event queue with events + per interval period. + + :param timeout: + Timeout (in seconds) between successive attempts at + reading events. + :type timeout: + ``float`` + """ + + def run(self) -> None: + while self.should_keep_running(): + self.queue_events(self.timeout) + + +class EventDispatcher(BaseThread): + """Consumer thread base class subclassed by event observer threads + that dispatch events from an event queue to appropriate event handlers. + + :param timeout: + Timeout value (in seconds) passed to emitters + constructions in the child class BaseObserver. + :type timeout: + ``float`` + """ + + stop_event = object() + """Event inserted into the queue to signal a requested stop.""" + + def __init__(self, *, timeout: float = DEFAULT_OBSERVER_TIMEOUT) -> None: + super().__init__() + self._event_queue = EventQueue() + self._timeout = timeout + + @property + def timeout(self) -> float: + """Timeout value to construct emitters with.""" + return self._timeout + + def stop(self) -> None: + BaseThread.stop(self) + with contextlib.suppress(queue.Full): + self.event_queue.put_nowait(EventDispatcher.stop_event) + + @property + def event_queue(self) -> EventQueue: + """The event queue which is populated with file system events + by emitters and from which events are dispatched by a dispatcher + thread. + """ + return self._event_queue + + def dispatch_events(self, event_queue: EventQueue) -> None: + """Override this method to consume events from an event queue, blocking + on the queue for the specified timeout before raising :class:`queue.Empty`. + + :param event_queue: + Event queue to populate with one set of events. + :type event_queue: + :class:`EventQueue` + :raises: + :class:`queue.Empty` + """ + + def run(self) -> None: + while self.should_keep_running(): + try: + self.dispatch_events(self.event_queue) + except queue.Empty: + continue + + +class BaseObserver(EventDispatcher): + """Base observer.""" + + def __init__(self, emitter_class: type[EventEmitter], *, timeout: float = DEFAULT_OBSERVER_TIMEOUT) -> None: + super().__init__(timeout=timeout) + self._emitter_class = emitter_class + self._lock = threading.RLock() + self._watches: set[ObservedWatch] = set() + self._handlers: defaultdict[ObservedWatch, set[FileSystemEventHandler]] = defaultdict(set) + self._emitters: set[EventEmitter] = set() + self._emitter_for_watch: dict[ObservedWatch, EventEmitter] = {} + + def _add_emitter(self, emitter: EventEmitter) -> None: + self._emitter_for_watch[emitter.watch] = emitter + self._emitters.add(emitter) + + def _remove_emitter(self, emitter: EventEmitter) -> None: + del self._emitter_for_watch[emitter.watch] + self._emitters.remove(emitter) + emitter.stop() + with contextlib.suppress(RuntimeError): + emitter.join() + + def _clear_emitters(self) -> None: + for emitter in self._emitters: + emitter.stop() + for emitter in self._emitters: + with contextlib.suppress(RuntimeError): + emitter.join() + self._emitters.clear() + self._emitter_for_watch.clear() + + def _add_handler_for_watch(self, event_handler: FileSystemEventHandler, watch: ObservedWatch) -> None: + self._handlers[watch].add(event_handler) + + def _remove_handlers_for_watch(self, watch: ObservedWatch) -> None: + del self._handlers[watch] + + @property + def emitters(self) -> set[EventEmitter]: + """Returns event emitter created by this observer.""" + return self._emitters + + def start(self) -> None: + for emitter in self._emitters.copy(): + try: + emitter.start() + except Exception: + self._remove_emitter(emitter) + raise + super().start() + + def schedule( + self, + event_handler: FileSystemEventHandler, + path: str, + *, + recursive: bool = False, + event_filter: list[type[FileSystemEvent]] | None = None, + ) -> ObservedWatch: + """Schedules watching a path and calls appropriate methods specified + in the given event handler in response to file system events. + + :param event_handler: + An event handler instance that has appropriate event handling + methods which will be called by the observer in response to + file system events. + :type event_handler: + :class:`watchdog.events.FileSystemEventHandler` or a subclass + :param path: + Directory path that will be monitored. + :type path: + ``str`` + :param recursive: + ``True`` if events will be emitted for sub-directories + traversed recursively; ``False`` otherwise. + :type recursive: + ``bool`` + :param event_filter: + Collection of event types to emit, or None for no filtering (default). + :type event_filter: + Iterable[:class:`watchdog.events.FileSystemEvent`] | None + :return: + An :class:`ObservedWatch` object instance representing + a watch. + """ + with self._lock: + watch = ObservedWatch(path, recursive=recursive, event_filter=event_filter) + self._add_handler_for_watch(event_handler, watch) + + # If we don't have an emitter for this watch already, create it. + if watch not in self._emitter_for_watch: + emitter = self._emitter_class(self.event_queue, watch, timeout=self.timeout, event_filter=event_filter) + if self.is_alive(): + emitter.start() + self._add_emitter(emitter) + self._watches.add(watch) + return watch + + def add_handler_for_watch(self, event_handler: FileSystemEventHandler, watch: ObservedWatch) -> None: + """Adds a handler for the given watch. + + :param event_handler: + An event handler instance that has appropriate event handling + methods which will be called by the observer in response to + file system events. + :type event_handler: + :class:`watchdog.events.FileSystemEventHandler` or a subclass + :param watch: + The watch to add a handler for. + :type watch: + An instance of :class:`ObservedWatch` or a subclass of + :class:`ObservedWatch` + """ + with self._lock: + self._add_handler_for_watch(event_handler, watch) + + def remove_handler_for_watch(self, event_handler: FileSystemEventHandler, watch: ObservedWatch) -> None: + """Removes a handler for the given watch. + + :param event_handler: + An event handler instance that has appropriate event handling + methods which will be called by the observer in response to + file system events. + :type event_handler: + :class:`watchdog.events.FileSystemEventHandler` or a subclass + :param watch: + The watch to remove a handler for. + :type watch: + An instance of :class:`ObservedWatch` or a subclass of + :class:`ObservedWatch` + """ + with self._lock: + self._handlers[watch].remove(event_handler) + + def unschedule(self, watch: ObservedWatch) -> None: + """Unschedules a watch. + + :param watch: + The watch to unschedule. + :type watch: + An instance of :class:`ObservedWatch` or a subclass of + :class:`ObservedWatch` + """ + with self._lock: + emitter = self._emitter_for_watch[watch] + del self._handlers[watch] + self._remove_emitter(emitter) + self._watches.remove(watch) + + def unschedule_all(self) -> None: + """Unschedules all watches and detaches all associated event handlers.""" + with self._lock: + self._handlers.clear() + self._clear_emitters() + self._watches.clear() + + def on_thread_stop(self) -> None: + self.unschedule_all() + + def dispatch_events(self, event_queue: EventQueue) -> None: + entry = event_queue.get(block=True) + if entry is EventDispatcher.stop_event: + return + + event, watch = entry + + with self._lock: + # To allow unschedule/stop and safe removal of event handlers + # within event handlers itself, check if the handler is still + # registered after every dispatch. + for handler in self._handlers[watch].copy(): + if handler in self._handlers[watch]: + handler.dispatch(event) + event_queue.task_done() diff --git a/.venv/Lib/site-packages/watchdog/observers/fsevents.py b/.venv/Lib/site-packages/watchdog/observers/fsevents.py new file mode 100644 index 0000000000000000000000000000000000000000..257e16e7b16c39751963781c1d37fc11b22489b5 --- /dev/null +++ b/.venv/Lib/site-packages/watchdog/observers/fsevents.py @@ -0,0 +1,339 @@ +""":module: watchdog.observers.fsevents +:synopsis: FSEvents based emitter implementation. +:author: yesudeep@google.com (Yesudeep Mangalapilly) +:author: contact@tiger-222.fr (MickaΓ«l Schoentgen) +:platforms: macOS +""" + +from __future__ import annotations + +import logging +import os +import threading +import time +import unicodedata +from typing import TYPE_CHECKING + +import _watchdog_fsevents as _fsevents + +from watchdog.events import ( + DirCreatedEvent, + DirDeletedEvent, + DirModifiedEvent, + DirMovedEvent, + FileCreatedEvent, + FileDeletedEvent, + FileModifiedEvent, + FileMovedEvent, + generate_sub_created_events, + generate_sub_moved_events, +) +from watchdog.observers.api import DEFAULT_EMITTER_TIMEOUT, DEFAULT_OBSERVER_TIMEOUT, BaseObserver, EventEmitter +from watchdog.utils.dirsnapshot import DirectorySnapshot + +if TYPE_CHECKING: + from watchdog.events import FileSystemEvent, FileSystemEventHandler + from watchdog.observers.api import EventQueue, ObservedWatch + + +logger = logging.getLogger("fsevents") + + +class FSEventsEmitter(EventEmitter): + """macOS FSEvents Emitter class. + + :param event_queue: + The event queue to fill with events. + :param watch: + A watch object representing the directory to monitor. + :type watch: + :class:`watchdog.observers.api.ObservedWatch` + :param timeout: + Read events blocking timeout (in seconds). + :param event_filter: + Collection of event types to emit, or None for no filtering (default). + :param suppress_history: + The FSEvents API may emit historic events up to 30 sec before the watch was + started. When ``suppress_history`` is ``True``, those events will be suppressed + by creating a directory snapshot of the watched path before starting the stream + as a reference to suppress old events. Warning: This may result in significant + memory usage in case of a large number of items in the watched path. + :type timeout: + ``float`` + """ + + def __init__( + self, + event_queue: EventQueue, + watch: ObservedWatch, + *, + timeout: float = DEFAULT_EMITTER_TIMEOUT, + event_filter: list[type[FileSystemEvent]] | None = None, + suppress_history: bool = False, + ) -> None: + super().__init__(event_queue, watch, timeout=timeout, event_filter=event_filter) + self._fs_view: set[int] = set() + self.suppress_history = suppress_history + self._start_time = 0.0 + self._starting_state: DirectorySnapshot | None = None + self._lock = threading.Lock() + self._absolute_watch_path = os.path.realpath(os.path.abspath(os.path.expanduser(self.watch.path))) + + def on_thread_stop(self) -> None: + _fsevents.remove_watch(self.watch) + _fsevents.stop(self) + + def queue_event(self, event: FileSystemEvent) -> None: + # fsevents defaults to be recursive, so if the watch was meant to be non-recursive then we need to drop + # all the events here which do not have a src_path / dest_path that matches the watched path + if self._watch.is_recursive or not self._is_recursive_event(event): + logger.debug("queue_event %s", event) + EventEmitter.queue_event(self, event) + else: + logger.debug("drop event %s", event) + + def _is_recursive_event(self, event: FileSystemEvent) -> bool: + src_path = event.src_path if event.is_directory else os.path.dirname(event.src_path) + if src_path == self._absolute_watch_path: + return False + + if isinstance(event, (FileMovedEvent, DirMovedEvent)): + # when moving something into the watch path we must always take the dirname, + # otherwise we miss out on `DirMovedEvent`s + dest_path = os.path.dirname(event.dest_path) + if dest_path == self._absolute_watch_path: + return False + + return True + + def _queue_created_event(self, event: FileSystemEvent, src_path: bytes | str, dirname: bytes | str) -> None: + cls = DirCreatedEvent if event.is_directory else FileCreatedEvent + self.queue_event(cls(src_path)) + self.queue_event(DirModifiedEvent(dirname)) + + def _queue_deleted_event(self, event: FileSystemEvent, src_path: bytes | str, dirname: bytes | str) -> None: + cls = DirDeletedEvent if event.is_directory else FileDeletedEvent + self.queue_event(cls(src_path)) + self.queue_event(DirModifiedEvent(dirname)) + + def _queue_modified_event(self, event: FileSystemEvent, src_path: bytes | str, dirname: bytes | str) -> None: + cls = DirModifiedEvent if event.is_directory else FileModifiedEvent + self.queue_event(cls(src_path)) + + def _queue_renamed_event( + self, + src_event: FileSystemEvent, + src_path: bytes | str, + dst_path: bytes | str, + src_dirname: bytes | str, + dst_dirname: bytes | str, + ) -> None: + cls = DirMovedEvent if src_event.is_directory else FileMovedEvent + dst_path = self._encode_path(dst_path) + self.queue_event(cls(src_path, dst_path)) + self.queue_event(DirModifiedEvent(src_dirname)) + self.queue_event(DirModifiedEvent(dst_dirname)) + + def _is_historic_created_event(self, event: _fsevents.NativeEvent) -> bool: + # We only queue a created event if the item was created after we + # started the FSEventsStream. + + in_history = event.inode in self._fs_view + + if self._starting_state: + try: + old_inode = self._starting_state.inode(event.path)[0] + before_start = old_inode == event.inode + except KeyError: + before_start = False + else: + before_start = False + + return in_history or before_start + + @staticmethod + def _is_meta_mod(event: _fsevents.NativeEvent) -> bool: + """Returns True if the event indicates a change in metadata.""" + return event.is_inode_meta_mod or event.is_xattr_mod or event.is_owner_change + + def queue_events(self, timeout: float, events: list[_fsevents.NativeEvent]) -> None: # type: ignore[override] + if logger.getEffectiveLevel() <= logging.DEBUG: + for event in events: + flags = ", ".join(attr for attr in dir(event) if getattr(event, attr) is True) + logger.debug("%s: %s", event, flags) + + if time.monotonic() - self._start_time > 60: + # Event history is no longer needed, let's free some memory. + self._starting_state = None + + while events: + event = events.pop(0) + + src_path = self._encode_path(event.path) + src_dirname = os.path.dirname(src_path) + + try: + stat = os.stat(src_path) + except OSError: + stat = None + + exists = stat and stat.st_ino == event.inode + + # FSevents may coalesce multiple events for the same item + path into a + # single event. However, events are never coalesced for different items at + # the same path or for the same item at different paths. Therefore, the + # event chains "removed -> created" and "created -> renamed -> removed" will + # never emit a single native event and a deleted event *always* means that + # the item no longer existed at the end of the event chain. + + # Some events will have a spurious `is_created` flag set, coalesced from an + # already emitted and processed CreatedEvent. To filter those, we keep track + # of all inodes which we know to be already created. This is safer than + # keeping track of paths since paths are more likely to be reused than + # inodes. + + # Likewise, some events will have a spurious `is_modified`, + # `is_inode_meta_mod` or `is_xattr_mod` flag set. We currently do not + # suppress those but could do so if the item still exists by caching the + # stat result and verifying that it did change. + + if event.is_created and event.is_removed: + # Events will only be coalesced for the same item / inode. + # The sequence deleted -> created therefore cannot occur. + # Any combination with renamed cannot occur either. + + if not self._is_historic_created_event(event): + self._queue_created_event(event, src_path, src_dirname) + + self._fs_view.add(event.inode) + + if event.is_modified or self._is_meta_mod(event): + self._queue_modified_event(event, src_path, src_dirname) + + self._queue_deleted_event(event, src_path, src_dirname) + self._fs_view.discard(event.inode) + + else: + if event.is_created and not self._is_historic_created_event(event): + self._queue_created_event(event, src_path, src_dirname) + + self._fs_view.add(event.inode) + + if event.is_modified or self._is_meta_mod(event): + self._queue_modified_event(event, src_path, src_dirname) + + if event.is_renamed: + # Check if we have a corresponding destination event in the watched path. + dst_event = next( + iter(e for e in events if e.is_renamed and e.inode == event.inode), + None, + ) + + if dst_event: + # Item was moved within the watched folder. + logger.debug("Destination event for rename is %s", dst_event) + + dst_path = self._encode_path(dst_event.path) + dst_dirname = os.path.dirname(dst_path) + + self._queue_renamed_event(event, src_path, dst_path, src_dirname, dst_dirname) + self._fs_view.add(event.inode) + + for sub_moved_event in generate_sub_moved_events(src_path, dst_path): + self.queue_event(sub_moved_event) + + # Process any coalesced flags for the dst_event. + + events.remove(dst_event) + + if dst_event.is_modified or self._is_meta_mod(dst_event): + self._queue_modified_event(dst_event, dst_path, dst_dirname) + + if dst_event.is_removed: + self._queue_deleted_event(dst_event, dst_path, dst_dirname) + self._fs_view.discard(dst_event.inode) + + elif exists: + # This is the destination event, item was moved into the watched + # folder. + self._queue_created_event(event, src_path, src_dirname) + self._fs_view.add(event.inode) + + for sub_created_event in generate_sub_created_events(src_path): + self.queue_event(sub_created_event) + + else: + # This is the source event, item was moved out of the watched + # folder. + self._queue_deleted_event(event, src_path, src_dirname) + self._fs_view.discard(event.inode) + + # Skip further coalesced processing. + continue + + if event.is_removed: + # Won't occur together with renamed. + self._queue_deleted_event(event, src_path, src_dirname) + self._fs_view.discard(event.inode) + + if event.is_root_changed: + # This will be set if root or any of its parents is renamed or deleted. + # TODO: find out new path and generate DirMovedEvent? + self.queue_event(DirDeletedEvent(self.watch.path)) + logger.debug("Stopping because root path was changed") + self.stop() + + self._fs_view.clear() + + def events_callback(self, paths: list[bytes], inodes: list[int], flags: list[int], ids: list[int]) -> None: + """Callback passed to FSEventStreamCreate(), it will receive all + FS events and queue them. + """ + cls = _fsevents.NativeEvent + try: + events = [ + cls(path, inode, event_flags, event_id) + for path, inode, event_flags, event_id in zip(paths, inodes, flags, ids) + ] + with self._lock: + self.queue_events(self.timeout, events) + except Exception: + logger.exception("Unhandled exception in fsevents callback") + + def run(self) -> None: + self.pathnames = [self.watch.path] + self._start_time = time.monotonic() + try: + _fsevents.add_watch(self, self.watch, self.events_callback, self.pathnames) + _fsevents.read_events(self) + except Exception: + logger.exception("Unhandled exception in FSEventsEmitter") + + def on_thread_start(self) -> None: + if self.suppress_history: + watch_path = os.fsdecode(self.watch.path) if isinstance(self.watch.path, bytes) else self.watch.path + self._starting_state = DirectorySnapshot(watch_path) + + def _encode_path(self, path: bytes | str) -> bytes | str: + """Encode path only if bytes were passed to this emitter.""" + return os.fsencode(path) if isinstance(self.watch.path, bytes) else path + + +class FSEventsObserver(BaseObserver): + def __init__(self, *, timeout: float = DEFAULT_OBSERVER_TIMEOUT) -> None: + super().__init__(FSEventsEmitter, timeout=timeout) + + def schedule( + self, + event_handler: FileSystemEventHandler, + path: str, + *, + recursive: bool = False, + event_filter: list[type[FileSystemEvent]] | None = None, + ) -> ObservedWatch: + # Fix for issue #26: Trace/BPT error when given a unicode path + # string. https://github.com/gorakhargosh/watchdog/issues#issue/26 + if isinstance(path, str): + path = unicodedata.normalize("NFC", path) + + return super().schedule(event_handler, path, recursive=recursive, event_filter=event_filter) diff --git a/.venv/Lib/site-packages/watchdog/observers/fsevents2.py b/.venv/Lib/site-packages/watchdog/observers/fsevents2.py new file mode 100644 index 0000000000000000000000000000000000000000..3d1f7e9b1eb7dd03bd58a52aa0728f2b590aaa0a --- /dev/null +++ b/.venv/Lib/site-packages/watchdog/observers/fsevents2.py @@ -0,0 +1,253 @@ +""":module: watchdog.observers.fsevents2 +:synopsis: FSEvents based emitter implementation. +:author: thomas.amland@gmail.com (Thomas Amland) +:author: contact@tiger-222.fr (MickaΓ«l Schoentgen) +:platforms: macOS +""" + +from __future__ import annotations + +import logging +import os +import queue +import unicodedata +import warnings +from threading import Thread +from typing import TYPE_CHECKING + +# pyobjc +import AppKit +from FSEvents import ( + CFRunLoopGetCurrent, + CFRunLoopRun, + CFRunLoopStop, + FSEventStreamCreate, + FSEventStreamInvalidate, + FSEventStreamRelease, + FSEventStreamScheduleWithRunLoop, + FSEventStreamStart, + FSEventStreamStop, + kCFAllocatorDefault, + kCFRunLoopDefaultMode, + kFSEventStreamCreateFlagFileEvents, + kFSEventStreamCreateFlagNoDefer, + kFSEventStreamEventFlagItemChangeOwner, + kFSEventStreamEventFlagItemCreated, + kFSEventStreamEventFlagItemFinderInfoMod, + kFSEventStreamEventFlagItemInodeMetaMod, + kFSEventStreamEventFlagItemIsDir, + kFSEventStreamEventFlagItemIsSymlink, + kFSEventStreamEventFlagItemModified, + kFSEventStreamEventFlagItemRemoved, + kFSEventStreamEventFlagItemRenamed, + kFSEventStreamEventFlagItemXattrMod, + kFSEventStreamEventIdSinceNow, +) + +from watchdog.events import ( + DirCreatedEvent, + DirDeletedEvent, + DirModifiedEvent, + DirMovedEvent, + FileCreatedEvent, + FileDeletedEvent, + FileModifiedEvent, + FileMovedEvent, + FileSystemEvent, +) +from watchdog.observers.api import DEFAULT_EMITTER_TIMEOUT, DEFAULT_OBSERVER_TIMEOUT, BaseObserver, EventEmitter + +if TYPE_CHECKING: + from typing import Callable + + from watchdog.observers.api import EventQueue, ObservedWatch + +logger = logging.getLogger(__name__) + +message = "watchdog.observers.fsevents2 is deprecated and will be removed in a future release." +warnings.warn(message, category=DeprecationWarning, stacklevel=1) +logger.warning(message) + + +class FSEventsQueue(Thread): + """Low level FSEvents client.""" + + def __init__(self, path: bytes | str) -> None: + Thread.__init__(self) + self._queue: queue.Queue[list[NativeEvent] | None] = queue.Queue() + self._run_loop = None + + if isinstance(path, bytes): + path = os.fsdecode(path) + self._path = unicodedata.normalize("NFC", path) + + context = None + latency = 1.0 + self._stream_ref = FSEventStreamCreate( + kCFAllocatorDefault, + self._callback, + context, + [self._path], + kFSEventStreamEventIdSinceNow, + latency, + kFSEventStreamCreateFlagNoDefer | kFSEventStreamCreateFlagFileEvents, + ) + if self._stream_ref is None: + error = "FSEvents. Could not create stream." + raise OSError(error) + + def run(self) -> None: + pool = AppKit.NSAutoreleasePool.alloc().init() + self._run_loop = CFRunLoopGetCurrent() + FSEventStreamScheduleWithRunLoop(self._stream_ref, self._run_loop, kCFRunLoopDefaultMode) + if not FSEventStreamStart(self._stream_ref): + FSEventStreamInvalidate(self._stream_ref) + FSEventStreamRelease(self._stream_ref) + error = "FSEvents. Could not start stream." + raise OSError(error) + + CFRunLoopRun() + FSEventStreamStop(self._stream_ref) + FSEventStreamInvalidate(self._stream_ref) + FSEventStreamRelease(self._stream_ref) + del pool + # Make sure waiting thread is notified + self._queue.put(None) + + def stop(self) -> None: + if self._run_loop is not None: + CFRunLoopStop(self._run_loop) + + def _callback( + self, + stream_ref: int, + client_callback_info: Callable, + num_events: int, + event_paths: list[bytes], + event_flags: list[int], + event_ids: list[int], + ) -> None: + events = [NativeEvent(path, flags, _id) for path, flags, _id in zip(event_paths, event_flags, event_ids)] + logger.debug("FSEvents callback. Got %d events:", num_events) + for e in events: + logger.debug(e) + self._queue.put(events) + + def read_events(self) -> list[NativeEvent] | None: + """Returns a list or one or more events, or None if there are no more + events to be read. + """ + return self._queue.get() if self.is_alive() else None + + +class NativeEvent: + def __init__(self, path: bytes, flags: int, event_id: int) -> None: + self.path = path + self.flags = flags + self.event_id = event_id + self.is_created = bool(flags & kFSEventStreamEventFlagItemCreated) + self.is_removed = bool(flags & kFSEventStreamEventFlagItemRemoved) + self.is_renamed = bool(flags & kFSEventStreamEventFlagItemRenamed) + self.is_modified = bool(flags & kFSEventStreamEventFlagItemModified) + self.is_change_owner = bool(flags & kFSEventStreamEventFlagItemChangeOwner) + self.is_inode_meta_mod = bool(flags & kFSEventStreamEventFlagItemInodeMetaMod) + self.is_finder_info_mod = bool(flags & kFSEventStreamEventFlagItemFinderInfoMod) + self.is_xattr_mod = bool(flags & kFSEventStreamEventFlagItemXattrMod) + self.is_symlink = bool(flags & kFSEventStreamEventFlagItemIsSymlink) + self.is_directory = bool(flags & kFSEventStreamEventFlagItemIsDir) + + @property + def _event_type(self) -> str: + if self.is_created: + return "Created" + if self.is_removed: + return "Removed" + if self.is_renamed: + return "Renamed" + if self.is_modified: + return "Modified" + if self.is_inode_meta_mod: + return "InodeMetaMod" + if self.is_xattr_mod: + return "XattrMod" + return "Unknown" + + def __repr__(self) -> str: + return ( + f"<{type(self).__name__}: path={self.path!r}, type={self._event_type}," + f" is_dir={self.is_directory}, flags={hex(self.flags)}, id={self.event_id}>" + ) + + +class FSEventsEmitter(EventEmitter): + """FSEvents based event emitter. Handles conversion of native events.""" + + def __init__( + self, + event_queue: EventQueue, + watch: ObservedWatch, + *, + timeout: float = DEFAULT_EMITTER_TIMEOUT, + event_filter: list[type[FileSystemEvent]] | None = None, + ): + super().__init__(event_queue, watch, timeout=timeout, event_filter=event_filter) + self._fsevents = FSEventsQueue(watch.path) + self._fsevents.start() + + def on_thread_stop(self) -> None: + self._fsevents.stop() + + def queue_events(self, timeout: float) -> None: + events = self._fsevents.read_events() + if events is None: + return + i = 0 + while i < len(events): + event = events[i] + + cls: type[FileSystemEvent] + # For some reason the create and remove flags are sometimes also + # set for rename and modify type events, so let those take + # precedence. + if event.is_renamed: + # Internal moves appears to always be consecutive in the same + # buffer and have IDs differ by exactly one (while others + # don't) making it possible to pair up the two events coming + # from a single move operation. (None of this is documented!) + # Otherwise, guess whether file was moved in or out. + # TODO: handle id wrapping + if i + 1 < len(events) and events[i + 1].is_renamed and events[i + 1].event_id == event.event_id + 1: + cls = DirMovedEvent if event.is_directory else FileMovedEvent + self.queue_event(cls(event.path, events[i + 1].path)) + self.queue_event(DirModifiedEvent(os.path.dirname(event.path))) + self.queue_event(DirModifiedEvent(os.path.dirname(events[i + 1].path))) + i += 1 + elif os.path.exists(event.path): + cls = DirCreatedEvent if event.is_directory else FileCreatedEvent + self.queue_event(cls(event.path)) + self.queue_event(DirModifiedEvent(os.path.dirname(event.path))) + else: + cls = DirDeletedEvent if event.is_directory else FileDeletedEvent + self.queue_event(cls(event.path)) + self.queue_event(DirModifiedEvent(os.path.dirname(event.path))) + # TODO: generate events for tree + + elif event.is_modified or event.is_inode_meta_mod or event.is_xattr_mod: + cls = DirModifiedEvent if event.is_directory else FileModifiedEvent + self.queue_event(cls(event.path)) + + elif event.is_created: + cls = DirCreatedEvent if event.is_directory else FileCreatedEvent + self.queue_event(cls(event.path)) + self.queue_event(DirModifiedEvent(os.path.dirname(event.path))) + + elif event.is_removed: + cls = DirDeletedEvent if event.is_directory else FileDeletedEvent + self.queue_event(cls(event.path)) + self.queue_event(DirModifiedEvent(os.path.dirname(event.path))) + i += 1 + + +class FSEventsObserver2(BaseObserver): + def __init__(self, *, timeout: float = DEFAULT_OBSERVER_TIMEOUT) -> None: + super().__init__(FSEventsEmitter, timeout=timeout) diff --git a/.venv/Lib/site-packages/watchdog/observers/inotify.py b/.venv/Lib/site-packages/watchdog/observers/inotify.py new file mode 100644 index 0000000000000000000000000000000000000000..a07aee5cf4451d28e74f940a7f4fe72f02b72b9c --- /dev/null +++ b/.venv/Lib/site-packages/watchdog/observers/inotify.py @@ -0,0 +1,252 @@ +""":module: watchdog.observers.inotify +:synopsis: ``inotify(7)`` based emitter implementation. +:author: Sebastien Martini +:author: Luke McCarthy +:author: yesudeep@google.com (Yesudeep Mangalapilly) +:author: Tim Cuthbertson +:author: contact@tiger-222.fr (MickaΓ«l Schoentgen) +:platforms: Linux 2.6.13+. + +.. ADMONITION:: About system requirements + + Recommended minimum kernel version: 2.6.25. + + Quote from the inotify(7) man page: + + "Inotify was merged into the 2.6.13 Linux kernel. The required library + interfaces were added to glibc in version 2.4. (IN_DONT_FOLLOW, + IN_MASK_ADD, and IN_ONLYDIR were only added in version 2.5.)" + + Therefore, you must ensure the system is running at least these versions + appropriate libraries and the kernel. + +.. ADMONITION:: About recursiveness, event order, and event coalescing + + Quote from the inotify(7) man page: + + If successive output inotify events produced on the inotify file + descriptor are identical (same wd, mask, cookie, and name) then they + are coalesced into a single event if the older event has not yet been + read (but see BUGS). + + The events returned by reading from an inotify file descriptor form + an ordered queue. Thus, for example, it is guaranteed that when + renaming from one directory to another, events will be produced in + the correct order on the inotify file descriptor. + + ... + + Inotify monitoring of directories is not recursive: to monitor + subdirectories under a directory, additional watches must be created. + + This emitter implementation therefore automatically adds watches for + sub-directories if running in recursive mode. + +Some extremely useful articles and documentation: + +.. _inotify FAQ: http://inotify.aiken.cz/?section=inotify&page=faq&lang=en +.. _intro to inotify: http://www.linuxjournal.com/article/8478 + +""" + +from __future__ import annotations + +import logging +import os +import threading +from typing import TYPE_CHECKING + +from watchdog.events import ( + DirCreatedEvent, + DirDeletedEvent, + DirModifiedEvent, + DirMovedEvent, + FileClosedEvent, + FileClosedNoWriteEvent, + FileCreatedEvent, + FileDeletedEvent, + FileModifiedEvent, + FileMovedEvent, + FileOpenedEvent, + FileSystemEvent, + generate_sub_created_events, + generate_sub_moved_events, +) +from watchdog.observers.api import DEFAULT_EMITTER_TIMEOUT, DEFAULT_OBSERVER_TIMEOUT, BaseObserver, EventEmitter +from watchdog.observers.inotify_buffer import InotifyBuffer +from watchdog.observers.inotify_c import InotifyConstants + +if TYPE_CHECKING: + from watchdog.observers.api import EventQueue, ObservedWatch + +logger = logging.getLogger(__name__) + + +class InotifyEmitter(EventEmitter): + """inotify(7)-based event emitter. + + :param event_queue: + The event queue to fill with events. + :param watch: + A watch object representing the directory to monitor. + :type watch: + :class:`watchdog.observers.api.ObservedWatch` + :param timeout: + Read events blocking timeout (in seconds). + :type timeout: + ``float`` + :param event_filter: + Collection of event types to emit, or None for no filtering (default). + :type event_filter: + Iterable[:class:`watchdog.events.FileSystemEvent`] | None + """ + + def __init__( + self, + event_queue: EventQueue, + watch: ObservedWatch, + *, + timeout: float = DEFAULT_EMITTER_TIMEOUT, + event_filter: list[type[FileSystemEvent]] | None = None, + ) -> None: + super().__init__(event_queue, watch, timeout=timeout, event_filter=event_filter) + self._lock = threading.Lock() + self._inotify: InotifyBuffer | None = None + + def on_thread_start(self) -> None: + path = os.fsencode(self.watch.path) + event_mask = self.get_event_mask_from_filter() + self._inotify = InotifyBuffer(path, recursive=self.watch.is_recursive, event_mask=event_mask) + + def on_thread_stop(self) -> None: + if self._inotify: + self._inotify.close() + self._inotify = None + + def queue_events(self, timeout: float, *, full_events: bool = False) -> None: + # If "full_events" is true, then the method will report unmatched move events as separate events + # This behavior is by default only called by a InotifyFullEmitter + if self._inotify is None: + logger.error("InotifyEmitter.queue_events() called when the thread is inactive") + return + with self._lock: + if self._inotify is None: + logger.error("InotifyEmitter.queue_events() called when the thread is inactive") + return + event = self._inotify.read_event() + if event is None: + return + + cls: type[FileSystemEvent] + if isinstance(event, tuple): + move_from, move_to = event + src_path = self._decode_path(move_from.src_path) + dest_path = self._decode_path(move_to.src_path) + cls = DirMovedEvent if move_from.is_directory else FileMovedEvent + self.queue_event(cls(src_path, dest_path)) + self.queue_event(DirModifiedEvent(os.path.dirname(src_path))) + self.queue_event(DirModifiedEvent(os.path.dirname(dest_path))) + if move_from.is_directory and self.watch.is_recursive: + for sub_moved_event in generate_sub_moved_events(src_path, dest_path): + self.queue_event(sub_moved_event) + return + + src_path = self._decode_path(event.src_path) + if event.is_moved_to: + if full_events: + cls = DirMovedEvent if event.is_directory else FileMovedEvent + self.queue_event(cls("", src_path)) + else: + cls = DirCreatedEvent if event.is_directory else FileCreatedEvent + self.queue_event(cls(src_path)) + self.queue_event(DirModifiedEvent(os.path.dirname(src_path))) + if event.is_directory and self.watch.is_recursive: + for sub_created_event in generate_sub_created_events(src_path): + self.queue_event(sub_created_event) + elif event.is_attrib or event.is_modify: + cls = DirModifiedEvent if event.is_directory else FileModifiedEvent + self.queue_event(cls(src_path)) + elif event.is_delete or (event.is_moved_from and not full_events): + cls = DirDeletedEvent if event.is_directory else FileDeletedEvent + self.queue_event(cls(src_path)) + self.queue_event(DirModifiedEvent(os.path.dirname(src_path))) + elif event.is_moved_from and full_events: + cls = DirMovedEvent if event.is_directory else FileMovedEvent + self.queue_event(cls(src_path, "")) + self.queue_event(DirModifiedEvent(os.path.dirname(src_path))) + elif event.is_create: + cls = DirCreatedEvent if event.is_directory else FileCreatedEvent + self.queue_event(cls(src_path)) + self.queue_event(DirModifiedEvent(os.path.dirname(src_path))) + elif event.is_delete_self and src_path == self.watch.path: + cls = DirDeletedEvent if event.is_directory else FileDeletedEvent + self.queue_event(cls(src_path)) + self.stop() + elif not event.is_directory: + if event.is_open: + cls = FileOpenedEvent + self.queue_event(cls(src_path)) + elif event.is_close_write: + cls = FileClosedEvent + self.queue_event(cls(src_path)) + self.queue_event(DirModifiedEvent(os.path.dirname(src_path))) + elif event.is_close_nowrite: + cls = FileClosedNoWriteEvent + self.queue_event(cls(src_path)) + + def _decode_path(self, path: bytes | str) -> bytes | str: + """Decode path only if unicode string was passed to this emitter.""" + return path if isinstance(self.watch.path, bytes) else os.fsdecode(path) + + def get_event_mask_from_filter(self) -> int | None: + """Optimization: Only include events we are filtering in inotify call.""" + if self._event_filter is None: + return None + + # Always listen to delete self + event_mask = InotifyConstants.IN_DELETE_SELF + + for cls in self._event_filter: + if cls in {DirMovedEvent, FileMovedEvent}: + event_mask |= InotifyConstants.IN_MOVE + elif cls in {DirCreatedEvent, FileCreatedEvent}: + event_mask |= InotifyConstants.IN_MOVE | InotifyConstants.IN_CREATE + elif cls is DirModifiedEvent: + event_mask |= ( + InotifyConstants.IN_MOVE + | InotifyConstants.IN_ATTRIB + | InotifyConstants.IN_MODIFY + | InotifyConstants.IN_CREATE + | InotifyConstants.IN_CLOSE_WRITE + ) + elif cls is FileModifiedEvent: + event_mask |= InotifyConstants.IN_ATTRIB | InotifyConstants.IN_MODIFY + elif cls in {DirDeletedEvent, FileDeletedEvent}: + event_mask |= InotifyConstants.IN_DELETE + elif cls is FileClosedEvent: + event_mask |= InotifyConstants.IN_CLOSE_WRITE + elif cls is FileClosedNoWriteEvent: + event_mask |= InotifyConstants.IN_CLOSE_NOWRITE + elif cls is FileOpenedEvent: + event_mask |= InotifyConstants.IN_OPEN + + return event_mask + + +class InotifyFullEmitter(InotifyEmitter): + """inotify(7)-based event emitter. By default this class produces move events even if they are not matched + Such move events will have a ``None`` value for the unmatched part. + """ + + def queue_events(self, timeout: float, *, events: bool = True) -> None: # type: ignore[override] + super().queue_events(timeout, full_events=events) + + +class InotifyObserver(BaseObserver): + """Observer thread that schedules watching directories and dispatches + calls to event handlers. + """ + + def __init__(self, *, timeout: float = DEFAULT_OBSERVER_TIMEOUT, generate_full_events: bool = False) -> None: + cls = InotifyFullEmitter if generate_full_events else InotifyEmitter + super().__init__(cls, timeout=timeout) diff --git a/.venv/Lib/site-packages/watchdog/observers/inotify_buffer.py b/.venv/Lib/site-packages/watchdog/observers/inotify_buffer.py new file mode 100644 index 0000000000000000000000000000000000000000..f542974a041ef5d27ea9c6cd4113a8827dfb68bd --- /dev/null +++ b/.venv/Lib/site-packages/watchdog/observers/inotify_buffer.py @@ -0,0 +1,102 @@ +""":module: watchdog.observers.inotify_buffer +:synopsis: A wrapper for ``Inotify``. +:author: thomas.amland@gmail.com (Thomas Amland) +:author: contact@tiger-222.fr (MickaΓ«l Schoentgen) +:platforms: linux +""" + +from __future__ import annotations + +import logging + +from watchdog.observers.inotify_c import Inotify, InotifyEvent +from watchdog.utils import BaseThread +from watchdog.utils.delayed_queue import DelayedQueue + +logger = logging.getLogger(__name__) + + +class InotifyBuffer(BaseThread): + """A wrapper for `Inotify` that holds events for `delay` seconds. During + this time, IN_MOVED_FROM and IN_MOVED_TO events are paired. + """ + + delay = 0.5 + + def __init__(self, path: bytes, *, recursive: bool = False, event_mask: int | None = None) -> None: + super().__init__() + # XXX: Remove quotes after Python 3.9 drop + self._queue = DelayedQueue["InotifyEvent | tuple[InotifyEvent, InotifyEvent]"](self.delay) + self._inotify = Inotify(path, recursive=recursive, event_mask=event_mask) + self.start() + + def read_event(self) -> InotifyEvent | tuple[InotifyEvent, InotifyEvent] | None: + """Returns a single event or a tuple of from/to events in case of a + paired move event. If this buffer has been closed, immediately return + None. + """ + return self._queue.get() + + def on_thread_stop(self) -> None: + self._inotify.close() + self._queue.close() + + def close(self) -> None: + self.stop() + self.join() + + def _group_events(self, event_list: list[InotifyEvent]) -> list[InotifyEvent | tuple[InotifyEvent, InotifyEvent]]: + """Group any matching move events""" + grouped: list[InotifyEvent | tuple[InotifyEvent, InotifyEvent]] = [] + for inotify_event in event_list: + logger.debug("in-event %s", inotify_event) + + def matching_from_event(event: InotifyEvent | tuple[InotifyEvent, InotifyEvent]) -> bool: + return not isinstance(event, tuple) and event.is_moved_from and event.cookie == inotify_event.cookie + + if inotify_event.is_moved_to: + # Check if move_from is already in the buffer + for index, event in enumerate(grouped): + if matching_from_event(event): + grouped[index] = (event, inotify_event) # type: ignore[assignment] + break + else: + # Check if move_from is in delayqueue already + from_event = self._queue.remove(matching_from_event) + if from_event is not None: + grouped.append((from_event, inotify_event)) # type: ignore[arg-type] + else: + logger.debug("could not find matching move_from event") + grouped.append(inotify_event) + else: + grouped.append(inotify_event) + return grouped + + def run(self) -> None: + """Read event from `inotify` and add them to `queue`. When reading a + IN_MOVE_TO event, remove the previous added matching IN_MOVE_FROM event + and add them back to the queue as a tuple. + """ + deleted_self = False + while self.should_keep_running() and not deleted_self: + inotify_events = self._inotify.read_events() + grouped_events = self._group_events(inotify_events) + for inotify_event in grouped_events: + if not isinstance(inotify_event, tuple) and inotify_event.is_ignored: + if inotify_event.src_path == self._inotify.path: + # Watch was removed explicitly (inotify_rm_watch(2)) or automatically (file + # was deleted, or filesystem was unmounted), stop watching for events + deleted_self = True + continue + + # Only add delay for unmatched move_from events + delay = not isinstance(inotify_event, tuple) and inotify_event.is_moved_from + self._queue.put(inotify_event, delay=delay) + + if ( + not isinstance(inotify_event, tuple) + and inotify_event.is_delete_self + and inotify_event.src_path == self._inotify.path + ): + # Deleted the watched directory, stop watching for events + deleted_self = True diff --git a/.venv/Lib/site-packages/watchdog/observers/inotify_c.py b/.venv/Lib/site-packages/watchdog/observers/inotify_c.py new file mode 100644 index 0000000000000000000000000000000000000000..33cbd25dda6eaf205c541e56cedf9ddf8d62cc4c --- /dev/null +++ b/.venv/Lib/site-packages/watchdog/observers/inotify_c.py @@ -0,0 +1,605 @@ +from __future__ import annotations + +import contextlib +import ctypes +import ctypes.util +import errno +import os +import select +import struct +import threading +from ctypes import c_char_p, c_int, c_uint32 +from functools import reduce +from typing import TYPE_CHECKING + +from watchdog.utils import UnsupportedLibcError + +if TYPE_CHECKING: + from collections.abc import Generator + +libc = ctypes.CDLL(None) + +if not hasattr(libc, "inotify_init") or not hasattr(libc, "inotify_add_watch") or not hasattr(libc, "inotify_rm_watch"): + error = f"Unsupported libc version found: {libc._name}" # noqa:SLF001 + raise UnsupportedLibcError(error) + +inotify_add_watch = ctypes.CFUNCTYPE(c_int, c_int, c_char_p, c_uint32, use_errno=True)(("inotify_add_watch", libc)) + +inotify_rm_watch = ctypes.CFUNCTYPE(c_int, c_int, c_uint32, use_errno=True)(("inotify_rm_watch", libc)) + +inotify_init = ctypes.CFUNCTYPE(c_int, use_errno=True)(("inotify_init", libc)) + + +class InotifyConstants: + # User-space events + IN_ACCESS = 0x00000001 # File was accessed. + IN_MODIFY = 0x00000002 # File was modified. + IN_ATTRIB = 0x00000004 # Meta-data changed. + IN_CLOSE_WRITE = 0x00000008 # Writable file was closed. + IN_CLOSE_NOWRITE = 0x00000010 # Unwritable file closed. + IN_OPEN = 0x00000020 # File was opened. + IN_MOVED_FROM = 0x00000040 # File was moved from X. + IN_MOVED_TO = 0x00000080 # File was moved to Y. + IN_CREATE = 0x00000100 # Subfile was created. + IN_DELETE = 0x00000200 # Subfile was deleted. + IN_DELETE_SELF = 0x00000400 # Self was deleted. + IN_MOVE_SELF = 0x00000800 # Self was moved. + + # Helper user-space events. + IN_MOVE = IN_MOVED_FROM | IN_MOVED_TO # Moves. + + # Events sent by the kernel to a watch. + IN_UNMOUNT = 0x00002000 # Backing file system was unmounted. + IN_Q_OVERFLOW = 0x00004000 # Event queued overflowed. + IN_IGNORED = 0x00008000 # File was ignored. + + # Special flags. + IN_ONLYDIR = 0x01000000 # Only watch the path if it's a directory. + IN_DONT_FOLLOW = 0x02000000 # Do not follow a symbolic link. + IN_EXCL_UNLINK = 0x04000000 # Exclude events on unlinked objects + IN_MASK_ADD = 0x20000000 # Add to the mask of an existing watch. + IN_ISDIR = 0x40000000 # Event occurred against directory. + IN_ONESHOT = 0x80000000 # Only send event once. + + # All user-space events. + IN_ALL_EVENTS = reduce( + lambda x, y: x | y, + [ + IN_ACCESS, + IN_MODIFY, + IN_ATTRIB, + IN_CLOSE_WRITE, + IN_CLOSE_NOWRITE, + IN_OPEN, + IN_MOVED_FROM, + IN_MOVED_TO, + IN_DELETE, + IN_CREATE, + IN_DELETE_SELF, + IN_MOVE_SELF, + ], + ) + + # Flags for ``inotify_init1`` + IN_CLOEXEC = 0x02000000 + IN_NONBLOCK = 0x00004000 + + +# Watchdog's API cares only about these events. +WATCHDOG_ALL_EVENTS = reduce( + lambda x, y: x | y, + [ + InotifyConstants.IN_MODIFY, + InotifyConstants.IN_ATTRIB, + InotifyConstants.IN_MOVED_FROM, + InotifyConstants.IN_MOVED_TO, + InotifyConstants.IN_CREATE, + InotifyConstants.IN_DELETE, + InotifyConstants.IN_DELETE_SELF, + InotifyConstants.IN_DONT_FOLLOW, + InotifyConstants.IN_CLOSE_WRITE, + InotifyConstants.IN_CLOSE_NOWRITE, + InotifyConstants.IN_OPEN, + ], +) + + +class InotifyEventStruct(ctypes.Structure): + """Structure representation of the inotify_event structure + (used in buffer size calculations):: + + struct inotify_event { + __s32 wd; /* watch descriptor */ + __u32 mask; /* watch mask */ + __u32 cookie; /* cookie to synchronize two events */ + __u32 len; /* length (including nulls) of name */ + char name[0]; /* stub for possible name */ + }; + """ + + _fields_ = ( + ("wd", c_int), + ("mask", c_uint32), + ("cookie", c_uint32), + ("len", c_uint32), + ("name", c_char_p), + ) + + +EVENT_SIZE = ctypes.sizeof(InotifyEventStruct) +DEFAULT_NUM_EVENTS = 2048 +DEFAULT_EVENT_BUFFER_SIZE = DEFAULT_NUM_EVENTS * (EVENT_SIZE + 16) + + +class Inotify: + """Linux inotify(7) API wrapper class. + + :param path: + The directory path for which we want an inotify object. + :type path: + :class:`bytes` + :param recursive: + ``True`` if subdirectories should be monitored; ``False`` otherwise. + """ + + def __init__(self, path: bytes, *, recursive: bool = False, event_mask: int | None = None) -> None: + # The file descriptor associated with the inotify instance. + inotify_fd = inotify_init() + if inotify_fd == -1: + Inotify._raise_error() + self._inotify_fd = inotify_fd + self._lock = threading.Lock() + self._closed = False + self._is_reading = True + self._kill_r, self._kill_w = os.pipe() + + # _check_inotify_fd will return true if we can read _inotify_fd without blocking + if hasattr(select, "poll"): + self._poller = select.poll() + self._poller.register(self._inotify_fd, select.POLLIN) + self._poller.register(self._kill_r, select.POLLIN) + + def do_poll() -> bool: + return any(fd == self._inotify_fd for fd, _ in self._poller.poll()) + + self._check_inotify_fd = do_poll + else: + + def do_select() -> bool: + result = select.select([self._inotify_fd, self._kill_r], [], []) + return self._inotify_fd in result[0] + + self._check_inotify_fd = do_select + + # Stores the watch descriptor for a given path. + self._wd_for_path: dict[bytes, int] = {} + self._path_for_wd: dict[int, bytes] = {} + + self._path = path + # Default to all events + if event_mask is None: + event_mask = WATCHDOG_ALL_EVENTS + self._event_mask = event_mask + self._is_recursive = recursive + if os.path.isdir(path): + self._add_dir_watch(path, event_mask, recursive=recursive) + else: + self._add_watch(path, event_mask) + self._moved_from_events: dict[int, InotifyEvent] = {} + + @property + def event_mask(self) -> int: + """The event mask for this inotify instance.""" + return self._event_mask + + @property + def path(self) -> bytes: + """The path associated with the inotify instance.""" + return self._path + + @property + def is_recursive(self) -> bool: + """Whether we are watching directories recursively.""" + return self._is_recursive + + @property + def fd(self) -> int: + """The file descriptor associated with the inotify instance.""" + return self._inotify_fd + + def clear_move_records(self) -> None: + """Clear cached records of MOVED_FROM events""" + self._moved_from_events = {} + + def source_for_move(self, destination_event: InotifyEvent) -> bytes | None: + """The source path corresponding to the given MOVED_TO event. + + If the source path is outside the monitored directories, None + is returned instead. + """ + if destination_event.cookie in self._moved_from_events: + return self._moved_from_events[destination_event.cookie].src_path + + return None + + def remember_move_from_event(self, event: InotifyEvent) -> None: + """Save this event as the source event for future MOVED_TO events to + reference. + """ + self._moved_from_events[event.cookie] = event + + def add_watch(self, path: bytes) -> None: + """Adds a watch for the given path. + + :param path: + Path to begin monitoring. + """ + with self._lock: + self._add_watch(path, self._event_mask) + + def remove_watch(self, path: bytes) -> None: + """Removes a watch for the given path. + + :param path: + Path string for which the watch will be removed. + """ + with self._lock: + wd = self._wd_for_path.pop(path) + del self._path_for_wd[wd] + if inotify_rm_watch(self._inotify_fd, wd) == -1: + Inotify._raise_error() + + def close(self) -> None: + """Closes the inotify instance and removes all associated watches.""" + with self._lock: + if not self._closed: + self._closed = True + + if self._path in self._wd_for_path: + wd = self._wd_for_path[self._path] + inotify_rm_watch(self._inotify_fd, wd) + + if self._is_reading: + # inotify_rm_watch() should write data to _inotify_fd and wake + # the thread, but writing to the kill channel will gaurentee this + os.write(self._kill_w, b"!") + else: + self._close_resources() + + def read_events(self, *, event_buffer_size: int = DEFAULT_EVENT_BUFFER_SIZE) -> list[InotifyEvent]: + """Reads events from inotify and yields them.""" + # HACK: We need to traverse the directory path + # recursively and simulate events for newly + # created subdirectories/files. This will handle + # mkdir -p foobar/blah/bar; touch foobar/afile + + def _recursive_simulate(src_path: bytes) -> list[InotifyEvent]: + events = [] + for root, dirnames, filenames in os.walk(src_path): + for dirname in dirnames: + with contextlib.suppress(OSError): + full_path = os.path.join(root, dirname) + wd_dir = self._add_watch(full_path, self._event_mask) + e = InotifyEvent( + wd_dir, + InotifyConstants.IN_CREATE | InotifyConstants.IN_ISDIR, + 0, + dirname, + full_path, + ) + events.append(e) + for filename in filenames: + full_path = os.path.join(root, filename) + wd_parent_dir = self._wd_for_path[os.path.dirname(full_path)] + e = InotifyEvent( + wd_parent_dir, + InotifyConstants.IN_CREATE, + 0, + filename, + full_path, + ) + events.append(e) + return events + + event_buffer = b"" + while True: + try: + with self._lock: + if self._closed: + return [] + + self._is_reading = True + + if self._check_inotify_fd(): + event_buffer = os.read(self._inotify_fd, event_buffer_size) + + with self._lock: + self._is_reading = False + + if self._closed: + self._close_resources() + return [] + except OSError as e: + if e.errno == errno.EINTR: + continue + + if e.errno == errno.EBADF: + return [] + + raise + break + + with self._lock: + event_list = [] + for wd, mask, cookie, name in Inotify._parse_event_buffer(event_buffer): + if wd == -1: + continue + wd_path = self._path_for_wd[wd] + src_path = os.path.join(wd_path, name) if name else wd_path # avoid trailing slash + inotify_event = InotifyEvent(wd, mask, cookie, name, src_path) + + if inotify_event.is_moved_from: + self.remember_move_from_event(inotify_event) + elif inotify_event.is_moved_to: + move_src_path = self.source_for_move(inotify_event) + if move_src_path in self._wd_for_path: + moved_wd = self._wd_for_path[move_src_path] + del self._wd_for_path[move_src_path] + self._wd_for_path[inotify_event.src_path] = moved_wd + self._path_for_wd[moved_wd] = inotify_event.src_path + if self.is_recursive: + for _path in self._wd_for_path.copy(): + if _path.startswith(move_src_path + os.path.sep.encode()): + moved_wd = self._wd_for_path.pop(_path) + _move_to_path = _path.replace(move_src_path, inotify_event.src_path) + self._wd_for_path[_move_to_path] = moved_wd + self._path_for_wd[moved_wd] = _move_to_path + src_path = os.path.join(wd_path, name) + inotify_event = InotifyEvent(wd, mask, cookie, name, src_path) + + if inotify_event.is_ignored: + # Clean up book-keeping for deleted watches. + path = self._path_for_wd.pop(wd) + if self._wd_for_path[path] == wd: + del self._wd_for_path[path] + + event_list.append(inotify_event) + + if self.is_recursive and inotify_event.is_directory and inotify_event.is_create: + # TODO: When a directory from another part of the + # filesystem is moved into a watched directory, this + # will not generate events for the directory tree. + # We need to coalesce IN_MOVED_TO events and those + # IN_MOVED_TO events which don't pair up with + # IN_MOVED_FROM events should be marked IN_CREATE + # instead relative to this directory. + try: + self._add_watch(src_path, self._event_mask) + except OSError: + continue + + event_list.extend(_recursive_simulate(src_path)) + + return event_list + + def _close_resources(self) -> None: + os.close(self._inotify_fd) + os.close(self._kill_r) + os.close(self._kill_w) + + # Non-synchronized methods. + def _add_dir_watch(self, path: bytes, mask: int, *, recursive: bool) -> None: + """Adds a watch (optionally recursively) for the given directory path + to monitor events specified by the mask. + + :param path: + Path to monitor + :param recursive: + ``True`` to monitor recursively. + :param mask: + Event bit mask. + """ + if not os.path.isdir(path): + raise OSError(errno.ENOTDIR, os.strerror(errno.ENOTDIR), path) + self._add_watch(path, mask) + if recursive: + for root, dirnames, _ in os.walk(path): + for dirname in dirnames: + full_path = os.path.join(root, dirname) + if os.path.islink(full_path): + continue + self._add_watch(full_path, mask) + + def _add_watch(self, path: bytes, mask: int) -> int: + """Adds a watch for the given path to monitor events specified by the + mask. + + :param path: + Path to monitor + :param mask: + Event bit mask. + """ + wd = inotify_add_watch(self._inotify_fd, path, mask) + if wd == -1: + Inotify._raise_error() + self._wd_for_path[path] = wd + self._path_for_wd[wd] = path + return wd + + @staticmethod + def _raise_error() -> None: + """Raises errors for inotify failures.""" + err = ctypes.get_errno() + + if err == errno.ENOSPC: + raise OSError(errno.ENOSPC, "inotify watch limit reached") + + if err == errno.EMFILE: + raise OSError(errno.EMFILE, "inotify instance limit reached") + + if err != errno.EACCES: + raise OSError(err, os.strerror(err)) + + @staticmethod + def _parse_event_buffer(event_buffer: bytes) -> Generator[tuple[int, int, int, bytes]]: + """Parses an event buffer of ``inotify_event`` structs returned by + inotify:: + + struct inotify_event { + __s32 wd; /* watch descriptor */ + __u32 mask; /* watch mask */ + __u32 cookie; /* cookie to synchronize two events */ + __u32 len; /* length (including nulls) of name */ + char name[0]; /* stub for possible name */ + }; + + The ``cookie`` member of this struct is used to pair two related + events, for example, it pairs an IN_MOVED_FROM event with an + IN_MOVED_TO event. + """ + i = 0 + while i + 16 <= len(event_buffer): + wd, mask, cookie, length = struct.unpack_from("iIII", event_buffer, i) + name = event_buffer[i + 16 : i + 16 + length].rstrip(b"\0") + i += 16 + length + yield wd, mask, cookie, name + + +class InotifyEvent: + """Inotify event struct wrapper. + + :param wd: + Watch descriptor + :param mask: + Event mask + :param cookie: + Event cookie + :param name: + Base name of the event source path. + :param src_path: + Full event source path. + """ + + def __init__(self, wd: int, mask: int, cookie: int, name: bytes, src_path: bytes) -> None: + self._wd = wd + self._mask = mask + self._cookie = cookie + self._name = name + self._src_path = src_path + + @property + def src_path(self) -> bytes: + return self._src_path + + @property + def wd(self) -> int: + return self._wd + + @property + def mask(self) -> int: + return self._mask + + @property + def cookie(self) -> int: + return self._cookie + + @property + def name(self) -> bytes: + return self._name + + @property + def is_modify(self) -> bool: + return self._mask & InotifyConstants.IN_MODIFY > 0 + + @property + def is_close_write(self) -> bool: + return self._mask & InotifyConstants.IN_CLOSE_WRITE > 0 + + @property + def is_close_nowrite(self) -> bool: + return self._mask & InotifyConstants.IN_CLOSE_NOWRITE > 0 + + @property + def is_open(self) -> bool: + return self._mask & InotifyConstants.IN_OPEN > 0 + + @property + def is_access(self) -> bool: + return self._mask & InotifyConstants.IN_ACCESS > 0 + + @property + def is_delete(self) -> bool: + return self._mask & InotifyConstants.IN_DELETE > 0 + + @property + def is_delete_self(self) -> bool: + return self._mask & InotifyConstants.IN_DELETE_SELF > 0 + + @property + def is_create(self) -> bool: + return self._mask & InotifyConstants.IN_CREATE > 0 + + @property + def is_moved_from(self) -> bool: + return self._mask & InotifyConstants.IN_MOVED_FROM > 0 + + @property + def is_moved_to(self) -> bool: + return self._mask & InotifyConstants.IN_MOVED_TO > 0 + + @property + def is_move(self) -> bool: + return self._mask & InotifyConstants.IN_MOVE > 0 + + @property + def is_move_self(self) -> bool: + return self._mask & InotifyConstants.IN_MOVE_SELF > 0 + + @property + def is_attrib(self) -> bool: + return self._mask & InotifyConstants.IN_ATTRIB > 0 + + @property + def is_ignored(self) -> bool: + return self._mask & InotifyConstants.IN_IGNORED > 0 + + @property + def is_directory(self) -> bool: + # It looks like the kernel does not provide this information for + # IN_DELETE_SELF and IN_MOVE_SELF. In this case, assume it's a dir. + # See also: https://github.com/seb-m/pyinotify/blob/2c7e8f8/python2/pyinotify.py#L897 + return self.is_delete_self or self.is_move_self or self._mask & InotifyConstants.IN_ISDIR > 0 + + @property + def key(self) -> tuple[bytes, int, int, int, bytes]: + return self._src_path, self._wd, self._mask, self._cookie, self._name + + def __eq__(self, inotify_event: object) -> bool: + if not isinstance(inotify_event, InotifyEvent): + return NotImplemented + return self.key == inotify_event.key + + def __ne__(self, inotify_event: object) -> bool: + if not isinstance(inotify_event, InotifyEvent): + return NotImplemented + return self.key != inotify_event.key + + def __hash__(self) -> int: + return hash(self.key) + + @staticmethod + def _get_mask_string(mask: int) -> str: + masks = [] + for c in dir(InotifyConstants): + if c.startswith("IN_") and c not in {"IN_ALL_EVENTS", "IN_MOVE"}: + c_val = getattr(InotifyConstants, c) + if mask & c_val: + masks.append(c) + return "|".join(masks) + + def __repr__(self) -> str: + return ( + f"<{type(self).__name__}: src_path={self.src_path!r}, wd={self.wd}," + f" mask={self._get_mask_string(self.mask)}, cookie={self.cookie}," + f" name={os.fsdecode(self.name)!r}>" + ) diff --git a/.venv/Lib/site-packages/watchdog/observers/kqueue.py b/.venv/Lib/site-packages/watchdog/observers/kqueue.py new file mode 100644 index 0000000000000000000000000000000000000000..2f9d0c6ffa3c3fda21803bbf38ea853e75a12332 --- /dev/null +++ b/.venv/Lib/site-packages/watchdog/observers/kqueue.py @@ -0,0 +1,655 @@ +""":module: watchdog.observers.kqueue +:synopsis: ``kqueue(2)`` based emitter implementation. +:author: yesudeep@google.com (Yesudeep Mangalapilly) +:author: contact@tiger-222.fr (MickaΓ«l Schoentgen) +:platforms: macOS and BSD with kqueue(2). + +.. WARNING:: kqueue is a very heavyweight way to monitor file systems. + Each kqueue-detected directory modification triggers + a full directory scan. Traversing the entire directory tree + and opening file descriptors for all files will create + performance problems. We need to find a way to re-scan + only those directories which report changes and do a diff + between two sub-DirectorySnapshots perhaps. + +.. ADMONITION:: About OS X performance guidelines + + Quote from the `macOS File System Performance Guidelines`_: + + "When you only want to track changes on a file or directory, be sure to + open it using the ``O_EVTONLY`` flag. This flag prevents the file or + directory from being marked as open or in use. This is important + if you are tracking files on a removable volume and the user tries to + unmount the volume. With this flag in place, the system knows it can + dismiss the volume. If you had opened the files or directories without + this flag, the volume would be marked as busy and would not be + unmounted." + + ``O_EVTONLY`` is defined as ``0x8000`` in the OS X header files. + More information here: http://www.mlsite.net/blog/?p=2312 + +Classes +------- +.. autoclass:: KqueueEmitter + :members: + :show-inheritance: + +Collections and Utility Classes +------------------------------- +.. autoclass:: KeventDescriptor + :members: + :show-inheritance: + +.. autoclass:: KeventDescriptorSet + :members: + :show-inheritance: + +.. _macOS File System Performance Guidelines: + http://developer.apple.com/library/ios/#documentation/Performance/Conceptual/FileSystem/Articles/TrackingChanges.html#//apple_ref/doc/uid/20001993-CJBJFIDD + +""" + + +# The `select` module varies between platforms. +# mypy may complain about missing module attributes depending on which platform it's running on. +# The comment below disables mypy's attribute check. +# mypy: disable-error-code="attr-defined, name-defined" + +from __future__ import annotations + +import contextlib +import errno +import os +import os.path +import select +import threading +from stat import S_ISDIR +from typing import TYPE_CHECKING + +from watchdog.events import ( + EVENT_TYPE_CREATED, + EVENT_TYPE_DELETED, + EVENT_TYPE_MOVED, + DirCreatedEvent, + DirDeletedEvent, + DirModifiedEvent, + DirMovedEvent, + FileCreatedEvent, + FileDeletedEvent, + FileModifiedEvent, + FileMovedEvent, + generate_sub_moved_events, +) +from watchdog.observers.api import DEFAULT_EMITTER_TIMEOUT, DEFAULT_OBSERVER_TIMEOUT, BaseObserver, EventEmitter +from watchdog.utils import platform +from watchdog.utils.dirsnapshot import DirectorySnapshot + +if TYPE_CHECKING: + from collections.abc import Generator + from typing import Callable + + from watchdog.events import FileSystemEvent + from watchdog.observers.api import EventQueue, ObservedWatch + +# Maximum number of events to process. +MAX_EVENTS = 4096 + +# O_EVTONLY value from the header files for OS X only. +O_EVTONLY = 0x8000 + +# Pre-calculated values for the kevent filter, flags, and fflags attributes. +WATCHDOG_OS_OPEN_FLAGS = O_EVTONLY if platform.is_darwin() else os.O_RDONLY | os.O_NONBLOCK +WATCHDOG_KQ_FILTER = select.KQ_FILTER_VNODE +WATCHDOG_KQ_EV_FLAGS = select.KQ_EV_ADD | select.KQ_EV_ENABLE | select.KQ_EV_CLEAR +WATCHDOG_KQ_FFLAGS = ( + select.KQ_NOTE_DELETE + | select.KQ_NOTE_WRITE + | select.KQ_NOTE_EXTEND + | select.KQ_NOTE_ATTRIB + | select.KQ_NOTE_LINK + | select.KQ_NOTE_RENAME + | select.KQ_NOTE_REVOKE +) + + +def absolute_path(path: bytes | str) -> bytes | str: + return os.path.abspath(os.path.normpath(path)) + + +# Flag tests. + + +def is_deleted(kev: select.kevent) -> bool: + """Determines whether the given kevent represents deletion.""" + return kev.fflags & select.KQ_NOTE_DELETE > 0 + + +def is_modified(kev: select.kevent) -> bool: + """Determines whether the given kevent represents modification.""" + fflags = kev.fflags + return (fflags & select.KQ_NOTE_EXTEND > 0) or (fflags & select.KQ_NOTE_WRITE > 0) + + +def is_attrib_modified(kev: select.kevent) -> bool: + """Determines whether the given kevent represents attribute modification.""" + return kev.fflags & select.KQ_NOTE_ATTRIB > 0 + + +def is_renamed(kev: select.kevent) -> bool: + """Determines whether the given kevent represents movement.""" + return kev.fflags & select.KQ_NOTE_RENAME > 0 + + +class KeventDescriptorSet: + """Thread-safe kevent descriptor collection.""" + + def __init__(self) -> None: + self._descriptors: set[KeventDescriptor] = set() + self._descriptor_for_path: dict[bytes | str, KeventDescriptor] = {} + self._descriptor_for_fd: dict[int, KeventDescriptor] = {} + self._kevents: list[select.kevent] = [] + self._lock = threading.Lock() + + @property + def kevents(self) -> list[select.kevent]: + """List of kevents monitored.""" + with self._lock: + return self._kevents + + @property + def paths(self) -> list[bytes | str]: + """List of paths for which kevents have been created.""" + with self._lock: + return list(self._descriptor_for_path.keys()) + + def get_for_fd(self, fd: int) -> KeventDescriptor: + """Given a file descriptor, returns the kevent descriptor object + for it. + + :param fd: + OS file descriptor. + :type fd: + ``int`` + :returns: + A :class:`KeventDescriptor` object. + """ + with self._lock: + return self._descriptor_for_fd[fd] + + def get(self, path: bytes | str) -> KeventDescriptor: + """Obtains a :class:`KeventDescriptor` object for the specified path. + + :param path: + Path for which the descriptor will be obtained. + """ + with self._lock: + path = absolute_path(path) + return self._get(path) + + def __contains__(self, path: bytes | str) -> bool: + """Determines whether a :class:`KeventDescriptor has been registered + for the specified path. + + :param path: + Path for which the descriptor will be obtained. + """ + with self._lock: + path = absolute_path(path) + return self._has_path(path) + + def add(self, path: bytes | str, *, is_directory: bool) -> None: + """Adds a :class:`KeventDescriptor` to the collection for the given + path. + + :param path: + The path for which a :class:`KeventDescriptor` object will be + added. + :param is_directory: + ``True`` if the path refers to a directory; ``False`` otherwise. + :type is_directory: + ``bool`` + """ + with self._lock: + path = absolute_path(path) + if not self._has_path(path): + self._add_descriptor(KeventDescriptor(path, is_directory=is_directory)) + + def remove(self, path: bytes | str) -> None: + """Removes the :class:`KeventDescriptor` object for the given path + if it already exists. + + :param path: + Path for which the :class:`KeventDescriptor` object will be + removed. + """ + with self._lock: + path = absolute_path(path) + if self._has_path(path): + self._remove_descriptor(self._get(path)) + + def clear(self) -> None: + """Clears the collection and closes all open descriptors.""" + with self._lock: + for descriptor in self._descriptors: + descriptor.close() + self._descriptors.clear() + self._descriptor_for_fd.clear() + self._descriptor_for_path.clear() + self._kevents = [] + + # Thread-unsafe methods. Locking is provided at a higher level. + def _get(self, path: bytes | str) -> KeventDescriptor: + """Returns a kevent descriptor for a given path.""" + return self._descriptor_for_path[path] + + def _has_path(self, path: bytes | str) -> bool: + """Determines whether a :class:`KeventDescriptor` for the specified + path exists already in the collection. + """ + return path in self._descriptor_for_path + + def _add_descriptor(self, descriptor: KeventDescriptor) -> None: + """Adds a descriptor to the collection. + + :param descriptor: + An instance of :class:`KeventDescriptor` to be added. + """ + self._descriptors.add(descriptor) + self._kevents.append(descriptor.kevent) + self._descriptor_for_path[descriptor.path] = descriptor + self._descriptor_for_fd[descriptor.fd] = descriptor + + def _remove_descriptor(self, descriptor: KeventDescriptor) -> None: + """Removes a descriptor from the collection. + + :param descriptor: + An instance of :class:`KeventDescriptor` to be removed. + """ + self._descriptors.remove(descriptor) + del self._descriptor_for_fd[descriptor.fd] + del self._descriptor_for_path[descriptor.path] + self._kevents.remove(descriptor.kevent) + descriptor.close() + + +class KeventDescriptor: + """A kevent descriptor convenience data structure to keep together: + + * kevent + * directory status + * path + * file descriptor + + :param path: + Path string for which a kevent descriptor will be created. + :param is_directory: + ``True`` if the path refers to a directory; ``False`` otherwise. + :type is_directory: + ``bool`` + """ + + def __init__(self, path: bytes | str, *, is_directory: bool) -> None: + self._path = absolute_path(path) + self._is_directory = is_directory + self._fd = os.open(path, WATCHDOG_OS_OPEN_FLAGS) + self._kev = select.kevent( + self._fd, + filter=WATCHDOG_KQ_FILTER, + flags=WATCHDOG_KQ_EV_FLAGS, + fflags=WATCHDOG_KQ_FFLAGS, + ) + + @property + def fd(self) -> int: + """OS file descriptor for the kevent descriptor.""" + return self._fd + + @property + def path(self) -> bytes | str: + """The path associated with the kevent descriptor.""" + return self._path + + @property + def kevent(self) -> select.kevent: + """The kevent object associated with the kevent descriptor.""" + return self._kev + + @property + def is_directory(self) -> bool: + """Determines whether the kevent descriptor refers to a directory. + + :returns: + ``True`` or ``False`` + """ + return self._is_directory + + def close(self) -> None: + """Closes the file descriptor associated with a kevent descriptor.""" + with contextlib.suppress(OSError): + os.close(self.fd) + + @property + def key(self) -> tuple[bytes | str, bool]: + return (self.path, self.is_directory) + + def __eq__(self, descriptor: object) -> bool: + if not isinstance(descriptor, KeventDescriptor): + return NotImplemented + return self.key == descriptor.key + + def __ne__(self, descriptor: object) -> bool: + if not isinstance(descriptor, KeventDescriptor): + return NotImplemented + return self.key != descriptor.key + + def __hash__(self) -> int: + return hash(self.key) + + def __repr__(self) -> str: + return f"<{type(self).__name__}: path={self.path!r}, is_directory={self.is_directory}>" + + +class KqueueEmitter(EventEmitter): + """kqueue(2)-based event emitter. + + .. ADMONITION:: About ``kqueue(2)`` behavior and this implementation + + ``kqueue(2)`` monitors file system events only for + open descriptors, which means, this emitter does a lot of + book-keeping behind the scenes to keep track of open + descriptors for every entry in the monitored directory tree. + + This also means the number of maximum open file descriptors + on your system must be increased **manually**. + Usually, issuing a call to ``ulimit`` should suffice:: + + ulimit -n 1024 + + Ensure that you pick a number that is larger than the + number of files you expect to be monitored. + + ``kqueue(2)`` does not provide enough information about the + following things: + + * The destination path of a file or directory that is renamed. + * Creation of a file or directory within a directory; in this + case, ``kqueue(2)`` only indicates a modified event on the + parent directory. + + Therefore, this emitter takes a snapshot of the directory + tree when ``kqueue(2)`` detects a change on the file system + to be able to determine the above information. + + :param event_queue: + The event queue to fill with events. + :param watch: + A watch object representing the directory to monitor. + :type watch: + :class:`watchdog.observers.api.ObservedWatch` + :param timeout: + Read events blocking timeout (in seconds). + :type timeout: + ``float`` + :param event_filter: + Collection of event types to emit, or None for no filtering (default). + :type event_filter: + Iterable[:class:`watchdog.events.FileSystemEvent`] | None + :param stat: stat function. See ``os.stat`` for details. + """ + + def __init__( + self, + event_queue: EventQueue, + watch: ObservedWatch, + *, + timeout: float = DEFAULT_EMITTER_TIMEOUT, + event_filter: list[type[FileSystemEvent]] | None = None, + stat: Callable[[str], os.stat_result] = os.stat, + ) -> None: + super().__init__(event_queue, watch, timeout=timeout, event_filter=event_filter) + + self._kq = select.kqueue() + self._lock = threading.RLock() + + # A collection of KeventDescriptor. + self._descriptors = KeventDescriptorSet() + + def custom_stat(path: str, cls: KqueueEmitter = self) -> os.stat_result: + stat_info = stat(path) + cls._register_kevent(path, is_directory=S_ISDIR(stat_info.st_mode)) + return stat_info + + self._snapshot = DirectorySnapshot(watch.path, recursive=watch.is_recursive, stat=custom_stat) + + def _register_kevent(self, path: bytes | str, *, is_directory: bool) -> None: + """Registers a kevent descriptor for the given path. + + :param path: + Path for which a kevent descriptor will be created. + :param is_directory: + ``True`` if the path refers to a directory; ``False`` otherwise. + :type is_directory: + ``bool`` + """ + try: + self._descriptors.add(path, is_directory=is_directory) + except OSError as e: + if e.errno == errno.ENOENT: + # Probably dealing with a temporary file that was created + # and then quickly deleted before we could open + # a descriptor for it. Therefore, simply queue a sequence + # of created and deleted events for the path. + + # TODO: We could simply ignore these files. + # Locked files cause the python process to die with + # a bus error when we handle temporary files. + # eg. .git/index.lock when running tig operations. + # I don't fully understand this at the moment. + pass + elif e.errno == errno.EOPNOTSUPP: + # Probably dealing with the socket or special file + # mounted through a file system that does not support + # access to it (e.g. NFS). On BSD systems look at + # EOPNOTSUPP in man 2 open. + pass + else: + # All other errors are propagated. + raise + + def _unregister_kevent(self, path: bytes | str) -> None: + """Convenience function to close the kevent descriptor for a + specified kqueue-monitored path. + + :param path: + Path for which the kevent descriptor will be closed. + """ + self._descriptors.remove(path) + + def queue_event(self, event: FileSystemEvent) -> None: + """Handles queueing a single event object. + + :param event: + An instance of :class:`watchdog.events.FileSystemEvent` + or a subclass. + """ + # Handles all the book keeping for queued events. + # We do not need to fire moved/deleted events for all subitems in + # a directory tree here, because this function is called by kqueue + # for all those events anyway. + EventEmitter.queue_event(self, event) + if event.event_type == EVENT_TYPE_CREATED: + self._register_kevent(event.src_path, is_directory=event.is_directory) + elif event.event_type == EVENT_TYPE_MOVED: + self._unregister_kevent(event.src_path) + self._register_kevent(event.dest_path, is_directory=event.is_directory) + elif event.event_type == EVENT_TYPE_DELETED: + self._unregister_kevent(event.src_path) + + def _gen_kqueue_events( + self, kev: select.kevent, ref_snapshot: DirectorySnapshot, new_snapshot: DirectorySnapshot + ) -> Generator[FileSystemEvent]: + """Generate events from the kevent list returned from the call to + :meth:`select.kqueue.control`. + + .. NOTE:: kqueue only tells us about deletions, file modifications, + attribute modifications. The other events, namely, + file creation, directory modification, file rename, + directory rename, directory creation, etc. are + determined by comparing directory snapshots. + """ + descriptor = self._descriptors.get_for_fd(kev.ident) + src_path = descriptor.path + + if is_renamed(kev): + # Kqueue does not specify the destination names for renames + # to, so we have to process these using the a snapshot + # of the directory. + yield from self._gen_renamed_events( + src_path, + ref_snapshot, + new_snapshot, + is_directory=descriptor.is_directory, + ) + elif is_attrib_modified(kev): + if descriptor.is_directory: + yield DirModifiedEvent(src_path) + else: + yield FileModifiedEvent(src_path) + elif is_modified(kev): + if descriptor.is_directory: + if self.watch.is_recursive or self.watch.path == src_path: + # When a directory is modified, it may be due to + # sub-file/directory renames or new file/directory + # creation. We determine all this by comparing + # snapshots later. + yield DirModifiedEvent(src_path) + else: + yield FileModifiedEvent(src_path) + elif is_deleted(kev): + if descriptor.is_directory: + yield DirDeletedEvent(src_path) + else: + yield FileDeletedEvent(src_path) + + def _parent_dir_modified(self, src_path: bytes | str) -> DirModifiedEvent: + """Helper to generate a DirModifiedEvent on the parent of src_path.""" + return DirModifiedEvent(os.path.dirname(src_path)) + + def _gen_renamed_events( + self, + src_path: bytes | str, + ref_snapshot: DirectorySnapshot, + new_snapshot: DirectorySnapshot, + *, + is_directory: bool, + ) -> Generator[FileSystemEvent]: + """Compares information from two directory snapshots (one taken before + the rename operation and another taken right after) to determine the + destination path of the file system object renamed, and yields + the appropriate events to be queued. + """ + try: + f_inode = ref_snapshot.inode(src_path) + except KeyError: + # Probably caught a temporary file/directory that was renamed + # and deleted. Fires a sequence of created and deleted events + # for the path. + if is_directory: + yield DirCreatedEvent(src_path) + yield DirDeletedEvent(src_path) + else: + yield FileCreatedEvent(src_path) + yield FileDeletedEvent(src_path) + # We don't process any further and bail out assuming + # the event represents deletion/creation instead of movement. + return + + dest_path = new_snapshot.path(f_inode) + if dest_path is not None: + dest_path = absolute_path(dest_path) + if is_directory: + yield DirMovedEvent(src_path, dest_path) + else: + yield FileMovedEvent(src_path, dest_path) + yield self._parent_dir_modified(src_path) + yield self._parent_dir_modified(dest_path) + if is_directory and self.watch.is_recursive: + # TODO: Do we need to fire moved events for the items + # inside the directory tree? Does kqueue does this + # all by itself? Check this and then enable this code + # only if it doesn't already. + # A: It doesn't. So I've enabled this block. + yield from generate_sub_moved_events(src_path, dest_path) + else: + # If the new snapshot does not have an inode for the + # old path, we haven't found the new name. Therefore, + # we mark it as deleted and remove unregister the path. + if is_directory: + yield DirDeletedEvent(src_path) + else: + yield FileDeletedEvent(src_path) + yield self._parent_dir_modified(src_path) + + def _read_events(self, timeout: float) -> list[select.kevent]: + """Reads events from a call to the blocking + :meth:`select.kqueue.control()` method. + + :param timeout: + Blocking timeout for reading events. + :type timeout: + ``float`` (seconds) + """ + return self._kq.control(self._descriptors.kevents, MAX_EVENTS, timeout) + + def queue_events(self, timeout: float) -> None: + """Queues events by reading them from a call to the blocking + :meth:`select.kqueue.control()` method. + + :param timeout: + Blocking timeout for reading events. + :type timeout: + ``float`` (seconds) + """ + with self._lock: + try: + event_list = self._read_events(timeout) + # TODO: investigate why order appears to be reversed + event_list.reverse() + + # Take a fresh snapshot of the directory and update the + # saved snapshot. + new_snapshot = DirectorySnapshot(self.watch.path, recursive=self.watch.is_recursive) + ref_snapshot = self._snapshot + self._snapshot = new_snapshot + diff_events = new_snapshot - ref_snapshot + + # Process events + for directory_created in diff_events.dirs_created: + self.queue_event(DirCreatedEvent(directory_created)) + for file_created in diff_events.files_created: + self.queue_event(FileCreatedEvent(file_created)) + for file_modified in diff_events.files_modified: + self.queue_event(FileModifiedEvent(file_modified)) + + for kev in event_list: + for event in self._gen_kqueue_events(kev, ref_snapshot, new_snapshot): + self.queue_event(event) + + except OSError as e: + if e.errno != errno.EBADF: + raise + + def on_thread_stop(self) -> None: + # Clean up. + with self._lock: + self._descriptors.clear() + self._kq.close() + + +class KqueueObserver(BaseObserver): + """Observer thread that schedules watching directories and dispatches + calls to event handlers. + """ + + def __init__(self, *, timeout: float = DEFAULT_OBSERVER_TIMEOUT) -> None: + super().__init__(KqueueEmitter, timeout=timeout) diff --git a/.venv/Lib/site-packages/watchdog/observers/polling.py b/.venv/Lib/site-packages/watchdog/observers/polling.py new file mode 100644 index 0000000000000000000000000000000000000000..5c94e525902e41f52b6362a87172b848e0778f1c --- /dev/null +++ b/.venv/Lib/site-packages/watchdog/observers/polling.py @@ -0,0 +1,142 @@ +""":module: watchdog.observers.polling +:synopsis: Polling emitter implementation. +:author: yesudeep@google.com (Yesudeep Mangalapilly) +:author: contact@tiger-222.fr (MickaΓ«l Schoentgen) + +Classes +------- +.. autoclass:: PollingObserver + :members: + :show-inheritance: + +.. autoclass:: PollingObserverVFS + :members: + :show-inheritance: + :special-members: +""" + +from __future__ import annotations + +import os +import threading +from functools import partial +from typing import TYPE_CHECKING + +from watchdog.events import ( + DirCreatedEvent, + DirDeletedEvent, + DirModifiedEvent, + DirMovedEvent, + FileCreatedEvent, + FileDeletedEvent, + FileModifiedEvent, + FileMovedEvent, +) +from watchdog.observers.api import DEFAULT_EMITTER_TIMEOUT, DEFAULT_OBSERVER_TIMEOUT, BaseObserver, EventEmitter +from watchdog.utils.dirsnapshot import DirectorySnapshot, DirectorySnapshotDiff, EmptyDirectorySnapshot + +if TYPE_CHECKING: + from collections.abc import Iterator + from typing import Callable + + from watchdog.events import FileSystemEvent + from watchdog.observers.api import EventQueue, ObservedWatch + + +class PollingEmitter(EventEmitter): + """Platform-independent emitter that polls a directory to detect file + system changes. + """ + + def __init__( + self, + event_queue: EventQueue, + watch: ObservedWatch, + *, + timeout: float = DEFAULT_EMITTER_TIMEOUT, + event_filter: list[type[FileSystemEvent]] | None = None, + stat: Callable[[str], os.stat_result] = os.stat, + listdir: Callable[[str | None], Iterator[os.DirEntry]] = os.scandir, + ) -> None: + super().__init__(event_queue, watch, timeout=timeout, event_filter=event_filter) + self._snapshot: DirectorySnapshot = EmptyDirectorySnapshot() + self._lock = threading.Lock() + self._take_snapshot: Callable[[], DirectorySnapshot] = lambda: DirectorySnapshot( + self.watch.path, + recursive=self.watch.is_recursive, + stat=stat, + listdir=listdir, + ) + + def on_thread_start(self) -> None: + self._snapshot = self._take_snapshot() + + def queue_events(self, timeout: float) -> None: + # We don't want to hit the disk continuously. + # timeout behaves like an interval for polling emitters. + if self.stopped_event.wait(timeout): + return + + with self._lock: + if not self.should_keep_running(): + return + + # Get event diff between fresh snapshot and previous snapshot. + # Update snapshot. + try: + new_snapshot = self._take_snapshot() + except OSError: + self.queue_event(DirDeletedEvent(self.watch.path)) + self.stop() + return + + events = DirectorySnapshotDiff(self._snapshot, new_snapshot) + self._snapshot = new_snapshot + + # Files. + for src_path in events.files_deleted: + self.queue_event(FileDeletedEvent(src_path)) + for src_path in events.files_modified: + self.queue_event(FileModifiedEvent(src_path)) + for src_path in events.files_created: + self.queue_event(FileCreatedEvent(src_path)) + for src_path, dest_path in events.files_moved: + self.queue_event(FileMovedEvent(src_path, dest_path)) + + # Directories. + for src_path in events.dirs_deleted: + self.queue_event(DirDeletedEvent(src_path)) + for src_path in events.dirs_modified: + self.queue_event(DirModifiedEvent(src_path)) + for src_path in events.dirs_created: + self.queue_event(DirCreatedEvent(src_path)) + for src_path, dest_path in events.dirs_moved: + self.queue_event(DirMovedEvent(src_path, dest_path)) + + +class PollingObserver(BaseObserver): + """Platform-independent observer that polls a directory to detect file + system changes. + """ + + def __init__(self, *, timeout: float = DEFAULT_OBSERVER_TIMEOUT) -> None: + super().__init__(PollingEmitter, timeout=timeout) + + +class PollingObserverVFS(BaseObserver): + """File system independent observer that polls a directory to detect changes.""" + + def __init__( + self, + stat: Callable[[str], os.stat_result], + listdir: Callable[[str | None], Iterator[os.DirEntry]], + *, + polling_interval: int = 1, + ) -> None: + """:param stat: stat function. See ``os.stat`` for details. + :param listdir: listdir function. See ``os.scandir`` for details. + :type polling_interval: int + :param polling_interval: interval in seconds between polling the file system. + """ + emitter_cls = partial(PollingEmitter, stat=stat, listdir=listdir) + super().__init__(emitter_cls, timeout=polling_interval) # type: ignore[arg-type] diff --git a/.venv/Lib/site-packages/watchdog/observers/read_directory_changes.py b/.venv/Lib/site-packages/watchdog/observers/read_directory_changes.py new file mode 100644 index 0000000000000000000000000000000000000000..4faa9450b29c4626153cb48fd6fd120dbd9a4ccc --- /dev/null +++ b/.venv/Lib/site-packages/watchdog/observers/read_directory_changes.py @@ -0,0 +1,109 @@ +from __future__ import annotations + +import os.path +import platform +import threading +from typing import TYPE_CHECKING + +from watchdog.events import ( + DirCreatedEvent, + DirDeletedEvent, + DirModifiedEvent, + DirMovedEvent, + FileCreatedEvent, + FileDeletedEvent, + FileModifiedEvent, + FileMovedEvent, + generate_sub_created_events, + generate_sub_moved_events, +) +from watchdog.observers.api import DEFAULT_EMITTER_TIMEOUT, DEFAULT_OBSERVER_TIMEOUT, BaseObserver, EventEmitter +from watchdog.observers.winapi import close_directory_handle, get_directory_handle, read_events + +if TYPE_CHECKING: + from ctypes.wintypes import HANDLE + + from watchdog.events import FileSystemEvent + from watchdog.observers.api import EventQueue, ObservedWatch + from watchdog.observers.winapi import WinAPINativeEvent + + +class WindowsApiEmitter(EventEmitter): + """Windows API-based emitter that uses ReadDirectoryChangesW + to detect file system changes for a watch. + """ + + def __init__( + self, + event_queue: EventQueue, + watch: ObservedWatch, + *, + timeout: float = DEFAULT_EMITTER_TIMEOUT, + event_filter: list[type[FileSystemEvent]] | None = None, + ) -> None: + super().__init__(event_queue, watch, timeout=timeout, event_filter=event_filter) + self._lock = threading.Lock() + self._whandle: HANDLE | None = None + + def on_thread_start(self) -> None: + self._whandle = get_directory_handle(self.watch.path) + + if platform.python_implementation() == "PyPy": + + def start(self) -> None: + """PyPy needs some time before receiving events, see #792.""" + from time import sleep + + super().start() + sleep(0.01) + + def on_thread_stop(self) -> None: + if self._whandle: + close_directory_handle(self._whandle) + + def _read_events(self) -> list[WinAPINativeEvent]: + if not self._whandle: + return [] + return read_events(self._whandle, self.watch.path, recursive=self.watch.is_recursive) + + def queue_events(self, timeout: float) -> None: + winapi_events = self._read_events() + with self._lock: + last_renamed_src_path = "" + for winapi_event in winapi_events: + src_path = os.path.join(self.watch.path, winapi_event.src_path) + + if winapi_event.is_renamed_old: + last_renamed_src_path = src_path + elif winapi_event.is_renamed_new: + dest_path = src_path + src_path = last_renamed_src_path + if os.path.isdir(dest_path): + self.queue_event(DirMovedEvent(src_path, dest_path)) + if self.watch.is_recursive: + for sub_moved_event in generate_sub_moved_events(src_path, dest_path): + self.queue_event(sub_moved_event) + else: + self.queue_event(FileMovedEvent(src_path, dest_path)) + elif winapi_event.is_modified: + self.queue_event((DirModifiedEvent if os.path.isdir(src_path) else FileModifiedEvent)(src_path)) + elif winapi_event.is_added: + isdir = os.path.isdir(src_path) + self.queue_event((DirCreatedEvent if isdir else FileCreatedEvent)(src_path)) + if isdir and self.watch.is_recursive: + for sub_created_event in generate_sub_created_events(src_path): + self.queue_event(sub_created_event) + elif winapi_event.is_removed: + self.queue_event(FileDeletedEvent(src_path)) + elif winapi_event.is_removed_self: + self.queue_event(DirDeletedEvent(self.watch.path)) + self.stop() + + +class WindowsApiObserver(BaseObserver): + """Observer thread that schedules watching directories and dispatches + calls to event handlers. + """ + + def __init__(self, *, timeout: float = DEFAULT_OBSERVER_TIMEOUT) -> None: + super().__init__(WindowsApiEmitter, timeout=timeout) diff --git a/.venv/Lib/site-packages/watchdog/observers/winapi.py b/.venv/Lib/site-packages/watchdog/observers/winapi.py new file mode 100644 index 0000000000000000000000000000000000000000..1247e1f874ee9c6e3784977d9f8c47f63e3e6b4a --- /dev/null +++ b/.venv/Lib/site-packages/watchdog/observers/winapi.py @@ -0,0 +1,382 @@ +""":module: watchdog.observers.winapi +:synopsis: Windows API-Python interface (removes dependency on ``pywin32``). +:author: theller@ctypes.org (Thomas Heller) +:author: will@willmcgugan.com (Will McGugan) +:author: ryan@rfk.id.au (Ryan Kelly) +:author: yesudeep@gmail.com (Yesudeep Mangalapilly) +:author: thomas.amland@gmail.com (Thomas Amland) +:author: contact@tiger-222.fr (MickaΓ«l Schoentgen) +:platforms: windows +""" + +from __future__ import annotations + +import contextlib +import ctypes +from ctypes.wintypes import BOOL, DWORD, HANDLE, LPCWSTR, LPVOID, LPWSTR +from dataclasses import dataclass +from functools import reduce +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from typing import Any + +# Invalid handle value. +INVALID_HANDLE_VALUE = ctypes.c_void_p(-1).value + +# File notification constants. +FILE_NOTIFY_CHANGE_FILE_NAME = 0x01 +FILE_NOTIFY_CHANGE_DIR_NAME = 0x02 +FILE_NOTIFY_CHANGE_ATTRIBUTES = 0x04 +FILE_NOTIFY_CHANGE_SIZE = 0x08 +FILE_NOTIFY_CHANGE_LAST_WRITE = 0x010 +FILE_NOTIFY_CHANGE_LAST_ACCESS = 0x020 +FILE_NOTIFY_CHANGE_CREATION = 0x040 +FILE_NOTIFY_CHANGE_SECURITY = 0x0100 + +FILE_FLAG_BACKUP_SEMANTICS = 0x02000000 +FILE_FLAG_OVERLAPPED = 0x40000000 +FILE_LIST_DIRECTORY = 1 +FILE_SHARE_READ = 0x01 +FILE_SHARE_WRITE = 0x02 +FILE_SHARE_DELETE = 0x04 +OPEN_EXISTING = 3 + +VOLUME_NAME_NT = 0x02 + +# File action constants. +FILE_ACTION_CREATED = 1 +FILE_ACTION_DELETED = 2 +FILE_ACTION_MODIFIED = 3 +FILE_ACTION_RENAMED_OLD_NAME = 4 +FILE_ACTION_RENAMED_NEW_NAME = 5 +FILE_ACTION_DELETED_SELF = 0xFFFE +FILE_ACTION_OVERFLOW = 0xFFFF + +# Aliases +FILE_ACTION_ADDED = FILE_ACTION_CREATED +FILE_ACTION_REMOVED = FILE_ACTION_DELETED +FILE_ACTION_REMOVED_SELF = FILE_ACTION_DELETED_SELF + +THREAD_TERMINATE = 0x0001 + +# IO waiting constants. +WAIT_ABANDONED = 0x00000080 +WAIT_IO_COMPLETION = 0x000000C0 +WAIT_OBJECT_0 = 0x00000000 +WAIT_TIMEOUT = 0x00000102 + +# Error codes +ERROR_OPERATION_ABORTED = 995 + + +class OVERLAPPED(ctypes.Structure): + _fields_ = ( + ("Internal", LPVOID), + ("InternalHigh", LPVOID), + ("Offset", DWORD), + ("OffsetHigh", DWORD), + ("Pointer", LPVOID), + ("hEvent", HANDLE), + ) + + +def _errcheck_bool(value: Any | None, func: Any, args: Any) -> Any: + if not value: + raise ctypes.WinError() # type: ignore[attr-defined] + return args + + +def _errcheck_handle(value: Any | None, func: Any, args: Any) -> Any: + if not value: + raise ctypes.WinError() # type: ignore[attr-defined] + if value == INVALID_HANDLE_VALUE: + raise ctypes.WinError() # type: ignore[attr-defined] + return args + + +def _errcheck_dword(value: Any | None, func: Any, args: Any) -> Any: + if value == 0xFFFFFFFF: + raise ctypes.WinError() # type: ignore[attr-defined] + return args + + +kernel32 = ctypes.WinDLL("kernel32") # type: ignore[attr-defined] + +ReadDirectoryChangesW = kernel32.ReadDirectoryChangesW +ReadDirectoryChangesW.restype = BOOL +ReadDirectoryChangesW.errcheck = _errcheck_bool +ReadDirectoryChangesW.argtypes = ( + HANDLE, # hDirectory + LPVOID, # lpBuffer + DWORD, # nBufferLength + BOOL, # bWatchSubtree + DWORD, # dwNotifyFilter + ctypes.POINTER(DWORD), # lpBytesReturned + ctypes.POINTER(OVERLAPPED), # lpOverlapped + LPVOID, # FileIOCompletionRoutine # lpCompletionRoutine +) + +CreateFileW = kernel32.CreateFileW +CreateFileW.restype = HANDLE +CreateFileW.errcheck = _errcheck_handle +CreateFileW.argtypes = ( + LPCWSTR, # lpFileName + DWORD, # dwDesiredAccess + DWORD, # dwShareMode + LPVOID, # lpSecurityAttributes + DWORD, # dwCreationDisposition + DWORD, # dwFlagsAndAttributes + HANDLE, # hTemplateFile +) + +CloseHandle = kernel32.CloseHandle +CloseHandle.restype = BOOL +CloseHandle.argtypes = (HANDLE,) # hObject + +CancelIoEx = kernel32.CancelIoEx +CancelIoEx.restype = BOOL +CancelIoEx.errcheck = _errcheck_bool +CancelIoEx.argtypes = ( + HANDLE, # hObject + ctypes.POINTER(OVERLAPPED), # lpOverlapped +) + +CreateEvent = kernel32.CreateEventW +CreateEvent.restype = HANDLE +CreateEvent.errcheck = _errcheck_handle +CreateEvent.argtypes = ( + LPVOID, # lpEventAttributes + BOOL, # bManualReset + BOOL, # bInitialState + LPCWSTR, # lpName +) + +SetEvent = kernel32.SetEvent +SetEvent.restype = BOOL +SetEvent.errcheck = _errcheck_bool +SetEvent.argtypes = (HANDLE,) # hEvent + +WaitForSingleObjectEx = kernel32.WaitForSingleObjectEx +WaitForSingleObjectEx.restype = DWORD +WaitForSingleObjectEx.errcheck = _errcheck_dword +WaitForSingleObjectEx.argtypes = ( + HANDLE, # hObject + DWORD, # dwMilliseconds + BOOL, # bAlertable +) + +CreateIoCompletionPort = kernel32.CreateIoCompletionPort +CreateIoCompletionPort.restype = HANDLE +CreateIoCompletionPort.errcheck = _errcheck_handle +CreateIoCompletionPort.argtypes = ( + HANDLE, # FileHandle + HANDLE, # ExistingCompletionPort + LPVOID, # CompletionKey + DWORD, # NumberOfConcurrentThreads +) + +GetQueuedCompletionStatus = kernel32.GetQueuedCompletionStatus +GetQueuedCompletionStatus.restype = BOOL +GetQueuedCompletionStatus.errcheck = _errcheck_bool +GetQueuedCompletionStatus.argtypes = ( + HANDLE, # CompletionPort + LPVOID, # lpNumberOfBytesTransferred + LPVOID, # lpCompletionKey + ctypes.POINTER(OVERLAPPED), # lpOverlapped + DWORD, # dwMilliseconds +) + +PostQueuedCompletionStatus = kernel32.PostQueuedCompletionStatus +PostQueuedCompletionStatus.restype = BOOL +PostQueuedCompletionStatus.errcheck = _errcheck_bool +PostQueuedCompletionStatus.argtypes = ( + HANDLE, # CompletionPort + DWORD, # lpNumberOfBytesTransferred + DWORD, # lpCompletionKey + ctypes.POINTER(OVERLAPPED), # lpOverlapped +) + + +GetFinalPathNameByHandleW = kernel32.GetFinalPathNameByHandleW +GetFinalPathNameByHandleW.restype = DWORD +GetFinalPathNameByHandleW.errcheck = _errcheck_dword +GetFinalPathNameByHandleW.argtypes = ( + HANDLE, # hFile + LPWSTR, # lpszFilePath + DWORD, # cchFilePath + DWORD, # DWORD +) + + +class FileNotifyInformation(ctypes.Structure): + _fields_ = ( + ("NextEntryOffset", DWORD), + ("Action", DWORD), + ("FileNameLength", DWORD), + ("FileName", (ctypes.c_char * 1)), + ) + + +LPFNI = ctypes.POINTER(FileNotifyInformation) + + +# We don't need to recalculate these flags every time a call is made to +# the win32 API functions. +WATCHDOG_FILE_FLAGS = FILE_FLAG_BACKUP_SEMANTICS +WATCHDOG_FILE_SHARE_FLAGS = reduce( + lambda x, y: x | y, + [ + FILE_SHARE_READ, + FILE_SHARE_WRITE, + FILE_SHARE_DELETE, + ], +) +WATCHDOG_FILE_NOTIFY_FLAGS = reduce( + lambda x, y: x | y, + [ + FILE_NOTIFY_CHANGE_FILE_NAME, + FILE_NOTIFY_CHANGE_DIR_NAME, + FILE_NOTIFY_CHANGE_ATTRIBUTES, + FILE_NOTIFY_CHANGE_SIZE, + FILE_NOTIFY_CHANGE_LAST_WRITE, + FILE_NOTIFY_CHANGE_SECURITY, + FILE_NOTIFY_CHANGE_LAST_ACCESS, + FILE_NOTIFY_CHANGE_CREATION, + ], +) + +# ReadDirectoryChangesW buffer length. +# To handle cases with lot of changes, this seems the highest safest value we can use. +# Note: it will fail with ERROR_INVALID_PARAMETER when it is greater than 64 KB and +# the application is monitoring a directory over the network. +# This is due to a packet size limitation with the underlying file sharing protocols. +# https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-readdirectorychangesw#remarks +BUFFER_SIZE = 64000 + +# Buffer length for path-related stuff. +# Introduced to keep the old behavior when we bumped BUFFER_SIZE from 2048 to 64000 in v1.0.0. +PATH_BUFFER_SIZE = 2048 + + +def _parse_event_buffer(read_buffer: bytes, n_bytes: int) -> list[tuple[int, str]]: + results = [] + while n_bytes > 0: + fni = ctypes.cast(read_buffer, LPFNI)[0] # type: ignore[arg-type] + ptr = ctypes.addressof(fni) + FileNotifyInformation.FileName.offset + filename = ctypes.string_at(ptr, fni.FileNameLength) + results.append((fni.Action, filename.decode("utf-16"))) + num_to_skip = fni.NextEntryOffset + if num_to_skip <= 0: + break + read_buffer = read_buffer[num_to_skip:] + n_bytes -= num_to_skip # num_to_skip is long. n_bytes should be long too. + return results + + +def _is_observed_path_deleted(handle: HANDLE, path: str) -> bool: + # Comparison of observed path and actual path, returned by + # GetFinalPathNameByHandleW. If directory moved to the trash bin, or + # deleted, actual path will not be equal to observed path. + buff = ctypes.create_unicode_buffer(PATH_BUFFER_SIZE) + GetFinalPathNameByHandleW(handle, buff, PATH_BUFFER_SIZE, VOLUME_NAME_NT) + return buff.value != path + + +def _generate_observed_path_deleted_event() -> tuple[bytes, int]: + # Create synthetic event for notify that observed directory is deleted + path = ctypes.create_unicode_buffer(".") + event = FileNotifyInformation(0, FILE_ACTION_DELETED_SELF, len(path), path.value.encode("utf-8")) + event_size = ctypes.sizeof(event) + buff = ctypes.create_string_buffer(PATH_BUFFER_SIZE) + ctypes.memmove(buff, ctypes.addressof(event), event_size) + return buff.raw, event_size + + +def get_directory_handle(path: str) -> HANDLE: + """Returns a Windows handle to the specified directory path.""" + return CreateFileW( + path, + FILE_LIST_DIRECTORY, + WATCHDOG_FILE_SHARE_FLAGS, + None, + OPEN_EXISTING, + WATCHDOG_FILE_FLAGS, + None, + ) + + +def close_directory_handle(handle: HANDLE) -> None: + try: + CancelIoEx(handle, None) # force ReadDirectoryChangesW to return + CloseHandle(handle) + except OSError: + with contextlib.suppress(Exception): + CloseHandle(handle) + + +def read_directory_changes(handle: HANDLE, path: str, *, recursive: bool) -> tuple[bytes, int]: + """Read changes to the directory using the specified directory handle. + + https://timgolden.me.uk/pywin32-docs/win32file__ReadDirectoryChangesW_meth.html + """ + event_buffer = ctypes.create_string_buffer(BUFFER_SIZE) + nbytes = DWORD() + try: + ReadDirectoryChangesW( + handle, + ctypes.byref(event_buffer), + len(event_buffer), + recursive, + WATCHDOG_FILE_NOTIFY_FLAGS, + ctypes.byref(nbytes), + None, + None, + ) + except OSError as e: + if e.winerror == ERROR_OPERATION_ABORTED: # type: ignore[attr-defined] + return event_buffer.raw, 0 + + # Handle the case when the root path is deleted + if _is_observed_path_deleted(handle, path): + return _generate_observed_path_deleted_event() + + raise + + return event_buffer.raw, int(nbytes.value) + + +@dataclass(unsafe_hash=True) +class WinAPINativeEvent: + action: int + src_path: str + + @property + def is_added(self) -> bool: + return self.action == FILE_ACTION_CREATED + + @property + def is_removed(self) -> bool: + return self.action == FILE_ACTION_REMOVED + + @property + def is_modified(self) -> bool: + return self.action == FILE_ACTION_MODIFIED + + @property + def is_renamed_old(self) -> bool: + return self.action == FILE_ACTION_RENAMED_OLD_NAME + + @property + def is_renamed_new(self) -> bool: + return self.action == FILE_ACTION_RENAMED_NEW_NAME + + @property + def is_removed_self(self) -> bool: + return self.action == FILE_ACTION_REMOVED_SELF + + +def read_events(handle: HANDLE, path: str, *, recursive: bool) -> list[WinAPINativeEvent]: + buf, nbytes = read_directory_changes(handle, path, recursive=recursive) + events = _parse_event_buffer(buf, nbytes) + return [WinAPINativeEvent(action, src_path) for action, src_path in events] diff --git a/.venv/Lib/site-packages/watchdog/py.typed b/.venv/Lib/site-packages/watchdog/py.typed new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/.venv/Lib/site-packages/watchdog/tricks/__init__.py b/.venv/Lib/site-packages/watchdog/tricks/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..b993b6d2c17dccf08d2e3e6a8c60bd7b8bf6e324 --- /dev/null +++ b/.venv/Lib/site-packages/watchdog/tricks/__init__.py @@ -0,0 +1,293 @@ +""":module: watchdog.tricks +:synopsis: Utility event handlers. +:author: yesudeep@google.com (Yesudeep Mangalapilly) +:author: contact@tiger-222.fr (MickaΓ«l Schoentgen) + +Classes +------- +.. autoclass:: Trick + :members: + :show-inheritance: + +.. autoclass:: LoggerTrick + :members: + :show-inheritance: + +.. autoclass:: ShellCommandTrick + :members: + :show-inheritance: + +.. autoclass:: AutoRestartTrick + :members: + :show-inheritance: + +""" + +from __future__ import annotations + +import contextlib +import functools +import logging +import os +import signal +import subprocess +import threading +import time + +from watchdog.events import EVENT_TYPE_CLOSED_NO_WRITE, EVENT_TYPE_OPENED, FileSystemEvent, PatternMatchingEventHandler +from watchdog.utils import echo, platform +from watchdog.utils.event_debouncer import EventDebouncer +from watchdog.utils.process_watcher import ProcessWatcher + +logger = logging.getLogger(__name__) +echo_events = functools.partial(echo.echo, write=lambda msg: logger.info(msg)) + + +class Trick(PatternMatchingEventHandler): + """Your tricks should subclass this class.""" + + def __repr__(self) -> str: + return f"<{type(self).__name__}>" + + @classmethod + def generate_yaml(cls) -> str: + return f"""- {cls.__module__}.{cls.__name__}: + args: + - argument1 + - argument2 + kwargs: + patterns: + - "*.py" + - "*.js" + ignore_patterns: + - "version.py" + ignore_directories: false +""" + + +class LoggerTrick(Trick): + """A simple trick that does only logs events.""" + + @echo_events + def on_any_event(self, event: FileSystemEvent) -> None: + pass + + +class ShellCommandTrick(Trick): + """Executes shell commands in response to matched events.""" + + def __init__( + self, + shell_command: str, + *, + patterns: list[str] | None = None, + ignore_patterns: list[str] | None = None, + ignore_directories: bool = False, + wait_for_process: bool = False, + drop_during_process: bool = False, + ): + super().__init__( + patterns=patterns, + ignore_patterns=ignore_patterns, + ignore_directories=ignore_directories, + ) + self.shell_command = shell_command + self.wait_for_process = wait_for_process + self.drop_during_process = drop_during_process + + self.process: subprocess.Popen[bytes] | None = None + self._process_watchers: set[ProcessWatcher] = set() + + def on_any_event(self, event: FileSystemEvent) -> None: + if event.event_type in {EVENT_TYPE_OPENED, EVENT_TYPE_CLOSED_NO_WRITE}: + # FIXME: see issue #949, and find a way to better handle that scenario + return + + from string import Template + + if self.drop_during_process and self.is_process_running(): + return + + object_type = "directory" if event.is_directory else "file" + context = { + "watch_src_path": event.src_path, + "watch_dest_path": "", + "watch_event_type": event.event_type, + "watch_object": object_type, + } + + if self.shell_command is None: + if hasattr(event, "dest_path"): + context["dest_path"] = event.dest_path + command = 'echo "${watch_event_type} ${watch_object} from ${watch_src_path} to ${watch_dest_path}"' + else: + command = 'echo "${watch_event_type} ${watch_object} ${watch_src_path}"' + else: + if hasattr(event, "dest_path"): + context["watch_dest_path"] = event.dest_path + command = self.shell_command + + command = Template(command).safe_substitute(**context) + self.process = subprocess.Popen(command, shell=True) + if self.wait_for_process: + self.process.wait() + else: + process_watcher = ProcessWatcher(self.process, None) + self._process_watchers.add(process_watcher) + process_watcher.process_termination_callback = functools.partial( + self._process_watchers.discard, + process_watcher, + ) + process_watcher.start() + + def is_process_running(self) -> bool: + return bool(self._process_watchers or (self.process is not None and self.process.poll() is None)) + + +class AutoRestartTrick(Trick): + """Starts a long-running subprocess and restarts it on matched events. + + The command parameter is a list of command arguments, such as + `['bin/myserver', '-c', 'etc/myconfig.ini']`. + + Call `start()` after creating the Trick. Call `stop()` when stopping + the process. + """ + + def __init__( + self, + command: list[str], + *, + patterns: list[str] | None = None, + ignore_patterns: list[str] | None = None, + ignore_directories: bool = False, + stop_signal: signal.Signals | int = signal.SIGINT, + kill_after: int = 10, + debounce_interval_seconds: int = 0, + restart_on_command_exit: bool = True, + ): + if kill_after < 0: + error = "kill_after must be non-negative." + raise ValueError(error) + if debounce_interval_seconds < 0: + error = "debounce_interval_seconds must be non-negative." + raise ValueError(error) + + super().__init__( + patterns=patterns, + ignore_patterns=ignore_patterns, + ignore_directories=ignore_directories, + ) + + self.command = command + self.stop_signal = stop_signal.value if isinstance(stop_signal, signal.Signals) else stop_signal + self.kill_after = kill_after + self.debounce_interval_seconds = debounce_interval_seconds + self.restart_on_command_exit = restart_on_command_exit + + self.process: subprocess.Popen[bytes] | None = None + self.process_watcher: ProcessWatcher | None = None + self.event_debouncer: EventDebouncer | None = None + self.restart_count = 0 + + self._is_process_stopping = False + self._is_trick_stopping = False + self._stopping_lock = threading.RLock() + + def start(self) -> None: + if self.debounce_interval_seconds: + self.event_debouncer = EventDebouncer( + debounce_interval_seconds=self.debounce_interval_seconds, + events_callback=lambda events: self._restart_process(), + ) + self.event_debouncer.start() + self._start_process() + + def stop(self) -> None: + # Ensure the body of the function is only run once. + with self._stopping_lock: + if self._is_trick_stopping: + return + self._is_trick_stopping = True + + process_watcher = self.process_watcher + if self.event_debouncer is not None: + self.event_debouncer.stop() + self._stop_process() + + # Don't leak threads: Wait for background threads to stop. + if self.event_debouncer is not None: + self.event_debouncer.join() + if process_watcher is not None: + process_watcher.join() + + def _start_process(self) -> None: + if self._is_trick_stopping: + return + + # windows doesn't have setsid + self.process = subprocess.Popen(self.command, preexec_fn=getattr(os, "setsid", None)) + if self.restart_on_command_exit: + self.process_watcher = ProcessWatcher(self.process, self._restart_process) + self.process_watcher.start() + + def _stop_process(self) -> None: + # Ensure the body of the function is not run in parallel in different threads. + with self._stopping_lock: + if self._is_process_stopping: + return + self._is_process_stopping = True + + try: + if self.process_watcher is not None: + self.process_watcher.stop() + self.process_watcher = None + + if self.process is not None: + try: + kill_process(self.process.pid, self.stop_signal) + except OSError: + # Process is already gone + pass + else: + kill_time = time.time() + self.kill_after + while time.time() < kill_time: + if self.process.poll() is not None: + break + time.sleep(0.25) + else: + # Process is already gone + with contextlib.suppress(OSError): + kill_process(self.process.pid, 9) + self.process = None + finally: + self._is_process_stopping = False + + @echo_events + def on_any_event(self, event: FileSystemEvent) -> None: + if event.event_type in {EVENT_TYPE_OPENED, EVENT_TYPE_CLOSED_NO_WRITE}: + # FIXME: see issue #949, and find a way to better handle that scenario + return + + if self.event_debouncer is not None: + self.event_debouncer.handle_event(event) + else: + self._restart_process() + + def _restart_process(self) -> None: + if self._is_trick_stopping: + return + self._stop_process() + self._start_process() + self.restart_count += 1 + + +if platform.is_windows(): + + def kill_process(pid: int, stop_signal: int) -> None: + os.kill(pid, stop_signal) + +else: + + def kill_process(pid: int, stop_signal: int) -> None: + os.killpg(os.getpgid(pid), stop_signal) diff --git a/.venv/Lib/site-packages/watchdog/utils/__init__.py b/.venv/Lib/site-packages/watchdog/utils/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..637d98885c5267896033ba4aed1d5d45f774c92b --- /dev/null +++ b/.venv/Lib/site-packages/watchdog/utils/__init__.py @@ -0,0 +1,122 @@ +""":module: watchdog.utils +:synopsis: Utility classes and functions. +:author: yesudeep@google.com (Yesudeep Mangalapilly) +:author: contact@tiger-222.fr (MickaΓ«l Schoentgen) + +Classes +------- +.. autoclass:: BaseThread + :members: + :show-inheritance: + :inherited-members: + +""" + +from __future__ import annotations + +import sys +import threading +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from types import ModuleType + + from watchdog.tricks import Trick + + +class UnsupportedLibcError(Exception): + pass + + +class WatchdogShutdownError(Exception): + """Semantic exception used to signal an external shutdown event.""" + + +class BaseThread(threading.Thread): + """Convenience class for creating stoppable threads.""" + + def __init__(self) -> None: + threading.Thread.__init__(self) + if hasattr(self, "daemon"): + self.daemon = True + else: + self.setDaemon(True) + self._stopped_event = threading.Event() + + @property + def stopped_event(self) -> threading.Event: + return self._stopped_event + + def should_keep_running(self) -> bool: + """Determines whether the thread should continue running.""" + return not self._stopped_event.is_set() + + def on_thread_stop(self) -> None: + """Override this method instead of :meth:`stop()`. + :meth:`stop()` calls this method. + + This method is called immediately after the thread is signaled to stop. + """ + + def stop(self) -> None: + """Signals the thread to stop.""" + self._stopped_event.set() + self.on_thread_stop() + + def on_thread_start(self) -> None: + """Override this method instead of :meth:`start()`. :meth:`start()` + calls this method. + + This method is called right before this thread is started and this + object's run() method is invoked. + """ + + def start(self) -> None: + self.on_thread_start() + threading.Thread.start(self) + + +def load_module(module_name: str) -> ModuleType: + """Imports a module given its name and returns a handle to it.""" + try: + __import__(module_name) + except ImportError as e: + error = f"No module named {module_name}" + raise ImportError(error) from e + return sys.modules[module_name] + + +def load_class(dotted_path: str) -> type[Trick]: + """Loads and returns a class definition provided a dotted path + specification the last part of the dotted path is the class name + and there is at least one module name preceding the class name. + + Notes + ----- + You will need to ensure that the module you are trying to load + exists in the Python path. + + Examples + -------- + - module.name.ClassName # Provided module.name is in the Python path. + - module.ClassName # Provided module is in the Python path. + + What won't work: + - ClassName + - modle.name.ClassName # Typo in module name. + - module.name.ClasNam # Typo in classname. + + """ + dotted_path_split = dotted_path.split(".") + if len(dotted_path_split) <= 1: + error = f"Dotted module path {dotted_path} must contain a module name and a classname" + raise ValueError(error) + klass_name = dotted_path_split[-1] + module_name = ".".join(dotted_path_split[:-1]) + + module = load_module(module_name) + if hasattr(module, klass_name): + return getattr(module, klass_name) + + error = f"Module {module_name} does not have class attribute {klass_name}" + raise AttributeError(error) diff --git a/.venv/Lib/site-packages/watchdog/utils/bricks.py b/.venv/Lib/site-packages/watchdog/utils/bricks.py new file mode 100644 index 0000000000000000000000000000000000000000..6aca8e425fe83c688bc2e9020ebf3a594598d09c --- /dev/null +++ b/.venv/Lib/site-packages/watchdog/utils/bricks.py @@ -0,0 +1,90 @@ +"""Utility collections or "bricks". + +:module: watchdog.utils.bricks +:author: yesudeep@google.com (Yesudeep Mangalapilly) +:author: lalinsky@gmail.com (LukΓ‘Ε‘ LalinskΓ½) +:author: python@rcn.com (Raymond Hettinger) +:author: contact@tiger-222.fr (MickaΓ«l Schoentgen) + +Classes +======= +.. autoclass:: OrderedSetQueue + :members: + :show-inheritance: + :inherited-members: + +.. autoclass:: OrderedSet + +""" + +from __future__ import annotations + +import queue +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from typing import Any + + +class SkipRepeatsQueue(queue.Queue): + """Thread-safe implementation of an special queue where a + put of the last-item put'd will be dropped. + + The implementation leverages locking already implemented in the base class + redefining only the primitives. + + Queued items must be immutable and hashable so that they can be used + as dictionary keys. You must implement **only read-only properties** and + the :meth:`Item.__hash__()`, :meth:`Item.__eq__()`, and + :meth:`Item.__ne__()` methods for items to be hashable. + + An example implementation follows:: + + class Item: + def __init__(self, a, b): + self._a = a + self._b = b + + @property + def a(self): + return self._a + + @property + def b(self): + return self._b + + def _key(self): + return (self._a, self._b) + + def __eq__(self, item): + return self._key() == item._key() + + def __ne__(self, item): + return self._key() != item._key() + + def __hash__(self): + return hash(self._key()) + + based on the OrderedSetQueue below + """ + + def _init(self, maxsize: int) -> None: + super()._init(maxsize) + self._last_item = None + + def put(self, item: Any, block: bool = True, timeout: float | None = None) -> None: # noqa: FBT001,FBT002 + """This method will be used by `eventlet`, when enabled, so we cannot use force proper keyword-only + arguments nor touch the signature. Also, the `timeout` argument will be ignored in that case. + """ + if self._last_item is None or item != self._last_item: + super().put(item, block, timeout) + + def _put(self, item: Any) -> None: + super()._put(item) + self._last_item = item + + def _get(self) -> Any: + item = super()._get() + if item is self._last_item: + self._last_item = None + return item diff --git a/.venv/Lib/site-packages/watchdog/utils/delayed_queue.py b/.venv/Lib/site-packages/watchdog/utils/delayed_queue.py new file mode 100644 index 0000000000000000000000000000000000000000..e85fa6348536c08a2a4ba59fab4ddee09e501071 --- /dev/null +++ b/.venv/Lib/site-packages/watchdog/utils/delayed_queue.py @@ -0,0 +1,77 @@ +""":module: watchdog.utils.delayed_queue +:author: thomas.amland@gmail.com (Thomas Amland) +:author: contact@tiger-222.fr (MickaΓ«l Schoentgen) +""" + +from __future__ import annotations + +import threading +import time +from collections import deque +from typing import Callable, Generic, TypeVar + +T = TypeVar("T") + + +class DelayedQueue(Generic[T]): + def __init__(self, delay: float) -> None: + self.delay_sec = delay + self._lock = threading.Lock() + self._not_empty = threading.Condition(self._lock) + self._queue: deque[tuple[T, float, bool]] = deque() + self._closed = False + + def put(self, element: T, *, delay: bool = False) -> None: + """Add element to queue.""" + self._lock.acquire() + self._queue.append((element, time.time(), delay)) + self._not_empty.notify() + self._lock.release() + + def close(self) -> None: + """Close queue, indicating no more items will be added.""" + self._closed = True + # Interrupt the blocking _not_empty.wait() call in get + self._not_empty.acquire() + self._not_empty.notify() + self._not_empty.release() + + def get(self) -> T | None: + """Remove and return an element from the queue, or this queue has been + closed raise the Closed exception. + """ + while True: + # wait for element to be added to queue + self._not_empty.acquire() + while len(self._queue) == 0 and not self._closed: + self._not_empty.wait() + + if self._closed: + self._not_empty.release() + return None + head, insert_time, delay = self._queue[0] + self._not_empty.release() + + # wait for delay if required + if delay: + time_left = insert_time + self.delay_sec - time.time() + while time_left > 0: + time.sleep(time_left) + time_left = insert_time + self.delay_sec - time.time() + + # return element if it's still in the queue + with self._lock: + if len(self._queue) > 0 and self._queue[0][0] is head: + self._queue.popleft() + return head + + def remove(self, predicate: Callable[[T], bool]) -> T | None: + """Remove and return the first items for which predicate is True, + ignoring delay. + """ + with self._lock: + for i, (elem, *_) in enumerate(self._queue): + if predicate(elem): + del self._queue[i] + return elem + return None diff --git a/.venv/Lib/site-packages/watchdog/utils/dirsnapshot.py b/.venv/Lib/site-packages/watchdog/utils/dirsnapshot.py new file mode 100644 index 0000000000000000000000000000000000000000..ff69b0b35e677a8873d2e8d28f2857100f8f4c36 --- /dev/null +++ b/.venv/Lib/site-packages/watchdog/utils/dirsnapshot.py @@ -0,0 +1,424 @@ +""":module: watchdog.utils.dirsnapshot +:synopsis: Directory snapshots and comparison. +:author: yesudeep@google.com (Yesudeep Mangalapilly) +:author: contact@tiger-222.fr (MickaΓ«l Schoentgen) + +.. ADMONITION:: Where are the moved events? They "disappeared" + + This implementation does not take partition boundaries + into consideration. It will only work when the directory + tree is entirely on the same file system. More specifically, + any part of the code that depends on inode numbers can + break if partition boundaries are crossed. In these cases, + the snapshot diff will represent file/directory movement as + created and deleted events. + +Classes +------- +.. autoclass:: DirectorySnapshot + :members: + :show-inheritance: + +.. autoclass:: DirectorySnapshotDiff + :members: + :show-inheritance: + +.. autoclass:: EmptyDirectorySnapshot + :members: + :show-inheritance: + +""" + +from __future__ import annotations + +import contextlib +import errno +import os +from stat import S_ISDIR +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from collections.abc import Iterator + from typing import Any, Callable + + +class DirectorySnapshotDiff: + """Compares two directory snapshots and creates an object that represents + the difference between the two snapshots. + + :param ref: + The reference directory snapshot. + :type ref: + :class:`DirectorySnapshot` + :param snapshot: + The directory snapshot which will be compared + with the reference snapshot. + :type snapshot: + :class:`DirectorySnapshot` + :param ignore_device: + A boolean indicating whether to ignore the device id or not. + By default, a file may be uniquely identified by a combination of its first + inode and its device id. The problem is that the device id may (or may not) + change between system boots. This problem would cause the DirectorySnapshotDiff + to think a file has been deleted and created again but it would be the + exact same file. + Set to True only if you are sure you will always use the same device. + :type ignore_device: + :class:`bool` + """ + + def __init__( + self, + ref: DirectorySnapshot, + snapshot: DirectorySnapshot, + *, + ignore_device: bool = False, + ) -> None: + created = snapshot.paths - ref.paths + deleted = ref.paths - snapshot.paths + + if ignore_device: + + def get_inode(directory: DirectorySnapshot, full_path: bytes | str) -> int | tuple[int, int]: + return directory.inode(full_path)[0] + + else: + + def get_inode(directory: DirectorySnapshot, full_path: bytes | str) -> int | tuple[int, int]: + return directory.inode(full_path) + + # check that all unchanged paths have the same inode + for path in ref.paths & snapshot.paths: + if get_inode(ref, path) != get_inode(snapshot, path): + created.add(path) + deleted.add(path) + + # find moved paths + moved: set[tuple[bytes | str, bytes | str]] = set() + for path in set(deleted): + inode = ref.inode(path) + new_path = snapshot.path(inode) + if new_path: + # file is not deleted but moved + deleted.remove(path) + moved.add((path, new_path)) + + for path in set(created): + inode = snapshot.inode(path) + old_path = ref.path(inode) + if old_path: + created.remove(path) + moved.add((old_path, path)) + + # find modified paths + # first check paths that have not moved + modified: set[bytes | str] = set() + for path in ref.paths & snapshot.paths: + if get_inode(ref, path) == get_inode(snapshot, path) and ( + ref.mtime(path) != snapshot.mtime(path) or ref.size(path) != snapshot.size(path) + ): + modified.add(path) + + for old_path, new_path in moved: + if ref.mtime(old_path) != snapshot.mtime(new_path) or ref.size(old_path) != snapshot.size(new_path): + modified.add(old_path) + + self._dirs_created = [path for path in created if snapshot.isdir(path)] + self._dirs_deleted = [path for path in deleted if ref.isdir(path)] + self._dirs_modified = [path for path in modified if ref.isdir(path)] + self._dirs_moved = [(frm, to) for (frm, to) in moved if ref.isdir(frm)] + + self._files_created = list(created - set(self._dirs_created)) + self._files_deleted = list(deleted - set(self._dirs_deleted)) + self._files_modified = list(modified - set(self._dirs_modified)) + self._files_moved = list(moved - set(self._dirs_moved)) + + def __str__(self) -> str: + return self.__repr__() + + def __repr__(self) -> str: + fmt = ( + "<{0} files(created={1}, deleted={2}, modified={3}, moved={4})," + " folders(created={5}, deleted={6}, modified={7}, moved={8})>" + ) + return fmt.format( + type(self).__name__, + len(self._files_created), + len(self._files_deleted), + len(self._files_modified), + len(self._files_moved), + len(self._dirs_created), + len(self._dirs_deleted), + len(self._dirs_modified), + len(self._dirs_moved), + ) + + @property + def files_created(self) -> list[bytes | str]: + """List of files that were created.""" + return self._files_created + + @property + def files_deleted(self) -> list[bytes | str]: + """List of files that were deleted.""" + return self._files_deleted + + @property + def files_modified(self) -> list[bytes | str]: + """List of files that were modified.""" + return self._files_modified + + @property + def files_moved(self) -> list[tuple[bytes | str, bytes | str]]: + """List of files that were moved. + + Each event is a two-tuple the first item of which is the path + that has been renamed to the second item in the tuple. + """ + return self._files_moved + + @property + def dirs_modified(self) -> list[bytes | str]: + """List of directories that were modified.""" + return self._dirs_modified + + @property + def dirs_moved(self) -> list[tuple[bytes | str, bytes | str]]: + """List of directories that were moved. + + Each event is a two-tuple the first item of which is the path + that has been renamed to the second item in the tuple. + """ + return self._dirs_moved + + @property + def dirs_deleted(self) -> list[bytes | str]: + """List of directories that were deleted.""" + return self._dirs_deleted + + @property + def dirs_created(self) -> list[bytes | str]: + """List of directories that were created.""" + return self._dirs_created + + class ContextManager: + """Context manager that creates two directory snapshots and a + diff object that represents the difference between the two snapshots. + + :param path: + The directory path for which a snapshot should be taken. + :type path: + ``str`` + :param recursive: + ``True`` if the entire directory tree should be included in the + snapshot; ``False`` otherwise. + :type recursive: + ``bool`` + :param stat: + Use custom stat function that returns a stat structure for path. + Currently only st_dev, st_ino, st_mode and st_mtime are needed. + + A function taking a ``path`` as argument which will be called + for every entry in the directory tree. + :param listdir: + Use custom listdir function. For details see ``os.scandir``. + :param ignore_device: + A boolean indicating whether to ignore the device id or not. + By default, a file may be uniquely identified by a combination of its first + inode and its device id. The problem is that the device id may (or may not) + change between system boots. This problem would cause the DirectorySnapshotDiff + to think a file has been deleted and created again but it would be the + exact same file. + Set to True only if you are sure you will always use the same device. + :type ignore_device: + :class:`bool` + """ + + def __init__( + self, + path: str, + *, + recursive: bool = True, + stat: Callable[[str], os.stat_result] = os.stat, + listdir: Callable[[str | None], Iterator[os.DirEntry]] = os.scandir, + ignore_device: bool = False, + ) -> None: + self.path = path + self.recursive = recursive + self.stat = stat + self.listdir = listdir + self.ignore_device = ignore_device + + def __enter__(self) -> None: + self.pre_snapshot = self.get_snapshot() + + def __exit__(self, *args: object) -> None: + self.post_snapshot = self.get_snapshot() + self.diff = DirectorySnapshotDiff( + self.pre_snapshot, + self.post_snapshot, + ignore_device=self.ignore_device, + ) + + def get_snapshot(self) -> DirectorySnapshot: + return DirectorySnapshot( + path=self.path, + recursive=self.recursive, + stat=self.stat, + listdir=self.listdir, + ) + + +class DirectorySnapshot: + """A snapshot of stat information of files in a directory. + + :param path: + The directory path for which a snapshot should be taken. + :type path: + ``str`` + :param recursive: + ``True`` if the entire directory tree should be included in the + snapshot; ``False`` otherwise. + :type recursive: + ``bool`` + :param stat: + Use custom stat function that returns a stat structure for path. + Currently only st_dev, st_ino, st_mode and st_mtime are needed. + + A function taking a ``path`` as argument which will be called + for every entry in the directory tree. + :param listdir: + Use custom listdir function. For details see ``os.scandir``. + """ + + def __init__( + self, + path: str, + *, + recursive: bool = True, + stat: Callable[[str], os.stat_result] = os.stat, + listdir: Callable[[str | None], Iterator[os.DirEntry]] = os.scandir, + ) -> None: + self.recursive = recursive + self.stat = stat + self.listdir = listdir + + self._stat_info: dict[bytes | str, os.stat_result] = {} + self._inode_to_path: dict[tuple[int, int], bytes | str] = {} + + st = self.stat(path) + self._stat_info[path] = st + self._inode_to_path[(st.st_ino, st.st_dev)] = path + + for p, st in self.walk(path): + i = (st.st_ino, st.st_dev) + self._inode_to_path[i] = p + self._stat_info[p] = st + + def walk(self, root: str) -> Iterator[tuple[str, os.stat_result]]: + try: + paths = [os.path.join(root, entry.name) for entry in self.listdir(root)] + except OSError as e: + # Directory may have been deleted between finding it in the directory + # list of its parent and trying to delete its contents. If this + # happens we treat it as empty. Likewise if the directory was replaced + # with a file of the same name (less likely, but possible). + if e.errno in (errno.ENOENT, errno.ENOTDIR, errno.EINVAL): + return + else: + raise + + entries = [] + for p in paths: + with contextlib.suppress(OSError): + entry = (p, self.stat(p)) + entries.append(entry) + yield entry + + if self.recursive: + for path, st in entries: + with contextlib.suppress(PermissionError): + if S_ISDIR(st.st_mode): + yield from self.walk(path) + + @property + def paths(self) -> set[bytes | str]: + """Set of file/directory paths in the snapshot.""" + return set(self._stat_info.keys()) + + def path(self, uid: tuple[int, int]) -> bytes | str | None: + """Returns path for id. None if id is unknown to this snapshot.""" + return self._inode_to_path.get(uid) + + def inode(self, path: bytes | str) -> tuple[int, int]: + """Returns an id for path.""" + st = self._stat_info[path] + return (st.st_ino, st.st_dev) + + def isdir(self, path: bytes | str) -> bool: + return S_ISDIR(self._stat_info[path].st_mode) + + def mtime(self, path: bytes | str) -> float: + return self._stat_info[path].st_mtime + + def size(self, path: bytes | str) -> int: + return self._stat_info[path].st_size + + def stat_info(self, path: bytes | str) -> os.stat_result: + """Returns a stat information object for the specified path from + the snapshot. + + Attached information is subject to change. Do not use unless + you specify `stat` in constructor. Use :func:`inode`, :func:`mtime`, + :func:`isdir` instead. + + :param path: + The path for which stat information should be obtained + from a snapshot. + """ + return self._stat_info[path] + + def __sub__(self, previous_dirsnap: DirectorySnapshot) -> DirectorySnapshotDiff: + """Allow subtracting a DirectorySnapshot object instance from + another. + + :returns: + A :class:`DirectorySnapshotDiff` object. + """ + return DirectorySnapshotDiff(previous_dirsnap, self) + + def __str__(self) -> str: + return self.__repr__() + + def __repr__(self) -> str: + return str(self._stat_info) + + +class EmptyDirectorySnapshot(DirectorySnapshot): + """Class to implement an empty snapshot. This is used together with + DirectorySnapshot and DirectorySnapshotDiff in order to get all the files/folders + in the directory as created. + """ + + def __init__(self) -> None: + pass + + @staticmethod + def path(_: Any) -> None: + """Mock up method to return the path of the received inode. As the snapshot + is intended to be empty, it always returns None. + + :returns: + None. + """ + return + + @property + def paths(self) -> set: + """Mock up method to return a set of file/directory paths in the snapshot. As + the snapshot is intended to be empty, it always returns an empty set. + + :returns: + An empty set. + """ + return set() diff --git a/.venv/Lib/site-packages/watchdog/utils/echo.py b/.venv/Lib/site-packages/watchdog/utils/echo.py new file mode 100644 index 0000000000000000000000000000000000000000..4ff9217d341584b2d2bc119506b6789a6a58593d --- /dev/null +++ b/.venv/Lib/site-packages/watchdog/utils/echo.py @@ -0,0 +1,68 @@ +# echo.py: Tracing function calls using Python decorators. +# +# Written by Thomas Guest +# Please see http://wordaligned.org/articles/echo +# +# Place into the public domain. + +"""Echo calls made to functions in a module. + +"Echoing" a function call means printing out the name of the function +and the values of its arguments before making the call (which is more +commonly referred to as "tracing", but Python already has a trace module). + +Alternatively, echo.echo can be used to decorate functions. Calls to the +decorated function will be echoed. + +Example: +------- + + @echo.echo + def my_function(args): + pass + +""" + +from __future__ import annotations + +import functools +import sys +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from typing import Any, Callable + + +def format_arg_value(arg_val: tuple[str, tuple[Any, ...]]) -> str: + """Return a string representing a (name, value) pair.""" + arg, val = arg_val + return f"{arg}={val!r}" + + +def echo(fn: Callable, write: Callable[[str], int | None] = sys.stdout.write) -> Callable: + """Echo calls to a function. + + Returns a decorated version of the input function which "echoes" calls + made to it by writing out the function's name and the arguments it was + called with. + """ + # Unpack function's arg count, arg names, arg defaults + code = fn.__code__ + argcount = code.co_argcount + argnames = code.co_varnames[:argcount] + fn_defaults: tuple[Any] = fn.__defaults__ or () + argdefs = dict(list(zip(argnames[-len(fn_defaults) :], fn_defaults))) + + @functools.wraps(fn) + def wrapped(*v: Any, **k: Any) -> Callable: + # Collect function arguments by chaining together positional, + # defaulted, extra positional and keyword arguments. + positional = list(map(format_arg_value, list(zip(argnames, v)))) + defaulted = [format_arg_value((a, argdefs[a])) for a in argnames[len(v) :] if a not in k] + nameless = list(map(repr, v[argcount:])) + keyword = list(map(format_arg_value, list(k.items()))) + args = positional + defaulted + nameless + keyword + write(f"{fn.__name__}({', '.join(args)})\n") + return fn(*v, **k) + + return wrapped diff --git a/.venv/Lib/site-packages/watchdog/utils/event_debouncer.py b/.venv/Lib/site-packages/watchdog/utils/event_debouncer.py new file mode 100644 index 0000000000000000000000000000000000000000..d9569733354904f057b29535a842521f0628db14 --- /dev/null +++ b/.venv/Lib/site-packages/watchdog/utils/event_debouncer.py @@ -0,0 +1,66 @@ +from __future__ import annotations + +import logging +import threading +from typing import TYPE_CHECKING + +from watchdog.utils import BaseThread + +if TYPE_CHECKING: + from typing import Callable + + from watchdog.events import FileSystemEvent + +logger = logging.getLogger(__name__) + + +class EventDebouncer(BaseThread): + """Background thread for debouncing event handling. + + When an event is received, wait until the configured debounce interval + passes before calling the callback. If additional events are received + before the interval passes, reset the timer and keep waiting. When the + debouncing interval passes, the callback will be called with a list of + events in the order in which they were received. + """ + + def __init__( + self, + debounce_interval_seconds: int, + events_callback: Callable[[list[FileSystemEvent]], None], + ) -> None: + super().__init__() + self.debounce_interval_seconds = debounce_interval_seconds + self.events_callback = events_callback + + self._events: list[FileSystemEvent] = [] + self._cond = threading.Condition() + + def handle_event(self, event: FileSystemEvent) -> None: + with self._cond: + self._events.append(event) + self._cond.notify() + + def stop(self) -> None: + with self._cond: + super().stop() + self._cond.notify() + + def run(self) -> None: + with self._cond: + while True: + # Wait for first event (or shutdown). + self._cond.wait() + + if self.debounce_interval_seconds: + # Wait for additional events (or shutdown) until the debounce interval passes. + while self.should_keep_running(): + if not self._cond.wait(timeout=self.debounce_interval_seconds): + break + + if not self.should_keep_running(): + break + + events = self._events + self._events = [] + self.events_callback(events) diff --git a/.venv/Lib/site-packages/watchdog/utils/patterns.py b/.venv/Lib/site-packages/watchdog/utils/patterns.py new file mode 100644 index 0000000000000000000000000000000000000000..95b479ae6be56e13aa020b28a42813e90d6a3797 --- /dev/null +++ b/.venv/Lib/site-packages/watchdog/utils/patterns.py @@ -0,0 +1,99 @@ +""":module: watchdog.utils.patterns +:synopsis: Common wildcard searching/filtering functionality for files. +:author: boris.staletic@gmail.com (Boris Staletic) +:author: yesudeep@gmail.com (Yesudeep Mangalapilly) +:author: contact@tiger-222.fr (MickaΓ«l Schoentgen) +""" + +from __future__ import annotations + +# Non-pure path objects are only allowed on their respective OS's. +# Thus, these utilities require "pure" path objects that don't access the filesystem. +# Since pathlib doesn't have a `case_sensitive` parameter, we have to approximate it +# by converting input paths to `PureWindowsPath` and `PurePosixPath` where: +# - `PureWindowsPath` is always case-insensitive. +# - `PurePosixPath` is always case-sensitive. +# Reference: https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.match +from pathlib import PurePosixPath, PureWindowsPath +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from collections.abc import Iterator + + +def _match_path( + raw_path: str, + included_patterns: set[str], + excluded_patterns: set[str], + *, + case_sensitive: bool, +) -> bool: + """Internal function same as :func:`match_path` but does not check arguments.""" + path: PurePosixPath | PureWindowsPath + if case_sensitive: + path = PurePosixPath(raw_path) + else: + included_patterns = {pattern.lower() for pattern in included_patterns} + excluded_patterns = {pattern.lower() for pattern in excluded_patterns} + path = PureWindowsPath(raw_path) + + common_patterns = included_patterns & excluded_patterns + if common_patterns: + error = f"conflicting patterns `{common_patterns}` included and excluded" + raise ValueError(error) + + return any(path.match(p) for p in included_patterns) and not any(path.match(p) for p in excluded_patterns) + + +def filter_paths( + paths: list[str], + *, + included_patterns: list[str] | None = None, + excluded_patterns: list[str] | None = None, + case_sensitive: bool = True, +) -> Iterator[str]: + """Filters from a set of paths based on acceptable patterns and + ignorable patterns. + :param paths: + A list of path names that will be filtered based on matching and + ignored patterns. + :param included_patterns: + Allow filenames matching wildcard patterns specified in this list. + If no pattern list is specified, ["*"] is used as the default pattern, + which matches all files. + :param excluded_patterns: + Ignores filenames matching wildcard patterns specified in this list. + If no pattern list is specified, no files are ignored. + :param case_sensitive: + ``True`` if matching should be case-sensitive; ``False`` otherwise. + :returns: + A list of pathnames that matched the allowable patterns and passed + through the ignored patterns. + """ + included = set(["*"] if included_patterns is None else included_patterns) + excluded = set([] if excluded_patterns is None else excluded_patterns) + + for path in paths: + if _match_path(path, included, excluded, case_sensitive=case_sensitive): + yield path + + +def match_any_paths( + paths: list[str], + *, + included_patterns: list[str] | None = None, + excluded_patterns: list[str] | None = None, + case_sensitive: bool = True, +) -> bool: + """Matches from a set of paths based on acceptable patterns and + ignorable patterns. + See ``filter_paths()`` for signature details. + """ + return any( + filter_paths( + paths, + included_patterns=included_patterns, + excluded_patterns=excluded_patterns, + case_sensitive=case_sensitive, + ), + ) diff --git a/.venv/Lib/site-packages/watchdog/utils/platform.py b/.venv/Lib/site-packages/watchdog/utils/platform.py new file mode 100644 index 0000000000000000000000000000000000000000..3c11d152c0302ad28794c3a415ab43b3ecf8a8d2 --- /dev/null +++ b/.venv/Lib/site-packages/watchdog/utils/platform.py @@ -0,0 +1,44 @@ +from __future__ import annotations + +import sys + +PLATFORM_WINDOWS = "windows" +PLATFORM_LINUX = "linux" +PLATFORM_BSD = "bsd" +PLATFORM_DARWIN = "darwin" +PLATFORM_UNKNOWN = "unknown" + + +def get_platform_name() -> str: + if sys.platform.startswith("win"): + return PLATFORM_WINDOWS + + if sys.platform.startswith("darwin"): + return PLATFORM_DARWIN + + if sys.platform.startswith("linux"): + return PLATFORM_LINUX + + if sys.platform.startswith(("dragonfly", "freebsd", "netbsd", "openbsd", "bsd")): + return PLATFORM_BSD + + return PLATFORM_UNKNOWN + + +__platform__ = get_platform_name() + + +def is_linux() -> bool: + return __platform__ == PLATFORM_LINUX + + +def is_bsd() -> bool: + return __platform__ == PLATFORM_BSD + + +def is_darwin() -> bool: + return __platform__ == PLATFORM_DARWIN + + +def is_windows() -> bool: + return __platform__ == PLATFORM_WINDOWS diff --git a/.venv/Lib/site-packages/watchdog/utils/process_watcher.py b/.venv/Lib/site-packages/watchdog/utils/process_watcher.py new file mode 100644 index 0000000000000000000000000000000000000000..f500266a5bbd688c436bd7fcd6091cd78dfded6f --- /dev/null +++ b/.venv/Lib/site-packages/watchdog/utils/process_watcher.py @@ -0,0 +1,30 @@ +from __future__ import annotations + +import logging +from typing import TYPE_CHECKING + +from watchdog.utils import BaseThread + +if TYPE_CHECKING: + import subprocess + from typing import Callable + +logger = logging.getLogger(__name__) + + +class ProcessWatcher(BaseThread): + def __init__(self, popen_obj: subprocess.Popen, process_termination_callback: Callable[[], None] | None) -> None: + super().__init__() + self.popen_obj = popen_obj + self.process_termination_callback = process_termination_callback + + def run(self) -> None: + while self.popen_obj.poll() is None: + if self.stopped_event.wait(timeout=0.1): + return + + try: + if not self.stopped_event.is_set() and self.process_termination_callback: + self.process_termination_callback() + except Exception: + logger.exception("Error calling process termination callback") diff --git a/.venv/Lib/site-packages/watchdog/version.py b/.venv/Lib/site-packages/watchdog/version.py new file mode 100644 index 0000000000000000000000000000000000000000..8e1876f6a2bc12c11999a2299d8b03b9332d1098 --- /dev/null +++ b/.venv/Lib/site-packages/watchdog/version.py @@ -0,0 +1,11 @@ +from __future__ import annotations + +# When updating this version number, please update the +# ``docs/source/global.rst.inc`` file as well. +VERSION_MAJOR = 6 +VERSION_MINOR = 0 +VERSION_BUILD = 0 +VERSION_INFO = (VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD) +VERSION_STRING = f"{VERSION_MAJOR}.{VERSION_MINOR}.{VERSION_BUILD}" + +__version__ = VERSION_INFO diff --git a/.venv/Lib/site-packages/watchdog/watchmedo.py b/.venv/Lib/site-packages/watchdog/watchmedo.py new file mode 100644 index 0000000000000000000000000000000000000000..e7879563c96b71ab428f942e8f4cce435cdb5a4e --- /dev/null +++ b/.venv/Lib/site-packages/watchdog/watchmedo.py @@ -0,0 +1,807 @@ +""":module: watchdog.watchmedo +:author: yesudeep@google.com (Yesudeep Mangalapilly) +:author: contact@tiger-222.fr (MickaΓ«l Schoentgen) +:synopsis: ``watchmedo`` shell script utility. +""" + +from __future__ import annotations + +import errno +import logging +import os +import os.path +import sys +import time +from argparse import ArgumentParser, RawDescriptionHelpFormatter +from io import StringIO +from textwrap import dedent +from typing import TYPE_CHECKING, Any + +from watchdog.utils import WatchdogShutdownError, load_class, platform +from watchdog.version import VERSION_STRING + +if TYPE_CHECKING: + from argparse import Namespace, _SubParsersAction + from typing import Callable + + from watchdog.events import FileSystemEventHandler + from watchdog.observers import ObserverType + from watchdog.observers.api import BaseObserver + + +logging.basicConfig(level=logging.INFO) + +CONFIG_KEY_TRICKS = "tricks" +CONFIG_KEY_PYTHON_PATH = "python-path" + + +class HelpFormatter(RawDescriptionHelpFormatter): + """A nicer help formatter. + + Help for arguments can be indented and contain new lines. + It will be de-dented and arguments in the help + will be separated by a blank line for better readability. + + Source: https://github.com/httpie/httpie/blob/2423f89/httpie/cli/argparser.py#L31 + """ + + def __init__(self, *args: Any, max_help_position: int = 6, **kwargs: Any) -> None: + # A smaller indent for args help. + kwargs["max_help_position"] = max_help_position + super().__init__(*args, **kwargs) + + def __repr__(self) -> str: + return f"<{type(self).__name__}>" + + def _split_lines(self, text: str, width: int) -> list[str]: + text = dedent(text).strip() + "\n\n" + return text.splitlines() + + +epilog = """\ +Copyright 2018-2024 MickaΓ«l Schoentgen & contributors +Copyright 2014-2018 Thomas Amland & contributors +Copyright 2012-2014 Google, Inc. +Copyright 2011-2012 Yesudeep Mangalapilly + +Licensed under the terms of the Apache license, version 2.0. Please see +LICENSE in the source code for more information.""" + +cli = ArgumentParser(epilog=epilog, formatter_class=HelpFormatter) +cli.add_argument("--version", action="version", version=VERSION_STRING) +subparsers = cli.add_subparsers(dest="top_command") +command_parsers = {} + +Argument = tuple[list[str], Any] + + +def argument(*name_or_flags: str, **kwargs: Any) -> Argument: + """Convenience function to properly format arguments to pass to the + command decorator. + """ + return list(name_or_flags), kwargs + + +def command( + args: list[Argument], + *, + parent: _SubParsersAction[ArgumentParser] = subparsers, + cmd_aliases: list[str] | None = None, +) -> Callable: + """Decorator to define a new command in a sanity-preserving way. + The function will be stored in the ``func`` variable when the parser + parses arguments so that it can be called directly like so:: + + >>> args = cli.parse_args() + >>> args.func(args) + + """ + + def decorator(func: Callable) -> Callable: + name = func.__name__.replace("_", "-") + desc = dedent(func.__doc__ or "") + parser = parent.add_parser(name, aliases=cmd_aliases or [], description=desc, formatter_class=HelpFormatter) + command_parsers[name] = parser + verbosity_group = parser.add_mutually_exclusive_group() + verbosity_group.add_argument("-q", "--quiet", dest="verbosity", action="append_const", const=-1) + verbosity_group.add_argument("-v", "--verbose", dest="verbosity", action="append_const", const=1) + for name_or_flags, kwargs in args: + parser.add_argument(*name_or_flags, **kwargs) + parser.set_defaults(func=func) + return func + + return decorator + + +def path_split(pathname_spec: str, *, separator: str = os.pathsep) -> list[str]: + """Splits a pathname specification separated by an OS-dependent separator. + + :param pathname_spec: + The pathname specification. + :param separator: + (OS Dependent) `:` on Unix and `;` on Windows or user-specified. + """ + return pathname_spec.split(separator) + + +def add_to_sys_path(pathnames: list[str], *, index: int = 0) -> None: + """Adds specified paths at specified index into the sys.path list. + + :param paths: + A list of paths to add to the sys.path + :param index: + (Default 0) The index in the sys.path list where the paths will be + added. + """ + for pathname in pathnames[::-1]: + sys.path.insert(index, pathname) + + +def load_config(tricks_file_pathname: str) -> dict: + """Loads the YAML configuration from the specified file. + + :param tricks_file_path: + The path to the tricks configuration file. + :returns: + A dictionary of configuration information. + """ + import yaml + + with open(tricks_file_pathname, "rb") as f: + return yaml.safe_load(f.read()) + + +def parse_patterns( + patterns_spec: str, ignore_patterns_spec: str, *, separator: str = ";" +) -> tuple[list[str], list[str]]: + """Parses pattern argument specs and returns a two-tuple of + (patterns, ignore_patterns). + """ + patterns = patterns_spec.split(separator) + ignore_patterns = ignore_patterns_spec.split(separator) + if ignore_patterns == [""]: + ignore_patterns = [] + return patterns, ignore_patterns + + +def observe_with( + observer: BaseObserver, + event_handler: FileSystemEventHandler, + pathnames: list[str], + *, + recursive: bool, +) -> None: + """Single observer thread with a scheduled path and event handler. + + :param observer: + The observer thread. + :param event_handler: + Event handler which will be called in response to file system events. + :param pathnames: + A list of pathnames to monitor. + :param recursive: + ``True`` if recursive; ``False`` otherwise. + """ + for pathname in set(pathnames): + observer.schedule(event_handler, pathname, recursive=recursive) + observer.start() + try: + while True: + time.sleep(1) + except WatchdogShutdownError: + observer.stop() + observer.join() + + +def schedule_tricks(observer: BaseObserver, tricks: list[dict], pathname: str, *, recursive: bool) -> None: + """Schedules tricks with the specified observer and for the given watch + path. + + :param observer: + The observer thread into which to schedule the trick and watch. + :param tricks: + A list of tricks. + :param pathname: + A path name which should be watched. + :param recursive: + ``True`` if recursive; ``False`` otherwise. + """ + for trick in tricks: + for name, value in trick.items(): + trick_cls = load_class(name) + handler = trick_cls(**value) + trick_pathname = getattr(handler, "source_directory", None) or pathname + observer.schedule(handler, trick_pathname, recursive=recursive) + + +@command( + [ + argument("files", nargs="*", help="perform tricks from given file"), + argument( + "--python-path", + default=".", + help=f"Paths separated by {os.pathsep!r} to add to the Python path.", + ), + argument( + "--interval", + "--timeout", + dest="timeout", + default=1.0, + type=float, + help="Use this as the polling interval/blocking timeout (in seconds).", + ), + argument( + "--recursive", + action="store_true", + default=True, + help="Recursively monitor paths (defaults to True).", + ), + argument("--debug-force-polling", action="store_true", help="[debug] Forces polling."), + argument( + "--debug-force-kqueue", + action="store_true", + help="[debug] Forces BSD kqueue(2).", + ), + argument( + "--debug-force-winapi", + action="store_true", + help="[debug] Forces Windows API.", + ), + argument( + "--debug-force-fsevents", + action="store_true", + help="[debug] Forces macOS FSEvents.", + ), + argument( + "--debug-force-inotify", + action="store_true", + help="[debug] Forces Linux inotify(7).", + ), + ], + cmd_aliases=["tricks"], +) +def tricks_from(args: Namespace) -> None: + """Command to execute tricks from a tricks configuration file.""" + observer_cls: ObserverType + if args.debug_force_polling: + from watchdog.observers.polling import PollingObserver + + observer_cls = PollingObserver + elif args.debug_force_kqueue: + from watchdog.observers.kqueue import KqueueObserver + + observer_cls = KqueueObserver + elif (not TYPE_CHECKING and args.debug_force_winapi) or (TYPE_CHECKING and platform.is_windows()): + from watchdog.observers.read_directory_changes import WindowsApiObserver + + observer_cls = WindowsApiObserver + elif args.debug_force_inotify: + from watchdog.observers.inotify import InotifyObserver + + observer_cls = InotifyObserver + elif args.debug_force_fsevents: + from watchdog.observers.fsevents import FSEventsObserver + + observer_cls = FSEventsObserver + else: + # Automatically picks the most appropriate observer for the platform + # on which it is running. + from watchdog.observers import Observer + + observer_cls = Observer + + add_to_sys_path(path_split(args.python_path)) + observers = [] + for tricks_file in args.files: + observer = observer_cls(timeout=args.timeout) + + if not os.path.exists(tricks_file): + raise OSError(errno.ENOENT, os.strerror(errno.ENOENT), tricks_file) + + config = load_config(tricks_file) + + try: + tricks = config[CONFIG_KEY_TRICKS] + except KeyError as e: + error = f"No {CONFIG_KEY_TRICKS!r} key specified in {tricks_file!r}." + raise KeyError(error) from e + + if CONFIG_KEY_PYTHON_PATH in config: + add_to_sys_path(config[CONFIG_KEY_PYTHON_PATH]) + + dir_path = os.path.dirname(tricks_file) or os.path.relpath(os.getcwd()) + schedule_tricks(observer, tricks, dir_path, recursive=args.recursive) + observer.start() + observers.append(observer) + + try: + while True: + time.sleep(1) + except WatchdogShutdownError: + for o in observers: + o.unschedule_all() + o.stop() + for o in observers: + o.join() + + +@command( + [ + argument( + "trick_paths", + nargs="*", + help="Dotted paths for all the tricks you want to generate.", + ), + argument( + "--python-path", + default=".", + help=f"Paths separated by {os.pathsep!r} to add to the Python path.", + ), + argument( + "--append-to-file", + default=None, + help=""" + Appends the generated tricks YAML to a file. + If not specified, prints to standard output.""", + ), + argument( + "-a", + "--append-only", + dest="append_only", + action="store_true", + help=""" + If --append-to-file is not specified, produces output for + appending instead of a complete tricks YAML file.""", + ), + ], + cmd_aliases=["generate-tricks-yaml"], +) +def tricks_generate_yaml(args: Namespace) -> None: + """Command to generate Yaml configuration for tricks named on the command line.""" + import yaml + + python_paths = path_split(args.python_path) + add_to_sys_path(python_paths) + output = StringIO() + + for trick_path in args.trick_paths: + trick_cls = load_class(trick_path) + output.write(trick_cls.generate_yaml()) + + content = output.getvalue() + output.close() + + header = yaml.dump({CONFIG_KEY_PYTHON_PATH: python_paths}) + header += f"{CONFIG_KEY_TRICKS}:\n" + if args.append_to_file is None: + # Output to standard output. + if not args.append_only: + content = header + content + sys.stdout.write(content) + else: + if not os.path.exists(args.append_to_file): + content = header + content + with open(args.append_to_file, "a", encoding="utf-8") as file: + file.write(content) + + +@command( + [ + argument( + "directories", + nargs="*", + default=".", + help="Directories to watch. (default: '.').", + ), + argument( + "-p", + "--pattern", + "--patterns", + dest="patterns", + default="*", + help="Matches event paths with these patterns (separated by ;).", + ), + argument( + "-i", + "--ignore-pattern", + "--ignore-patterns", + dest="ignore_patterns", + default="", + help="Ignores event paths with these patterns (separated by ;).", + ), + argument( + "-D", + "--ignore-directories", + dest="ignore_directories", + action="store_true", + help="Ignores events for directories.", + ), + argument( + "-R", + "--recursive", + dest="recursive", + action="store_true", + help="Monitors the directories recursively.", + ), + argument( + "--interval", + "--timeout", + dest="timeout", + default=1.0, + type=float, + help="Use this as the polling interval/blocking timeout.", + ), + argument("--debug-force-polling", action="store_true", help="[debug] Forces polling."), + argument( + "--debug-force-kqueue", + action="store_true", + help="[debug] Forces BSD kqueue(2).", + ), + argument( + "--debug-force-winapi", + action="store_true", + help="[debug] Forces Windows API.", + ), + argument( + "--debug-force-fsevents", + action="store_true", + help="[debug] Forces macOS FSEvents.", + ), + argument( + "--debug-force-inotify", + action="store_true", + help="[debug] Forces Linux inotify(7).", + ), + ], +) +def log(args: Namespace) -> None: + """Command to log file system events to the console.""" + from watchdog.tricks import LoggerTrick + + patterns, ignore_patterns = parse_patterns(args.patterns, args.ignore_patterns) + handler = LoggerTrick( + patterns=patterns, + ignore_patterns=ignore_patterns, + ignore_directories=args.ignore_directories, + ) + + observer_cls: ObserverType + if args.debug_force_polling: + from watchdog.observers.polling import PollingObserver + + observer_cls = PollingObserver + elif args.debug_force_kqueue: + from watchdog.observers.kqueue import KqueueObserver + + observer_cls = KqueueObserver + elif (not TYPE_CHECKING and args.debug_force_winapi) or (TYPE_CHECKING and platform.is_windows()): + from watchdog.observers.read_directory_changes import WindowsApiObserver + + observer_cls = WindowsApiObserver + elif args.debug_force_inotify: + from watchdog.observers.inotify import InotifyObserver + + observer_cls = InotifyObserver + elif args.debug_force_fsevents: + from watchdog.observers.fsevents import FSEventsObserver + + observer_cls = FSEventsObserver + else: + # Automatically picks the most appropriate observer for the platform + # on which it is running. + from watchdog.observers import Observer + + observer_cls = Observer + + observer = observer_cls(timeout=args.timeout) + observe_with(observer, handler, args.directories, recursive=args.recursive) + + +@command( + [ + argument("directories", nargs="*", default=".", help="Directories to watch."), + argument( + "-c", + "--command", + dest="command", + default=None, + help=""" + Shell command executed in response to matching events. + These interpolation variables are available to your command string: + + ${watch_src_path} - event source path + ${watch_dest_path} - event destination path (for moved events) + ${watch_event_type} - event type + ${watch_object} - 'file' or 'directory' + + Note: + Please ensure you do not use double quotes (") to quote + your command string. That will force your shell to + interpolate before the command is processed by this + command. + + Example: + + --command='echo "${watch_src_path}"' + """, + ), + argument( + "-p", + "--pattern", + "--patterns", + dest="patterns", + default="*", + help="Matches event paths with these patterns (separated by ;).", + ), + argument( + "-i", + "--ignore-pattern", + "--ignore-patterns", + dest="ignore_patterns", + default="", + help="Ignores event paths with these patterns (separated by ;).", + ), + argument( + "-D", + "--ignore-directories", + dest="ignore_directories", + default=False, + action="store_true", + help="Ignores events for directories.", + ), + argument( + "-R", + "--recursive", + dest="recursive", + action="store_true", + help="Monitors the directories recursively.", + ), + argument( + "--interval", + "--timeout", + dest="timeout", + default=1.0, + type=float, + help="Use this as the polling interval/blocking timeout.", + ), + argument( + "-w", + "--wait", + dest="wait_for_process", + action="store_true", + help="Wait for process to finish to avoid multiple simultaneous instances.", + ), + argument( + "-W", + "--drop", + dest="drop_during_process", + action="store_true", + help="Ignore events that occur while command is still being" + " executed to avoid multiple simultaneous instances.", + ), + argument("--debug-force-polling", action="store_true", help="[debug] Forces polling."), + ], +) +def shell_command(args: Namespace) -> None: + """Command to execute shell commands in response to file system events.""" + from watchdog.tricks import ShellCommandTrick + + if not args.command: + args.command = None + + observer_cls: ObserverType + if args.debug_force_polling: + from watchdog.observers.polling import PollingObserver + + observer_cls = PollingObserver + else: + from watchdog.observers import Observer + + observer_cls = Observer + + patterns, ignore_patterns = parse_patterns(args.patterns, args.ignore_patterns) + handler = ShellCommandTrick( + args.command, + patterns=patterns, + ignore_patterns=ignore_patterns, + ignore_directories=args.ignore_directories, + wait_for_process=args.wait_for_process, + drop_during_process=args.drop_during_process, + ) + observer = observer_cls(timeout=args.timeout) + observe_with(observer, handler, args.directories, recursive=args.recursive) + + +@command( + [ + argument("command", help="Long-running command to run in a subprocess."), + argument( + "command_args", + metavar="arg", + nargs="*", + help=""" + Command arguments. + + Note: Use -- before the command arguments, otherwise watchmedo will + try to interpret them. + """, + ), + argument( + "-d", + "--directory", + dest="directories", + metavar="DIRECTORY", + action="append", + help="Directory to watch. Use another -d or --directory option for each directory.", + ), + argument( + "-p", + "--pattern", + "--patterns", + dest="patterns", + default="*", + help="Matches event paths with these patterns (separated by ;).", + ), + argument( + "-i", + "--ignore-pattern", + "--ignore-patterns", + dest="ignore_patterns", + default="", + help="Ignores event paths with these patterns (separated by ;).", + ), + argument( + "-D", + "--ignore-directories", + dest="ignore_directories", + default=False, + action="store_true", + help="Ignores events for directories.", + ), + argument( + "-R", + "--recursive", + dest="recursive", + action="store_true", + help="Monitors the directories recursively.", + ), + argument( + "--interval", + "--timeout", + dest="timeout", + default=1.0, + type=float, + help="Use this as the polling interval/blocking timeout.", + ), + argument( + "--signal", + dest="signal", + default="SIGINT", + help="Stop the subprocess with this signal (default SIGINT).", + ), + argument("--debug-force-polling", action="store_true", help="[debug] Forces polling."), + argument( + "--kill-after", + dest="kill_after", + default=10.0, + type=float, + help="When stopping, kill the subprocess after the specified timeout in seconds (default 10.0).", + ), + argument( + "--debounce-interval", + dest="debounce_interval", + default=0.0, + type=float, + help="After a file change, Wait until the specified interval (in " + "seconds) passes with no file changes, and only then restart.", + ), + argument( + "--no-restart-on-command-exit", + dest="restart_on_command_exit", + default=True, + action="store_false", + help="Don't auto-restart the command after it exits.", + ), + ], +) +def auto_restart(args: Namespace) -> None: + """Command to start a long-running subprocess and restart it on matched events.""" + observer_cls: ObserverType + if args.debug_force_polling: + from watchdog.observers.polling import PollingObserver + + observer_cls = PollingObserver + else: + from watchdog.observers import Observer + + observer_cls = Observer + + import signal + + from watchdog.tricks import AutoRestartTrick + + if not args.directories: + args.directories = ["."] + + # Allow either signal name or number. + stop_signal = getattr(signal, args.signal) if args.signal.startswith("SIG") else int(args.signal) + + # Handle termination signals by raising a semantic exception which will + # allow us to gracefully unwind and stop the observer + termination_signals = {signal.SIGTERM, signal.SIGINT} + + if hasattr(signal, "SIGHUP"): + termination_signals.add(signal.SIGHUP) + + def handler_termination_signal(_signum: signal._SIGNUM, _frame: object) -> None: + # Neuter all signals so that we don't attempt a double shutdown + for signum in termination_signals: + signal.signal(signum, signal.SIG_IGN) + raise WatchdogShutdownError + + for signum in termination_signals: + signal.signal(signum, handler_termination_signal) + + patterns, ignore_patterns = parse_patterns(args.patterns, args.ignore_patterns) + command = [args.command] + command.extend(args.command_args) + handler = AutoRestartTrick( + command, + patterns=patterns, + ignore_patterns=ignore_patterns, + ignore_directories=args.ignore_directories, + stop_signal=stop_signal, + kill_after=args.kill_after, + debounce_interval_seconds=args.debounce_interval, + restart_on_command_exit=args.restart_on_command_exit, + ) + handler.start() + observer = observer_cls(timeout=args.timeout) + try: + observe_with(observer, handler, args.directories, recursive=args.recursive) + except WatchdogShutdownError: + pass + finally: + handler.stop() + + +class LogLevelError(Exception): + pass + + +def _get_log_level_from_args(args: Namespace) -> str: + verbosity = sum(args.verbosity or []) + if verbosity < -1: + error = "-q/--quiet may be specified only once." + raise LogLevelError(error) + if verbosity > 2: + error = "-v/--verbose may be specified up to 2 times." + raise LogLevelError(error) + return ["ERROR", "WARNING", "INFO", "DEBUG"][1 + verbosity] + + +def main() -> int: + """Entry-point function.""" + args = cli.parse_args() + if args.top_command is None: + cli.print_help() + return 1 + + try: + log_level = _get_log_level_from_args(args) + except LogLevelError as exc: + print(f"Error: {exc.args[0]}", file=sys.stderr) # noqa:T201 + command_parsers[args.top_command].print_help() + return 1 + logging.getLogger("watchdog").setLevel(log_level) + + try: + args.func(args) + except KeyboardInterrupt: + return 130 + + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/.venv/Lib/site-packages/websockets-16.1.dist-info/INSTALLER b/.venv/Lib/site-packages/websockets-16.1.dist-info/INSTALLER new file mode 100644 index 0000000000000000000000000000000000000000..a1b589e38a32041e49332e5e81c2d363dc418d68 --- /dev/null +++ b/.venv/Lib/site-packages/websockets-16.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/.venv/Lib/site-packages/websockets-16.1.dist-info/METADATA b/.venv/Lib/site-packages/websockets-16.1.dist-info/METADATA new file mode 100644 index 0000000000000000000000000000000000000000..ffacc824932ee11da09d5cb502cb325f4f31c65f --- /dev/null +++ b/.venv/Lib/site-packages/websockets-16.1.dist-info/METADATA @@ -0,0 +1,179 @@ +Metadata-Version: 2.4 +Name: websockets +Version: 16.1 +Summary: An implementation of the WebSocket Protocol (RFC 6455 & 7692) +Author-email: Aymeric Augustin +License-Expression: BSD-3-Clause +Project-URL: Homepage, https://github.com/python-websockets/websockets +Project-URL: Changelog, https://websockets.readthedocs.io/en/stable/project/changelog.html +Project-URL: Documentation, https://websockets.readthedocs.io/ +Project-URL: Funding, https://tidelift.com/subscription/pkg/pypi-websockets?utm_source=pypi-websockets&utm_medium=referral&utm_campaign=readme +Project-URL: Tracker, https://github.com/python-websockets/websockets/issues +Keywords: WebSocket +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 +Classifier: Programming Language :: Python :: 3.13 +Classifier: Programming Language :: Python :: 3.14 +Requires-Python: >=3.10 +Description-Content-Type: text/x-rst +License-File: LICENSE +Dynamic: description +Dynamic: description-content-type +Dynamic: license-file + +.. image:: logo/horizontal.svg + :width: 480px + :alt: websockets + +|licence| |version| |pyversions| |tests| |docs| |openssf| + +.. |licence| image:: https://img.shields.io/pypi/l/websockets.svg + :target: https://pypi.python.org/pypi/websockets + +.. |version| image:: https://img.shields.io/pypi/v/websockets.svg + :target: https://pypi.python.org/pypi/websockets + +.. |pyversions| image:: https://img.shields.io/pypi/pyversions/websockets.svg + :target: https://pypi.python.org/pypi/websockets + +.. |tests| image:: https://img.shields.io/github/checks-status/python-websockets/websockets/main?label=tests + :target: https://github.com/python-websockets/websockets/actions/workflows/tests.yml + +.. |docs| image:: https://img.shields.io/readthedocs/websockets.svg + :target: https://websockets.readthedocs.io/ + +.. |openssf| image:: https://bestpractices.coreinfrastructure.org/projects/6475/badge + :target: https://bestpractices.coreinfrastructure.org/projects/6475 + +What is ``websockets``? +----------------------- + +websockets is a library for building WebSocket_ servers and clients in Python +with a focus on correctness, simplicity, robustness, and performance. + +.. _WebSocket: https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API + +Built on top of ``asyncio``, Python's standard asynchronous I/O framework, the +default implementation provides an elegant coroutine-based API. + +An implementation on top of ``threading`` and a Sans-I/O implementation are also +available. + +`Documentation is available on Read the Docs. `_ + +.. copy-pasted because GitHub doesn't support the include directive + +Here's an echo server with the ``asyncio`` API: + +.. code:: python + + #!/usr/bin/env python + + import asyncio + from websockets.asyncio.server import serve + + async def echo(websocket): + async for message in websocket: + await websocket.send(message) + + async def main(): + async with serve(echo, "localhost", 8765) as server: + await server.serve_forever() + + asyncio.run(main()) + +Here's how a client sends and receives messages with the ``threading`` API: + +.. code:: python + + #!/usr/bin/env python + + from websockets.sync.client import connect + + def hello(): + with connect("ws://localhost:8765") as websocket: + websocket.send("Hello world!") + message = websocket.recv() + print(f"Received: {message}") + + hello() + + +Does that look good? + +`Get started with the tutorial! `_ + +Why should I use ``websockets``? +-------------------------------- + +The development of ``websockets`` is shaped by four principles: + +1. **Correctness**: ``websockets`` is heavily tested for compliance with + :rfc:`6455`. Continuous integration fails under 100% branch coverage. + +2. **Simplicity**: all you need to understand is ``msg = await ws.recv()`` and + ``await ws.send(msg)``. ``websockets`` takes care of managing connections + so you can focus on your application. + +3. **Robustness**: ``websockets`` is built for production. For example, it was + the only library to `handle backpressure correctly`_ before the issue + became widely known in the Python community. + +4. **Performance**: memory usage is optimized and configurable. A C extension + accelerates expensive operations. It's pre-compiled for Linux, macOS and + Windows and packaged in the wheel format for each system and Python version. + +Documentation is a first class concern in the project. Head over to `Read the +Docs`_ and see for yourself. + +.. _Read the Docs: https://websockets.readthedocs.io/ +.. _handle backpressure correctly: https://vorpus.org/blog/some-thoughts-on-asynchronous-api-design-in-a-post-asyncawait-world/#websocket-servers + +Why shouldn't I use ``websockets``? +----------------------------------- + +* If you prefer callbacks over coroutines: ``websockets`` was created to + provide the best coroutine-based API to manage WebSocket connections in + Python. Pick another library for a callback-based API. + +* If you're looking for a mixed HTTP / WebSocket library: ``websockets`` aims + at being an excellent implementation of :rfc:`6455`: The WebSocket Protocol + and :rfc:`7692`: Compression Extensions for WebSocket. Its support for HTTP + is minimal β€” just enough for an HTTP health check. + + If you want to do both in the same server, look at HTTP + WebSocket servers + that build on top of ``websockets`` to support WebSocket connections, like + uvicorn_ or Sanic_. + +.. _uvicorn: https://www.uvicorn.org/ +.. _Sanic: https://sanic.dev/en/ + +What else? +---------- + +Bug reports, patches and suggestions are welcome! + +To report a security vulnerability, please use the `Tidelift security +contact`_. Tidelift will coordinate the fix and disclosure. + +.. _Tidelift security contact: https://tidelift.com/security + +For anything else, please open an issue_ or send a `pull request`_. + +.. _issue: https://github.com/python-websockets/websockets/issues/new +.. _pull request: https://github.com/python-websockets/websockets/compare/ + +Participants must uphold the `Contributor Covenant code of conduct`_. + +.. _Contributor Covenant code of conduct: https://github.com/python-websockets/websockets/blob/main/CODE_OF_CONDUCT.md + +``websockets`` is released under the `BSD license`_. + +.. _BSD license: https://github.com/python-websockets/websockets/blob/main/LICENSE diff --git a/.venv/Lib/site-packages/websockets-16.1.dist-info/RECORD b/.venv/Lib/site-packages/websockets-16.1.dist-info/RECORD new file mode 100644 index 0000000000000000000000000000000000000000..09485c3d2fe1c8b0005bd1a0b410d8ac300076a8 --- /dev/null +++ b/.venv/Lib/site-packages/websockets-16.1.dist-info/RECORD @@ -0,0 +1,108 @@ +../../Scripts/websockets.exe,sha256=HiLwOnn4vwO3nazuaC8Nf8U6Xrs2l-wW24JNmKTsh7A,108464 +websockets-16.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +websockets-16.1.dist-info/METADATA,sha256=gS1X-c0eX9dKZwdeRLvSC1Fq9OiCeEndyDy-gnC70us,6978 +websockets-16.1.dist-info/RECORD,, +websockets-16.1.dist-info/WHEEL,sha256=92f7vyHE_GZiwRnD2I05vCT_S39UvkRyuguYDAKOGb8,101 +websockets-16.1.dist-info/entry_points.txt,sha256=Dnhn4dm5EsI4ZMAsHldGF6CwBXZrGXnR7cnK2-XR7zY,51 +websockets-16.1.dist-info/licenses/LICENSE,sha256=D0RRSZisognTSC0QIEqK3yqkKW_xV6NqXAki8igGMtM,1538 +websockets-16.1.dist-info/top_level.txt,sha256=CMpdKklxKsvZgCgyltxUWOHibZXZ1uYIVpca9xsQ8Hk,11 +websockets/__init__.py,sha256=gnZ1a8qhrWVVClaf7lGqkSVQAPPm-cSZ3k3525fozaY,7294 +websockets/__main__.py,sha256=h1QpgvR08tO6TfQHuySKKgQiQVXVIoQRKLEx5sVht_M,67 +websockets/__pycache__/__init__.cpython-312.pyc,, +websockets/__pycache__/__main__.cpython-312.pyc,, +websockets/__pycache__/auth.cpython-312.pyc,, +websockets/__pycache__/cli.cpython-312.pyc,, +websockets/__pycache__/client.cpython-312.pyc,, +websockets/__pycache__/connection.cpython-312.pyc,, +websockets/__pycache__/datastructures.cpython-312.pyc,, +websockets/__pycache__/exceptions.cpython-312.pyc,, +websockets/__pycache__/frames.cpython-312.pyc,, +websockets/__pycache__/headers.cpython-312.pyc,, +websockets/__pycache__/http.cpython-312.pyc,, +websockets/__pycache__/http11.cpython-312.pyc,, +websockets/__pycache__/imports.cpython-312.pyc,, +websockets/__pycache__/protocol.cpython-312.pyc,, +websockets/__pycache__/proxy.cpython-312.pyc,, +websockets/__pycache__/server.cpython-312.pyc,, +websockets/__pycache__/streams.cpython-312.pyc,, +websockets/__pycache__/typing.cpython-312.pyc,, +websockets/__pycache__/uri.cpython-312.pyc,, +websockets/__pycache__/utils.cpython-312.pyc,, +websockets/__pycache__/version.cpython-312.pyc,, +websockets/asyncio/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +websockets/asyncio/__pycache__/__init__.cpython-312.pyc,, +websockets/asyncio/__pycache__/async_timeout.cpython-312.pyc,, +websockets/asyncio/__pycache__/client.cpython-312.pyc,, +websockets/asyncio/__pycache__/compatibility.cpython-312.pyc,, +websockets/asyncio/__pycache__/connection.cpython-312.pyc,, +websockets/asyncio/__pycache__/messages.cpython-312.pyc,, +websockets/asyncio/__pycache__/router.cpython-312.pyc,, +websockets/asyncio/__pycache__/server.cpython-312.pyc,, +websockets/asyncio/async_timeout.py,sha256=jMKMQcVKWtn09n6lqefqdpSYoMRlP4Ek60RjJ6B6Eco,9253 +websockets/asyncio/client.py,sha256=g0N4kYlROTuOyS-rU_YhbprrOC9x_FTJ7LQCxqonMHo,32162 +websockets/asyncio/compatibility.py,sha256=ld5lpbBgJ8YGAi3tc1hMiIxuLeQWDg6pKDYBVbSQMl4,816 +websockets/asyncio/connection.py,sha256=Y-tLFQVXcW0_52GKZvDxKomW7_qpGuN8Ngnx0RYdrnI,51166 +websockets/asyncio/messages.py,sha256=5pvFEis6dP0xGLmotFZGxoPJ1rl9i7k1s85i_Ha4TrY,11445 +websockets/asyncio/router.py,sha256=98y3YRKtWomjfocLPYz4jGwU6bvL9TN4eAlyvKmUJro,7739 +websockets/asyncio/server.py,sha256=G0cSJSp63u37S7cUPmhEJWPdVil7NFDtCXRzIQVxzFU,38938 +websockets/auth.py,sha256=NZ60zoE10wklboBHzj4Wof9piVB09jO1bDn_KHN8ZcE,586 +websockets/cli.py,sha256=OvOQljnMqxdpvpHzFJsxt_T24XbSQJst5sU0gZjWp10,6236 +websockets/client.py,sha256=He7BIvvTGzYbHmp6H31P64wLgGRIAtp87Cht0wdo_qI,14180 +websockets/connection.py,sha256=uIRi5jeS3zVIWq8DcEDJPousrYNTItPe0ioKxBr2hOs,335 +websockets/datastructures.py,sha256=JaPna2SP6zi3cSJ8067m2GmIOmBVwPuDVpMXZPj5JZA,6329 +websockets/exceptions.py,sha256=pyrzbaJrSdmwd0PrUKhYNRfFKWOcWR93RphctQzKNj8,13332 +websockets/extensions/__init__.py,sha256=HdQaQhOVkCR5RJVRKXG5Xmb6cMpAhLaKgRikYRzO64E,102 +websockets/extensions/__pycache__/__init__.cpython-312.pyc,, +websockets/extensions/__pycache__/base.cpython-312.pyc,, +websockets/extensions/__pycache__/permessage_deflate.cpython-312.pyc,, +websockets/extensions/base.py,sha256=Je1VMBHq7_gqq5idsCqMPD87CI6m7zpDSRj_lCL37Rc,3026 +websockets/extensions/permessage_deflate.py,sha256=ajutevKOhw678Vk3niHfVnbNyLdv1Koeu9kJ6m6adsY,26602 +websockets/frames.py,sha256=xdSTdF1n5wwIIY1UmK_5eEQISVJLqPJRB5TzaH0uruw,17443 +websockets/headers.py,sha256=2XFbUE0BzEIftBR2KS2ygeSRIYzPB-a-q35jfdcZ1MA,16632 +websockets/http.py,sha256=pQmdzRiYK_SuiwvXIrP_rsJZAj8tGIol76e_TvsPUrg,679 +websockets/http11.py,sha256=7YUFyVNAqvmYlLUWnqBcFDmG5Q5mg_KMzYEQJwtxPpM,16660 +websockets/imports.py,sha256=oFdWkxypj_diuqneRuA5OWEXLMQ6pAtj-rKqFU6Pmdg,2895 +websockets/legacy/__init__.py,sha256=VS5mRP7oS3kXCcXX7F3vPULmXPFi4VcyKbnv8Lk18MY,287 +websockets/legacy/__pycache__/__init__.cpython-312.pyc,, +websockets/legacy/__pycache__/auth.cpython-312.pyc,, +websockets/legacy/__pycache__/client.cpython-312.pyc,, +websockets/legacy/__pycache__/exceptions.cpython-312.pyc,, +websockets/legacy/__pycache__/framing.cpython-312.pyc,, +websockets/legacy/__pycache__/handshake.cpython-312.pyc,, +websockets/legacy/__pycache__/http.cpython-312.pyc,, +websockets/legacy/__pycache__/protocol.cpython-312.pyc,, +websockets/legacy/__pycache__/server.cpython-312.pyc,, +websockets/legacy/auth.py,sha256=wILIJE28YsQKmQcWdPMzmdM_0Sw674dqUo2XGqyUvH4,6721 +websockets/legacy/client.py,sha256=j2qpkzkQWVYBTJQKsAqOJHCImUQQay4eMqipofyrG5Y,28092 +websockets/legacy/exceptions.py,sha256=KrvUEI31DUZs3gl6M-Q-dgsSnsMXzU_bDRuHU6AcKbc,1995 +websockets/legacy/framing.py,sha256=X4UdahsxzmHaQ96Lc1h1JxYGQmldJ3lQATAIIBPMQ1s,6590 +websockets/legacy/handshake.py,sha256=CRRxkJ96TIgWuoMIL0iol4jp4X7llMA8buX4gfo0SwE,5443 +websockets/legacy/http.py,sha256=OPu_UljFJH74nxk5V-jnOOkqzdXcpJ6M0LynIpuZ740,7262 +websockets/legacy/protocol.py,sha256=OFcAFHJ8pFj74uNGIjbyeqSkUSXJhBwMfxdKFwBJQFA,65267 +websockets/legacy/server.py,sha256=Vaib6rEFl_Xkms8uQObh12u0ndomOiFkOLtNalRg-Vk,46442 +websockets/protocol.py,sha256=rmByeSbZrcEbAI2tuTTvGfKD7Sg7jnvwOuOr_sRtY88,28015 +websockets/proxy.py,sha256=Vx6ChvQlavAZ2DkzlmoEw5I5e7alDqBCISi_xZotAS0,5119 +websockets/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +websockets/server.py,sha256=vQdDh3m2Bkq754OYtC91IdkGwScTFsUexkyJtoq9p40,22379 +websockets/speedups.c,sha256=cWPv8E0JKXSneV8b732dwNEbyD5JWJKzyI5bqmGiXaY,6149 +websockets/speedups.cp312-win_amd64.pyd,sha256=9S4Q_ugcBLcUv5nMBs-oxX3IZbHGJApPkDMshOwp2lc,11264 +websockets/speedups.pyi,sha256=xJUwsMLc11sH19lvnxlmuwROSIxzQYdvN3Qt5zS0674,105 +websockets/streams.py,sha256=MXiB2d6mNsARFXdwXqVa2GHqb8wCxm0ncqtxPcdDFok,4222 +websockets/sync/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +websockets/sync/__pycache__/__init__.cpython-312.pyc,, +websockets/sync/__pycache__/client.cpython-312.pyc,, +websockets/sync/__pycache__/connection.cpython-312.pyc,, +websockets/sync/__pycache__/messages.cpython-312.pyc,, +websockets/sync/__pycache__/router.cpython-312.pyc,, +websockets/sync/__pycache__/server.cpython-312.pyc,, +websockets/sync/__pycache__/utils.cpython-312.pyc,, +websockets/sync/client.py,sha256=EOrmXS1WhebA6bsDxeJqOj0-SQjF6Z0Vnp5_DlUpPWE,22741 +websockets/sync/connection.py,sha256=tq-LYVnq4w9JIhkEZAUN3kxq4Soh4NK8fBkRPgTORdo,43008 +websockets/sync/messages.py,sha256=DIyybPDUiIzC6-uvSqc3U7FjDO1B6plAMPrZgaQf2d0,13206 +websockets/sync/router.py,sha256=TVsMXN0SIyiP5Sl9NxVC4Ovy-88FPbFQTGQVw5SjOYQ,7385 +websockets/sync/server.py,sha256=RkxGcOmPL9NhzBmjs_jACLG5On8o51ghp2wn3XY_Dzg,28420 +websockets/sync/utils.py,sha256=JgQVxO_NcQXZd8m6hDeXpSQ_uN6GYF8u9XLHZ7msv3k,1152 +websockets/typing.py,sha256=FUGyn9CqzlBNvfCTU0Gm75J0IKYxEFcWRyyKDpGTa6Q,2021 +websockets/uri.py,sha256=gohMr47baKGfjhydsaOE1sc8FH_7B8f10SdunNqY2p0,3232 +websockets/utils.py,sha256=_-f-crtqkFa__OUthSFKOWseCzSOqH15QSQFkjKsJrE,1416 +websockets/version.py,sha256=q7b4ijf7FeHL_jC8iDJ6F0o_GFKJD-jjplRmNEHUATU,3294 diff --git a/.venv/Lib/site-packages/websockets-16.1.dist-info/WHEEL b/.venv/Lib/site-packages/websockets-16.1.dist-info/WHEEL new file mode 100644 index 0000000000000000000000000000000000000000..5a3c3ddb13beca65d058226a14c8ecd42ebd1030 --- /dev/null +++ b/.venv/Lib/site-packages/websockets-16.1.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: setuptools (83.0.0) +Root-Is-Purelib: false +Tag: cp312-cp312-win_amd64 + diff --git a/.venv/Lib/site-packages/websockets-16.1.dist-info/entry_points.txt b/.venv/Lib/site-packages/websockets-16.1.dist-info/entry_points.txt new file mode 100644 index 0000000000000000000000000000000000000000..60cd61ca0074591bf4dd607f11ee22310a3daab4 --- /dev/null +++ b/.venv/Lib/site-packages/websockets-16.1.dist-info/entry_points.txt @@ -0,0 +1,2 @@ +[console_scripts] +websockets = websockets.cli:main diff --git a/.venv/Lib/site-packages/websockets-16.1.dist-info/licenses/LICENSE b/.venv/Lib/site-packages/websockets-16.1.dist-info/licenses/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..737391524fbd8fd489087e9ff3ee1b24c1070e83 --- /dev/null +++ b/.venv/Lib/site-packages/websockets-16.1.dist-info/licenses/LICENSE @@ -0,0 +1,24 @@ +Copyright (c) Aymeric Augustin and contributors + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/.venv/Lib/site-packages/websockets-16.1.dist-info/top_level.txt b/.venv/Lib/site-packages/websockets-16.1.dist-info/top_level.txt new file mode 100644 index 0000000000000000000000000000000000000000..14774b465e97f655dbcaa60d97c8a9aa72e7d51b --- /dev/null +++ b/.venv/Lib/site-packages/websockets-16.1.dist-info/top_level.txt @@ -0,0 +1 @@ +websockets diff --git a/.venv/Lib/site-packages/websockets/__init__.py b/.venv/Lib/site-packages/websockets/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..de677b8f9c0da920e26f9e413c409c9ee4e49e27 --- /dev/null +++ b/.venv/Lib/site-packages/websockets/__init__.py @@ -0,0 +1,236 @@ +from __future__ import annotations + +# Importing the typing module would conflict with websockets.typing. +from typing import TYPE_CHECKING + +from .imports import lazy_import +from .version import version as __version__ # noqa: F401 + + +__all__ = [ + # .asyncio.client + "connect", + "unix_connect", + "ClientConnection", + # .asyncio.router + "route", + "unix_route", + "Router", + # .asyncio.server + "basic_auth", + "broadcast", + "serve", + "unix_serve", + "ServerConnection", + "Server", + # .client + "ClientProtocol", + # .datastructures + "Headers", + "HeadersLike", + "MultipleValuesError", + # .exceptions + "ConcurrencyError", + "ConnectionClosed", + "ConnectionClosedError", + "ConnectionClosedOK", + "DuplicateParameter", + "InvalidHandshake", + "InvalidHeader", + "InvalidHeaderFormat", + "InvalidHeaderValue", + "InvalidMessage", + "InvalidOrigin", + "InvalidParameterName", + "InvalidParameterValue", + "InvalidProxy", + "InvalidProxyMessage", + "InvalidProxyStatus", + "InvalidState", + "InvalidStatus", + "InvalidUpgrade", + "InvalidURI", + "NegotiationError", + "PayloadTooBig", + "ProtocolError", + "ProxyError", + "SecurityError", + "WebSocketException", + # .frames + "Close", + "CloseCode", + "Frame", + "Opcode", + # .http11 + "Request", + "Response", + # .protocol + "Protocol", + "Side", + "State", + # .server + "ServerProtocol", + # .typing + "Data", + "ExtensionName", + "ExtensionParameter", + "LoggerLike", + "StatusLike", + "Origin", + "Subprotocol", +] + +# When type checking, import non-deprecated aliases eagerly. Else, import on demand. +if TYPE_CHECKING: + from .asyncio.client import ClientConnection, connect, unix_connect + from .asyncio.router import Router, route, unix_route + from .asyncio.server import ( + Server, + ServerConnection, + basic_auth, + broadcast, + serve, + unix_serve, + ) + from .client import ClientProtocol + from .datastructures import Headers, HeadersLike, MultipleValuesError + from .exceptions import ( + ConcurrencyError, + ConnectionClosed, + ConnectionClosedError, + ConnectionClosedOK, + DuplicateParameter, + InvalidHandshake, + InvalidHeader, + InvalidHeaderFormat, + InvalidHeaderValue, + InvalidMessage, + InvalidOrigin, + InvalidParameterName, + InvalidParameterValue, + InvalidProxy, + InvalidProxyMessage, + InvalidProxyStatus, + InvalidState, + InvalidStatus, + InvalidUpgrade, + InvalidURI, + NegotiationError, + PayloadTooBig, + ProtocolError, + ProxyError, + SecurityError, + WebSocketException, + ) + from .frames import Close, CloseCode, Frame, Opcode + from .http11 import Request, Response + from .protocol import Protocol, Side, State + from .server import ServerProtocol + from .typing import ( + Data, + ExtensionName, + ExtensionParameter, + LoggerLike, + Origin, + StatusLike, + Subprotocol, + ) +else: + lazy_import( + globals(), + aliases={ + # .asyncio.client + "connect": ".asyncio.client", + "unix_connect": ".asyncio.client", + "ClientConnection": ".asyncio.client", + # .asyncio.router + "route": ".asyncio.router", + "unix_route": ".asyncio.router", + "Router": ".asyncio.router", + # .asyncio.server + "basic_auth": ".asyncio.server", + "broadcast": ".asyncio.server", + "serve": ".asyncio.server", + "unix_serve": ".asyncio.server", + "ServerConnection": ".asyncio.server", + "Server": ".asyncio.server", + # .client + "ClientProtocol": ".client", + # .datastructures + "Headers": ".datastructures", + "HeadersLike": ".datastructures", + "MultipleValuesError": ".datastructures", + # .exceptions + "ConcurrencyError": ".exceptions", + "ConnectionClosed": ".exceptions", + "ConnectionClosedError": ".exceptions", + "ConnectionClosedOK": ".exceptions", + "DuplicateParameter": ".exceptions", + "InvalidHandshake": ".exceptions", + "InvalidHeader": ".exceptions", + "InvalidHeaderFormat": ".exceptions", + "InvalidHeaderValue": ".exceptions", + "InvalidMessage": ".exceptions", + "InvalidOrigin": ".exceptions", + "InvalidParameterName": ".exceptions", + "InvalidParameterValue": ".exceptions", + "InvalidProxy": ".exceptions", + "InvalidProxyMessage": ".exceptions", + "InvalidProxyStatus": ".exceptions", + "InvalidState": ".exceptions", + "InvalidStatus": ".exceptions", + "InvalidUpgrade": ".exceptions", + "InvalidURI": ".exceptions", + "NegotiationError": ".exceptions", + "PayloadTooBig": ".exceptions", + "ProtocolError": ".exceptions", + "ProxyError": ".exceptions", + "SecurityError": ".exceptions", + "WebSocketException": ".exceptions", + # .frames + "Close": ".frames", + "CloseCode": ".frames", + "Frame": ".frames", + "Opcode": ".frames", + # .http11 + "Request": ".http11", + "Response": ".http11", + # .protocol + "Protocol": ".protocol", + "Side": ".protocol", + "State": ".protocol", + # .server + "ServerProtocol": ".server", + # .typing + "Data": ".typing", + "ExtensionName": ".typing", + "ExtensionParameter": ".typing", + "LoggerLike": ".typing", + "Origin": ".typing", + "StatusLike": ".typing", + "Subprotocol": ".typing", + }, + deprecated_aliases={ + # deprecated in 9.0 - 2021-09-01 + "framing": ".legacy", + "handshake": ".legacy", + "parse_uri": ".uri", + "WebSocketURI": ".uri", + # deprecated in 14.0 - 2024-11-09 + # .legacy.auth + "BasicAuthWebSocketServerProtocol": ".legacy.auth", + "basic_auth_protocol_factory": ".legacy.auth", + # .legacy.client + "WebSocketClientProtocol": ".legacy.client", + # .legacy.exceptions + "AbortHandshake": ".legacy.exceptions", + "InvalidStatusCode": ".legacy.exceptions", + "RedirectHandshake": ".legacy.exceptions", + "WebSocketProtocolError": ".legacy.exceptions", + # .legacy.protocol + "WebSocketCommonProtocol": ".legacy.protocol", + # .legacy.server + "WebSocketServer": ".legacy.server", + "WebSocketServerProtocol": ".legacy.server", + }, + ) diff --git a/.venv/Lib/site-packages/websockets/__main__.py b/.venv/Lib/site-packages/websockets/__main__.py new file mode 100644 index 0000000000000000000000000000000000000000..e1cbc62e37e5e4cfdce0525a06ff496936cb6afb --- /dev/null +++ b/.venv/Lib/site-packages/websockets/__main__.py @@ -0,0 +1,5 @@ +from .cli import main + + +if __name__ == "__main__": + main() diff --git a/.venv/Lib/site-packages/websockets/asyncio/__init__.py b/.venv/Lib/site-packages/websockets/asyncio/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/.venv/Lib/site-packages/websockets/asyncio/async_timeout.py b/.venv/Lib/site-packages/websockets/asyncio/async_timeout.py new file mode 100644 index 0000000000000000000000000000000000000000..3e5b9a0486861da034d15d5e692831d87f45535a --- /dev/null +++ b/.venv/Lib/site-packages/websockets/asyncio/async_timeout.py @@ -0,0 +1,282 @@ +# From https://github.com/aio-libs/async-timeout/blob/master/async_timeout/__init__.py +# Licensed under the Apache License (Apache-2.0) + +import asyncio +import enum +import sys +import warnings +from types import TracebackType +from typing import Optional, Type + + +if sys.version_info >= (3, 11): + from typing import final +else: + # From https://github.com/python/typing_extensions/blob/main/src/typing_extensions.py + # Licensed under the Python Software Foundation License (PSF-2.0) + + # @final exists in 3.8+, but we backport it for all versions + # before 3.11 to keep support for the __final__ attribute. + # See https://bugs.python.org/issue46342 + def final(f): + """This decorator can be used to indicate to type checkers that + the decorated method cannot be overridden, and decorated class + cannot be subclassed. For example: + + class Base: + @final + def done(self) -> None: + ... + class Sub(Base): + def done(self) -> None: # Error reported by type checker + ... + @final + class Leaf: + ... + class Other(Leaf): # Error reported by type checker + ... + + There is no runtime checking of these properties. The decorator + sets the ``__final__`` attribute to ``True`` on the decorated object + to allow runtime introspection. + """ + try: + f.__final__ = True + except (AttributeError, TypeError): + # Skip the attribute silently if it is not writable. + # AttributeError happens if the object has __slots__ or a + # read-only property, TypeError if it's a builtin class. + pass + return f + + # End https://github.com/python/typing_extensions/blob/main/src/typing_extensions.py + + +if sys.version_info >= (3, 11): + + def _uncancel_task(task: "asyncio.Task[object]") -> None: + task.uncancel() + +else: + + def _uncancel_task(task: "asyncio.Task[object]") -> None: + pass + + +__version__ = "4.0.3" + + +__all__ = ("timeout", "timeout_at", "Timeout") + + +def timeout(delay: Optional[float]) -> "Timeout": + """timeout context manager. + + Useful in cases when you want to apply timeout logic around block + of code or in cases when asyncio.wait_for is not suitable. For example: + + >>> async with timeout(0.001): + ... async with aiohttp.get('https://github.com') as r: + ... await r.text() + + + delay - value in seconds or None to disable timeout logic + """ + loop = asyncio.get_running_loop() + if delay is not None: + deadline = loop.time() + delay # type: Optional[float] + else: + deadline = None + return Timeout(deadline, loop) + + +def timeout_at(deadline: Optional[float]) -> "Timeout": + """Schedule the timeout at absolute time. + + deadline argument points on the time in the same clock system + as loop.time(). + + Please note: it is not POSIX time but a time with + undefined starting base, e.g. the time of the system power on. + + >>> async with timeout_at(loop.time() + 10): + ... async with aiohttp.get('https://github.com') as r: + ... await r.text() + + + """ + loop = asyncio.get_running_loop() + return Timeout(deadline, loop) + + +class _State(enum.Enum): + INIT = "INIT" + ENTER = "ENTER" + TIMEOUT = "TIMEOUT" + EXIT = "EXIT" + + +@final +class Timeout: + # Internal class, please don't instantiate it directly + # Use timeout() and timeout_at() public factories instead. + # + # Implementation note: `async with timeout()` is preferred + # over `with timeout()`. + # While technically the Timeout class implementation + # doesn't need to be async at all, + # the `async with` statement explicitly points that + # the context manager should be used from async function context. + # + # This design allows to avoid many silly misusages. + # + # TimeoutError is raised immediately when scheduled + # if the deadline is passed. + # The purpose is to time out as soon as possible + # without waiting for the next await expression. + + __slots__ = ("_deadline", "_loop", "_state", "_timeout_handler", "_task") + + def __init__( + self, deadline: Optional[float], loop: asyncio.AbstractEventLoop + ) -> None: + self._loop = loop + self._state = _State.INIT + + self._task: Optional["asyncio.Task[object]"] = None + self._timeout_handler = None # type: Optional[asyncio.Handle] + if deadline is None: + self._deadline = None # type: Optional[float] + else: + self.update(deadline) + + def __enter__(self) -> "Timeout": + warnings.warn( + "with timeout() is deprecated, use async with timeout() instead", + DeprecationWarning, + stacklevel=2, + ) + self._do_enter() + return self + + def __exit__( + self, + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType], + ) -> Optional[bool]: + self._do_exit(exc_type) + return None + + async def __aenter__(self) -> "Timeout": + self._do_enter() + return self + + async def __aexit__( + self, + exc_type: Optional[Type[BaseException]], + exc_val: Optional[BaseException], + exc_tb: Optional[TracebackType], + ) -> Optional[bool]: + self._do_exit(exc_type) + return None + + @property + def expired(self) -> bool: + """Is timeout expired during execution?""" + return self._state == _State.TIMEOUT + + @property + def deadline(self) -> Optional[float]: + return self._deadline + + def reject(self) -> None: + """Reject scheduled timeout if any.""" + # cancel is maybe better name but + # task.cancel() raises CancelledError in asyncio world. + if self._state not in (_State.INIT, _State.ENTER): + raise RuntimeError(f"invalid state {self._state.value}") + self._reject() + + def _reject(self) -> None: + self._task = None + if self._timeout_handler is not None: + self._timeout_handler.cancel() + self._timeout_handler = None + + def shift(self, delay: float) -> None: + """Advance timeout on delay seconds. + + The delay can be negative. + + Raise RuntimeError if shift is called when deadline is not scheduled + """ + deadline = self._deadline + if deadline is None: + raise RuntimeError("cannot shift timeout if deadline is not scheduled") + self.update(deadline + delay) + + def update(self, deadline: float) -> None: + """Set deadline to absolute value. + + deadline argument points on the time in the same clock system + as loop.time(). + + If new deadline is in the past the timeout is raised immediately. + + Please note: it is not POSIX time but a time with + undefined starting base, e.g. the time of the system power on. + """ + if self._state == _State.EXIT: + raise RuntimeError("cannot reschedule after exit from context manager") + if self._state == _State.TIMEOUT: + raise RuntimeError("cannot reschedule expired timeout") + if self._timeout_handler is not None: + self._timeout_handler.cancel() + self._deadline = deadline + if self._state != _State.INIT: + self._reschedule() + + def _reschedule(self) -> None: + assert self._state == _State.ENTER + deadline = self._deadline + if deadline is None: + return + + now = self._loop.time() + if self._timeout_handler is not None: + self._timeout_handler.cancel() + + self._task = asyncio.current_task() + if deadline <= now: + self._timeout_handler = self._loop.call_soon(self._on_timeout) + else: + self._timeout_handler = self._loop.call_at(deadline, self._on_timeout) + + def _do_enter(self) -> None: + if self._state != _State.INIT: + raise RuntimeError(f"invalid state {self._state.value}") + self._state = _State.ENTER + self._reschedule() + + def _do_exit(self, exc_type: Optional[Type[BaseException]]) -> None: + if exc_type is asyncio.CancelledError and self._state == _State.TIMEOUT: + assert self._task is not None + _uncancel_task(self._task) + self._timeout_handler = None + self._task = None + raise asyncio.TimeoutError + # timeout has not expired + self._state = _State.EXIT + self._reject() + return None + + def _on_timeout(self) -> None: + assert self._task is not None + self._task.cancel() + self._state = _State.TIMEOUT + # drop the reference early + self._timeout_handler = None + + +# End https://github.com/aio-libs/async-timeout/blob/master/async_timeout/__init__.py diff --git a/.venv/Lib/site-packages/websockets/asyncio/client.py b/.venv/Lib/site-packages/websockets/asyncio/client.py new file mode 100644 index 0000000000000000000000000000000000000000..46321c8bf93ea6da6f7010c6d15682bc08dd43a4 --- /dev/null +++ b/.venv/Lib/site-packages/websockets/asyncio/client.py @@ -0,0 +1,815 @@ +from __future__ import annotations + +import asyncio +import logging +import os +import socket +import ssl as ssl_module +import traceback +import urllib.parse +from collections.abc import AsyncIterator, Generator, Sequence +from types import TracebackType +from typing import Any, Callable, Literal, cast + +from ..client import ClientProtocol, backoff +from ..datastructures import Headers, HeadersLike +from ..exceptions import ( + InvalidMessage, + InvalidProxyMessage, + InvalidProxyStatus, + InvalidStatus, + ProxyError, + SecurityError, +) +from ..extensions.base import ClientExtensionFactory +from ..extensions.permessage_deflate import enable_client_permessage_deflate +from ..headers import validate_subprotocols +from ..http11 import USER_AGENT, Response +from ..protocol import CONNECTING, Event +from ..proxy import Proxy, get_proxy, parse_proxy, prepare_connect_request +from ..streams import StreamReader +from ..typing import LoggerLike, Origin, Subprotocol +from ..uri import WebSocketURI, parse_uri +from .compatibility import TimeoutError, asyncio_timeout +from .connection import Connection + + +__all__ = ["connect", "unix_connect", "ClientConnection"] + +MAX_REDIRECTS = int(os.environ.get("WEBSOCKETS_MAX_REDIRECTS", "10")) + + +class ClientConnection(Connection): + """ + :mod:`asyncio` implementation of a WebSocket client connection. + + :class:`ClientConnection` provides :meth:`recv` and :meth:`send` coroutines + for receiving and sending messages. + + It supports asynchronous iteration to receive messages:: + + async for message in websocket: + await process(message) + + The iterator exits normally when the connection is closed with code + 1000 (OK) or 1001 (going away) or without a close code. It raises a + :exc:`~websockets.exceptions.ConnectionClosedError` when the connection is + closed with any other code. + + The ``ping_interval``, ``ping_timeout``, ``close_timeout``, ``max_queue``, + and ``write_limit`` arguments have the same meaning as in :func:`connect`. + + Args: + protocol: Sans-I/O connection. + + """ + + def __init__( + self, + protocol: ClientProtocol, + *, + ping_interval: float | None = 20, + ping_timeout: float | None = 20, + close_timeout: float | None = 10, + max_queue: int | None | tuple[int | None, int | None] = 16, + write_limit: int | tuple[int, int | None] = 2**15, + ) -> None: + self.protocol: ClientProtocol + super().__init__( + protocol, + ping_interval=ping_interval, + ping_timeout=ping_timeout, + close_timeout=close_timeout, + max_queue=max_queue, + write_limit=write_limit, + ) + self.response_rcvd: asyncio.Future[None] = self.loop.create_future() + + async def handshake( + self, + additional_headers: HeadersLike | None = None, + user_agent_header: str | None = USER_AGENT, + ) -> None: + """ + Perform the opening handshake. + + """ + async with self.send_context(expected_state=CONNECTING): + self.request = self.protocol.connect() + if additional_headers is not None: + self.request.headers.update(additional_headers) + if user_agent_header is not None: + self.request.headers.setdefault("User-Agent", user_agent_header) + self.protocol.send_request(self.request) + + await asyncio.wait( + [self.response_rcvd, self.connection_lost_waiter], + return_when=asyncio.FIRST_COMPLETED, + ) + + # self.protocol.handshake_exc is set when the connection is lost before + # receiving a response, when the response cannot be parsed, or when the + # response fails the handshake. + + if self.protocol.handshake_exc is not None: + raise self.protocol.handshake_exc + + def process_event(self, event: Event) -> None: + """ + Process one incoming event. + + """ + # First event - handshake response. + if self.response is None: + assert isinstance(event, Response) + self.response = event + self.response_rcvd.set_result(None) + # Later events - frames. + else: + super().process_event(event) + + +def process_exception(exc: Exception) -> Exception | None: + """ + Determine whether a connection error is retryable or fatal. + + When reconnecting automatically with ``async for ... in connect(...)``, if a + connection attempt fails, :func:`process_exception` is called to determine + whether to retry connecting or to raise the exception. + + This function defines the default behavior, which is to retry on: + + * :exc:`EOFError`, :exc:`OSError`, :exc:`asyncio.TimeoutError`: network + errors; + * :exc:`~websockets.exceptions.InvalidStatus` when the status code is 500, + 502, 503, or 504: server or proxy errors. + + All other exceptions are considered fatal. + + You can change this behavior with the ``process_exception`` argument of + :func:`connect`. + + Return :obj:`None` if the exception is retryable i.e. when the error could + be transient and trying to reconnect with the same parameters could succeed. + The exception will be logged at the ``INFO`` level. + + Return an exception, either ``exc`` or a new exception, if the exception is + fatal i.e. when trying to reconnect will most likely produce the same error. + That exception will be raised, breaking out of the retry loop. + + """ + # This catches python-socks' ProxyConnectionError and ProxyTimeoutError. + # Remove asyncio.TimeoutError when dropping Python < 3.11. + if isinstance(exc, (OSError, TimeoutError, asyncio.TimeoutError)): + return None + if isinstance(exc, InvalidMessage) and isinstance(exc.__cause__, EOFError): + return None + if isinstance(exc, InvalidStatus) and exc.response.status_code in [ + 500, # Internal Server Error + 502, # Bad Gateway + 503, # Service Unavailable + 504, # Gateway Timeout + ]: + return None + return exc + + +# This is spelled in lower case because it's exposed as a callable in the API. +class connect: + """ + Connect to the WebSocket server at ``uri``. + + This coroutine returns a :class:`ClientConnection` instance, which you can + use to send and receive messages. + + :func:`connect` may be used as an asynchronous context manager:: + + from websockets.asyncio.client import connect + + async with connect(...) as websocket: + ... + + The connection is closed automatically when exiting the context. + + :func:`connect` can be used as an infinite asynchronous iterator to + reconnect automatically on errors:: + + async for websocket in connect(...): + try: + ... + except websockets.exceptions.ConnectionClosed: + continue + + If the connection fails with a transient error, it is retried with + exponential backoff. If it fails with a fatal error, the exception is + raised, breaking out of the loop. + + The connection is closed automatically after each iteration of the loop. + + Args: + uri: URI of the WebSocket server. + origin: Value of the ``Origin`` header, for servers that require it. + extensions: List of supported extensions, in order in which they + should be negotiated and run. + subprotocols: List of supported subprotocols, in order of decreasing + preference. + compression: The "permessage-deflate" extension is enabled by default. + Set ``compression`` to :obj:`None` to disable it. See the + :doc:`compression guide <../../topics/compression>` for details. + additional_headers (HeadersLike | None): Arbitrary HTTP headers to add + to the handshake request. + user_agent_header: Value of the ``User-Agent`` request header. + It defaults to ``"Python/x.y.z websockets/X.Y"``. + Setting it to :obj:`None` removes the header. + proxy: If a proxy is configured, it is used by default. Set ``proxy`` + to :obj:`None` to disable the proxy or to the address of a proxy + to override the system configuration. See the :doc:`proxy docs + <../../topics/proxies>` for details. + process_exception: When reconnecting automatically, tell whether an + error is transient or fatal. The default behavior is defined by + :func:`process_exception`. Refer to its documentation for details. + open_timeout: Timeout for opening the connection in seconds. + :obj:`None` disables the timeout. + ping_interval: Interval between keepalive pings in seconds. + :obj:`None` disables keepalive. + ping_timeout: Timeout for keepalive pings in seconds. + :obj:`None` disables timeouts. + close_timeout: Timeout for closing the connection in seconds. + :obj:`None` disables the timeout. + max_size: Maximum size of incoming messages in bytes. + :obj:`None` disables the limit. You may pass a ``(max_message_size, + max_fragment_size)`` tuple to set different limits for messages and + fragments when you expect long messages sent in short fragments. + max_queue: High-water mark of the buffer where frames are received. + It defaults to 16 frames. The low-water mark defaults to ``max_queue + // 4``. You may pass a ``(high, low)`` tuple to set the high-water + and low-water marks. If you want to disable flow control entirely, + you may set it to ``None``, although that's a bad idea. + write_limit: High-water mark of write buffer in bytes. It is passed to + :meth:`~asyncio.WriteTransport.set_write_buffer_limits`. It defaults + to 32Β KiB. You may pass a ``(high, low)`` tuple to set the + high-water and low-water marks. + logger: Logger for this client. + It defaults to ``logging.getLogger("websockets.client")``. + See the :doc:`logging guide <../../topics/logging>` for details. + create_connection: Factory for the :class:`ClientConnection` managing + the connection. Set it to a wrapper or a subclass to customize + connection handling. + + Any other keyword arguments are passed to the event loop's + :meth:`~asyncio.loop.create_connection` method. + + For example: + + * You can set ``ssl`` to a :class:`~ssl.SSLContext` to enforce TLS settings. + When connecting to a ``wss://`` URI, if ``ssl`` isn't provided, a TLS + context is created with :func:`~ssl.create_default_context`. + + * You can set ``server_hostname`` to override the host name from ``uri`` in + the TLS handshake. + + * You can set ``host`` and ``port`` to connect to a different host and port + from those found in ``uri``. This only changes the destination of the TCP + connection. The host name from ``uri`` is still used in the TLS handshake + for secure connections and in the ``Host`` header. + + * You can set ``sock`` to provide a preexisting TCP socket. You may call + :func:`socket.create_connection` (not to be confused with the event loop's + :meth:`~asyncio.loop.create_connection` method) to create a suitable + client socket and customize it. + + When using a proxy: + + * Prefix keyword arguments with ``proxy_`` for configuring TLS between the + client and an HTTPS proxy: ``proxy_ssl``, ``proxy_server_hostname``, + ``proxy_ssl_handshake_timeout``, and ``proxy_ssl_shutdown_timeout``. + * Use the standard keyword arguments for configuring TLS between the proxy + and the WebSocket server: ``ssl``, ``server_hostname``, + ``ssl_handshake_timeout``, and ``ssl_shutdown_timeout``. + * Other keyword arguments are used only for connecting to the proxy. + + Raises: + InvalidURI: If ``uri`` isn't a valid WebSocket URI. + InvalidProxy: If ``proxy`` isn't a valid proxy. + OSError: If the TCP connection fails. + InvalidHandshake: If the opening handshake fails. + TimeoutError: If the opening handshake times out. + + """ + + def __init__( + self, + uri: str, + *, + # WebSocket + origin: Origin | None = None, + extensions: Sequence[ClientExtensionFactory] | None = None, + subprotocols: Sequence[Subprotocol] | None = None, + compression: str | None = "deflate", + # HTTP + additional_headers: HeadersLike | None = None, + user_agent_header: str | None = USER_AGENT, + proxy: str | Literal[True] | None = True, + process_exception: Callable[[Exception], Exception | None] = process_exception, + # Timeouts + open_timeout: float | None = 10, + ping_interval: float | None = 20, + ping_timeout: float | None = 20, + close_timeout: float | None = 10, + # Limits + max_size: int | None | tuple[int | None, int | None] = 2**20, + max_queue: int | None | tuple[int | None, int | None] = 16, + write_limit: int | tuple[int, int | None] = 2**15, + # Logging + logger: LoggerLike | None = None, + # Escape hatch for advanced customization + create_connection: type[ClientConnection] | None = None, + # Other keyword arguments are passed to loop.create_connection + **kwargs: Any, + ) -> None: + self.uri = uri + + if subprotocols is not None: + validate_subprotocols(subprotocols) + + if compression == "deflate": + extensions = enable_client_permessage_deflate(extensions) + elif compression is not None: + raise ValueError(f"unsupported compression: {compression}") + + if logger is None: + logger = logging.getLogger("websockets.client") + + if create_connection is None: + create_connection = ClientConnection + + def protocol_factory(uri: WebSocketURI) -> ClientConnection: + # This is a protocol in the Sans-I/O implementation of websockets. + protocol = ClientProtocol( + uri, + origin=origin, + extensions=extensions, + subprotocols=subprotocols, + max_size=max_size, + logger=logger, + ) + # This is a connection in websockets and a protocol in asyncio. + connection = create_connection( + protocol, + ping_interval=ping_interval, + ping_timeout=ping_timeout, + close_timeout=close_timeout, + max_queue=max_queue, + write_limit=write_limit, + ) + return connection + + self.proxy = proxy + self.protocol_factory = protocol_factory + self.additional_headers = additional_headers + self.user_agent_header = user_agent_header + self.process_exception = process_exception + self.open_timeout = open_timeout + self.logger = logger + self.connection_kwargs = kwargs + + async def create_connection(self) -> ClientConnection: + """Create TCP or Unix connection.""" + loop = asyncio.get_running_loop() + kwargs = self.connection_kwargs.copy() + + ws_uri = parse_uri(self.uri) + + proxy = self.proxy + if kwargs.get("unix", False): + proxy = None + if kwargs.get("sock") is not None: + proxy = None + if proxy is True: + proxy = get_proxy(ws_uri) + + def factory() -> ClientConnection: + return self.protocol_factory(ws_uri) + + if ws_uri.secure: + kwargs.setdefault("ssl", True) + kwargs.setdefault("server_hostname", ws_uri.host) + if kwargs.get("ssl") is None: + raise ValueError("ssl=None is incompatible with a wss:// URI") + else: + if kwargs.get("ssl") is not None: + raise ValueError("ssl argument is incompatible with a ws:// URI") + + if kwargs.pop("unix", False): + _, connection = await loop.create_unix_connection(factory, **kwargs) + elif proxy is not None: + proxy_parsed = parse_proxy(proxy) + if proxy_parsed.scheme[:5] == "socks": + # Connect to the server through the proxy. + sock = await connect_socks_proxy( + proxy_parsed, + ws_uri, + local_addr=kwargs.pop("local_addr", None), + ) + # Initialize WebSocket connection via the proxy. + _, connection = await loop.create_connection( + factory, + sock=sock, + **kwargs, + ) + elif proxy_parsed.scheme[:4] == "http": + # Split keyword arguments between the proxy and the server. + all_kwargs, proxy_kwargs, kwargs = kwargs, {}, {} + for key, value in all_kwargs.items(): + if key.startswith("ssl") or key == "server_hostname": + kwargs[key] = value + elif key.startswith("proxy_"): + proxy_kwargs[key[6:]] = value + else: + proxy_kwargs[key] = value + # Validate the proxy_ssl argument. + if proxy_parsed.scheme == "https": + proxy_kwargs.setdefault("ssl", True) + if proxy_kwargs.get("ssl") is None: + raise ValueError( + "proxy_ssl=None is incompatible with an https:// proxy" + ) + else: + if proxy_kwargs.get("ssl") is not None: + raise ValueError( + "proxy_ssl argument is incompatible with an http:// proxy" + ) + # Connect to the server through the proxy. + transport = await connect_http_proxy( + proxy_parsed, + ws_uri, + user_agent_header=self.user_agent_header, + **proxy_kwargs, + ) + # Initialize WebSocket connection via the proxy. + connection = factory() + transport.set_protocol(connection) + ssl = kwargs.pop("ssl", None) + if ssl is True: + ssl = ssl_module.create_default_context() + if ssl is not None: + new_transport = await loop.start_tls( + transport, connection, ssl, **kwargs + ) + assert new_transport is not None # help mypy + transport = new_transport + connection.connection_made(transport) + else: + raise AssertionError("unsupported proxy") + else: + # Connect to the server directly. + if kwargs.get("sock") is None: + kwargs.setdefault("host", ws_uri.host) + kwargs.setdefault("port", ws_uri.port) + # Initialize WebSocket connection. + _, connection = await loop.create_connection(factory, **kwargs) + return connection + + def process_redirect(self, exc: Exception) -> Exception | str: + """ + Determine whether a connection error is a redirect that can be followed. + + Return the new URI if it's a valid redirect. Else, return an exception. + + """ + if not ( + isinstance(exc, InvalidStatus) + and exc.response.status_code + in [ + 300, # Multiple Choices + 301, # Moved Permanently + 302, # Found + 303, # See Other + 307, # Temporary Redirect + 308, # Permanent Redirect + ] + and "Location" in exc.response.headers + ): + return exc + + old_ws_uri = parse_uri(self.uri) + new_uri = urllib.parse.urljoin(self.uri, exc.response.headers["Location"]) + new_ws_uri = parse_uri(new_uri) + + # If connect() received a socket, it is closed and cannot be reused. + if self.connection_kwargs.get("sock") is not None: + return ValueError( + f"cannot follow redirect to {new_uri} with a preexisting socket" + ) + + # TLS downgrade is forbidden. + if old_ws_uri.secure and not new_ws_uri.secure: + return SecurityError(f"cannot follow redirect to non-secure URI {new_uri}") + + # Apply restrictions to cross-origin redirects. + if ( + old_ws_uri.secure != new_ws_uri.secure + or old_ws_uri.host != new_ws_uri.host + or old_ws_uri.port != new_ws_uri.port + ): + # Cross-origin redirects on Unix sockets don't quite make sense. + if self.connection_kwargs.get("unix", False): + return ValueError( + f"cannot follow cross-origin redirect to {new_uri} " + f"with a Unix socket" + ) + + # Cross-origin redirects when host and port are overridden are ill-defined. + if ( + self.connection_kwargs.get("host") is not None + or self.connection_kwargs.get("port") is not None + ): + return ValueError( + f"cannot follow cross-origin redirect to {new_uri} " + f"with an explicit host or port" + ) + + # Strip credentials to avoid leaking them to a different origin. + if self.additional_headers is not None: + self.additional_headers = Headers( + ( + (key, value) + for key, value in Headers(self.additional_headers).raw_items() + if key.lower() + not in ["authorization", "cookie", "proxy-authorization"] + ) + ) + + return new_uri + + # ... = await connect(...) + + def __await__(self) -> Generator[Any, None, ClientConnection]: + # Create a suitable iterator by calling __await__ on a coroutine. + return self.__await_impl__().__await__() + + async def __await_impl__(self) -> ClientConnection: + try: + async with asyncio_timeout(self.open_timeout): + for _ in range(MAX_REDIRECTS): + self.connection = await self.create_connection() + try: + await self.connection.handshake( + self.additional_headers, + self.user_agent_header, + ) + except asyncio.CancelledError: + self.connection.transport.abort() + raise + except Exception as exc: + # Always close the connection even though keep-alive is + # the default in HTTP/1.1 because create_connection ties + # opening the network connection with initializing the + # protocol. In the current design of connect(), there is + # no easy way to reuse the network connection that works + # in every case nor to reinitialize the protocol. + self.connection.transport.abort() + + uri_or_exc = self.process_redirect(exc) + # Response is a valid redirect; follow it. + if isinstance(uri_or_exc, str): + self.uri = uri_or_exc + continue + # Response isn't a valid redirect; raise the exception. + if uri_or_exc is exc: + raise + else: + raise uri_or_exc from exc + + else: + self.connection.start_keepalive() + return self.connection + else: + raise SecurityError(f"more than {MAX_REDIRECTS} redirects") + + except TimeoutError as exc: + # Re-raise exception with an informative error message. + raise TimeoutError("timed out during opening handshake") from exc + + # ... = yield from connect(...) - remove when dropping Python < 3.11 + + __iter__ = __await__ + + # async with connect(...) as ...: ... + + async def __aenter__(self) -> ClientConnection: + return await self + + async def __aexit__( + self, + exc_type: type[BaseException] | None, + exc_value: BaseException | None, + traceback: TracebackType | None, + ) -> None: + await self.connection.close() + + # async for ... in connect(...): + + async def __aiter__(self) -> AsyncIterator[ClientConnection]: + delays: Generator[float] | None = None + while True: + try: + async with self as protocol: + yield protocol + except Exception as exc: + # Determine whether the exception is retryable or fatal. + # The API of process_exception is "return an exception or None"; + # "raise an exception" is also supported because it's a frequent + # mistake. It isn't documented in order to keep the API simple. + try: + new_exc = self.process_exception(exc) + except Exception as raised_exc: + new_exc = raised_exc + + # The connection failed with a fatal error. + # Raise the exception and exit the loop. + if new_exc is exc: + raise + if new_exc is not None: + raise new_exc from exc + + # The connection failed with a retryable error. + # Start or continue backoff and reconnect. + if delays is None: + delays = backoff() + delay = next(delays) + self.logger.info( + "connect failed; reconnecting in %.1f seconds: %s", + delay, + traceback.format_exception_only(exc)[0].strip(), + ) + await asyncio.sleep(delay) + continue + + else: + # The connection succeeded. Reset backoff. + delays = None + + +def unix_connect( + path: str | None = None, + uri: str | None = None, + **kwargs: Any, +) -> connect: + """ + Connect to a WebSocket server listening on a Unix socket. + + This function accepts the same keyword arguments as :func:`connect`. + + It's only available on Unix. + + It's mainly useful for debugging servers listening on Unix sockets. + + Args: + path: File system path to the Unix socket. + uri: URI of the WebSocket server. ``uri`` defaults to + ``ws://localhost/`` or, when a ``ssl`` argument is provided, to + ``wss://localhost/``. + + """ + if uri is None: + if kwargs.get("ssl") is None: + uri = "ws://localhost/" + else: + uri = "wss://localhost/" + return connect(uri=uri, unix=True, path=path, **kwargs) + + +try: + from python_socks import ProxyType + from python_socks.async_.asyncio import Proxy as SocksProxy + +except ImportError: + + async def connect_socks_proxy( + proxy: Proxy, + ws_uri: WebSocketURI, + **kwargs: Any, + ) -> socket.socket: + raise ImportError("connecting through a SOCKS proxy requires python-socks") + +else: + SOCKS_PROXY_TYPES = { + "socks5h": ProxyType.SOCKS5, + "socks5": ProxyType.SOCKS5, + "socks4a": ProxyType.SOCKS4, + "socks4": ProxyType.SOCKS4, + } + + SOCKS_PROXY_RDNS = { + "socks5h": True, + "socks5": False, + "socks4a": True, + "socks4": False, + } + + async def connect_socks_proxy( + proxy: Proxy, + ws_uri: WebSocketURI, + **kwargs: Any, + ) -> socket.socket: + """Connect via a SOCKS proxy and return the socket.""" + socks_proxy = SocksProxy( + SOCKS_PROXY_TYPES[proxy.scheme], + proxy.host, + proxy.port, + proxy.username, + proxy.password, + SOCKS_PROXY_RDNS[proxy.scheme], + ) + # connect() is documented to raise OSError. + # socks_proxy.connect() doesn't raise TimeoutError; it gets canceled. + # Wrap other exceptions in ProxyError, a subclass of InvalidHandshake. + try: + return await socks_proxy.connect(ws_uri.host, ws_uri.port, **kwargs) + except OSError: + raise + except Exception as exc: + raise ProxyError("failed to connect to SOCKS proxy") from exc + + +class HTTPProxyConnection(asyncio.Protocol): + def __init__( + self, + ws_uri: WebSocketURI, + proxy: Proxy, + user_agent_header: str | None = None, + ): + self.ws_uri = ws_uri + self.proxy = proxy + self.user_agent_header = user_agent_header + + self.reader = StreamReader() + self.parser = Response.parse( + self.reader.read_line, + self.reader.read_exact, + self.reader.read_to_eof, + proxy=True, + ) + + loop = asyncio.get_running_loop() + self.response: asyncio.Future[Response] = loop.create_future() + + def run_parser(self) -> None: + try: + next(self.parser) + except StopIteration as exc: + response = exc.value + if 200 <= response.status_code < 300: + self.response.set_result(response) + else: + self.response.set_exception(InvalidProxyStatus(response)) + except Exception as exc: + proxy_exc = InvalidProxyMessage( + "did not receive a valid HTTP response from proxy" + ) + proxy_exc.__cause__ = exc + self.response.set_exception(proxy_exc) + + def connection_made(self, transport: asyncio.BaseTransport) -> None: + transport = cast(asyncio.Transport, transport) + self.transport = transport + self.transport.write( + prepare_connect_request(self.proxy, self.ws_uri, self.user_agent_header) + ) + + def data_received(self, data: bytes) -> None: + self.reader.feed_data(data) + self.run_parser() + + def eof_received(self) -> None: + self.reader.feed_eof() + self.run_parser() + + def connection_lost(self, exc: Exception | None) -> None: + self.reader.feed_eof() + if exc is not None: + self.response.set_exception(exc) + + +async def connect_http_proxy( + proxy: Proxy, + ws_uri: WebSocketURI, + user_agent_header: str | None = None, + **kwargs: Any, +) -> asyncio.Transport: + transport, protocol = await asyncio.get_running_loop().create_connection( + lambda: HTTPProxyConnection(ws_uri, proxy, user_agent_header), + proxy.host, + proxy.port, + **kwargs, + ) + + try: + # This raises exceptions if the connection to the proxy fails. + await protocol.response + except Exception: + transport.close() + raise + + return transport diff --git a/.venv/Lib/site-packages/websockets/asyncio/compatibility.py b/.venv/Lib/site-packages/websockets/asyncio/compatibility.py new file mode 100644 index 0000000000000000000000000000000000000000..cd3f93891a5893d6a96979e54b3b80cf83d35b12 --- /dev/null +++ b/.venv/Lib/site-packages/websockets/asyncio/compatibility.py @@ -0,0 +1,30 @@ +from __future__ import annotations + +import sys + + +__all__ = ["TimeoutError", "aiter", "anext", "asyncio_timeout", "asyncio_timeout_at"] + + +if sys.version_info[:2] >= (3, 11): + TimeoutError = TimeoutError + aiter = aiter + anext = anext + from asyncio import ( + timeout as asyncio_timeout, # noqa: F401 + timeout_at as asyncio_timeout_at, # noqa: F401 + ) + +else: # Python < 3.11 + from asyncio import TimeoutError + + def aiter(async_iterable): + return type(async_iterable).__aiter__(async_iterable) + + async def anext(async_iterator): + return await type(async_iterator).__anext__(async_iterator) + + from .async_timeout import ( + timeout as asyncio_timeout, # noqa: F401 + timeout_at as asyncio_timeout_at, # noqa: F401 + ) diff --git a/.venv/Lib/site-packages/websockets/asyncio/connection.py b/.venv/Lib/site-packages/websockets/asyncio/connection.py new file mode 100644 index 0000000000000000000000000000000000000000..37a10d3bf655040fcf8f3e4d2a4e96d66cc41514 --- /dev/null +++ b/.venv/Lib/site-packages/websockets/asyncio/connection.py @@ -0,0 +1,1262 @@ +from __future__ import annotations + +import asyncio +import collections +import contextlib +import logging +import random +import struct +import sys +import traceback +import uuid +from collections.abc import AsyncIterable, AsyncIterator, Awaitable, Iterable, Mapping +from types import TracebackType +from typing import Any, Literal, cast, overload + +from ..exceptions import ( + ConcurrencyError, + ConnectionClosed, + ConnectionClosedOK, + ProtocolError, +) +from ..frames import DATA_OPCODES, CloseCode, Frame, Opcode +from ..http11 import Request, Response +from ..protocol import CLOSED, OPEN, Event, Protocol, State +from ..typing import BytesLike, Data, DataLike, LoggerLike, Subprotocol +from .compatibility import ( + TimeoutError, + aiter, + anext, + asyncio_timeout, + asyncio_timeout_at, +) +from .messages import Assembler + + +__all__ = ["Connection"] + + +class Connection(asyncio.Protocol): + """ + :mod:`asyncio` implementation of a WebSocket connection. + + :class:`Connection` provides APIs shared between WebSocket servers and + clients. + + You shouldn't use it directly. Instead, use + :class:`~websockets.asyncio.client.ClientConnection` or + :class:`~websockets.asyncio.server.ServerConnection`. + + """ + + def __init__( + self, + protocol: Protocol, + *, + ping_interval: float | None = 20, + ping_timeout: float | None = 20, + close_timeout: float | None = 10, + max_queue: int | None | tuple[int | None, int | None] = 16, + write_limit: int | tuple[int, int | None] = 2**15, + ) -> None: + self.protocol = protocol + self.ping_interval = ping_interval + self.ping_timeout = ping_timeout + self.close_timeout = close_timeout + if isinstance(max_queue, int) or max_queue is None: + self.max_queue_high, self.max_queue_low = max_queue, None + else: + self.max_queue_high, self.max_queue_low = max_queue + if isinstance(write_limit, int): + self.write_limit_high, self.write_limit_low = write_limit, None + else: + self.write_limit_high, self.write_limit_low = write_limit + + # Inject reference to this instance in the protocol's logger. + self.protocol.logger = logging.LoggerAdapter( + self.protocol.logger, + {"websocket": self}, + ) + + # Copy attributes from the protocol for convenience. + self.id: uuid.UUID = self.protocol.id + """Unique identifier of the connection. Useful in logs.""" + self.logger: LoggerLike = self.protocol.logger + """Logger for this connection.""" + self.debug = self.protocol.debug + + # HTTP handshake request and response. + self.request: Request | None = None + """Opening handshake request.""" + self.response: Response | None = None + """Opening handshake response.""" + + # Event loop running this connection. + self.loop = asyncio.get_running_loop() + + # Assembler turning frames into messages and serializing reads. + self.recv_messages: Assembler # initialized in connection_made + + # Deadline for the closing handshake. + self.close_deadline: float | None = None + + # Whether we are busy sending a fragmented message. + self.send_in_progress: asyncio.Future[None] | None = None + + # Mapping of ping IDs to pong waiters, in chronological order. + self.pending_pings: dict[bytes, tuple[asyncio.Future[float], float]] = {} + + self.latency: float = 0.0 + """ + Latency of the connection, in seconds. + + Latency is defined as the round-trip time of the connection. It is + measured by sending a Ping frame and waiting for a matching Pong frame. + Before the first measurement, :attr:`latency` is ``0.0``. + + By default, websockets enables a :ref:`keepalive ` mechanism + that sends Ping frames automatically at regular intervals. You can also + send Ping frames and measure latency with :meth:`ping`. + """ + + # Task that sends keepalive pings. None when ping_interval is None. + self.keepalive_task: asyncio.Task[None] | None = None + + # Exception raised while reading from the connection, to be chained to + # ConnectionClosed in order to show why the TCP connection dropped. + self.recv_exc: BaseException | None = None + + # Completed when the TCP connection is closed and the WebSocket + # connection state becomes CLOSED. + self.connection_lost_waiter: asyncio.Future[None] = self.loop.create_future() + + # Adapted from asyncio.FlowControlMixin. + self.paused: bool = False + self.drain_waiters: collections.deque[asyncio.Future[None]] = ( + collections.deque() + ) + + # Public attributes + + @property + def local_address(self) -> Any: + """ + Local address of the connection. + + For IPv4 connections, this is a ``(host, port)`` tuple. + + The format of the address depends on the address family. + See :meth:`~socket.socket.getsockname`. + + """ + return self.transport.get_extra_info("sockname") + + @property + def remote_address(self) -> Any: + """ + Remote address of the connection. + + For IPv4 connections, this is a ``(host, port)`` tuple. + + The format of the address depends on the address family. + See :meth:`~socket.socket.getpeername`. + + """ + return self.transport.get_extra_info("peername") + + @property + def state(self) -> State: + """ + State of the WebSocket connection, defined in :rfc:`6455`. + + This attribute is provided for completeness. Typical applications + shouldn't check its value. Instead, they should call :meth:`~recv` or + :meth:`send` and handle :exc:`~websockets.exceptions.ConnectionClosed` + exceptions. + + """ + return self.protocol.state + + @property + def subprotocol(self) -> Subprotocol | None: + """ + Subprotocol negotiated during the opening handshake. + + :obj:`None` if no subprotocol was negotiated. + + """ + return self.protocol.subprotocol + + @property + def close_code(self) -> int | None: + """ + State of the WebSocket connection, defined in :rfc:`6455`. + + This attribute is provided for completeness. Typical applications + shouldn't check its value. Instead, they should inspect attributes + of :exc:`~websockets.exceptions.ConnectionClosed` exceptions. + + """ + return self.protocol.close_code + + @property + def close_reason(self) -> str | None: + """ + State of the WebSocket connection, defined in :rfc:`6455`. + + This attribute is provided for completeness. Typical applications + shouldn't check its value. Instead, they should inspect attributes + of :exc:`~websockets.exceptions.ConnectionClosed` exceptions. + + """ + return self.protocol.close_reason + + # Public methods + + async def __aenter__(self) -> Connection: + return self + + async def __aexit__( + self, + exc_type: type[BaseException] | None, + exc_value: BaseException | None, + traceback: TracebackType | None, + ) -> None: + if exc_type is None: + await self.close() + else: + await self.close(CloseCode.INTERNAL_ERROR) + + async def __aiter__(self) -> AsyncIterator[Data]: + """ + Iterate on incoming messages. + + The iterator calls :meth:`recv` and yields messages asynchronously in an + infinite loop. + + It exits when the connection is closed normally. It raises a + :exc:`~websockets.exceptions.ConnectionClosedError` exception after a + protocol error or a network failure. + + """ + try: + while True: + yield await self.recv() + except ConnectionClosedOK: + return + + @overload + async def recv(self, decode: Literal[True]) -> str: ... + + @overload + async def recv(self, decode: Literal[False]) -> bytes: ... + + @overload + async def recv(self, decode: bool | None = None) -> Data: ... + + async def recv(self, decode: bool | None = None) -> Data: + """ + Receive the next message. + + When the connection is closed, :meth:`recv` raises + :exc:`~websockets.exceptions.ConnectionClosed`. Specifically, it raises + :exc:`~websockets.exceptions.ConnectionClosedOK` after a normal closure + and :exc:`~websockets.exceptions.ConnectionClosedError` after a protocol + error or a network failure. This is how you detect the end of the + message stream. + + Canceling :meth:`recv` is safe. There's no risk of losing data. The next + invocation of :meth:`recv` will return the next message. + + This makes it possible to enforce a timeout by wrapping :meth:`recv` in + :func:`~asyncio.timeout` or :func:`~asyncio.wait_for`. + + When the message is fragmented, :meth:`recv` waits until all fragments + are received, reassembles them, and returns the whole message. + + Args: + decode: Set this flag to override the default behavior of returning + :class:`str` or :class:`bytes`. See below for details. + + Returns: + A string (:class:`str`) for a Text_ frame or a bytestring + (:class:`bytes`) for a Binary_ frame. + + .. _Text: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6 + .. _Binary: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6 + + You may override this behavior with the ``decode`` argument: + + * Set ``decode=False`` to disable UTF-8 decoding of Text_ frames and + return a bytestring (:class:`bytes`). This improves performance + when decoding isn't needed, for example if the message contains + JSON and you're using a JSON library that expects a bytestring. + * Set ``decode=True`` to force UTF-8 decoding of Binary_ frames and + return strings (:class:`str`). This may be useful for servers that + send binary frames instead of text frames. + + Raises: + ConnectionClosed: When the connection is closed. + ConcurrencyError: If two coroutines call :meth:`recv` or + :meth:`recv_streaming` concurrently. + + """ + try: + return await self.recv_messages.get(decode) + except EOFError: + pass + # fallthrough + except ConcurrencyError: + raise ConcurrencyError( + "cannot call recv while another coroutine " + "is already running recv or recv_streaming" + ) from None + except UnicodeDecodeError as exc: + async with self.send_context(): + self.protocol.fail( + CloseCode.INVALID_DATA, + f"{exc.reason} at position {exc.start}", + ) + # fallthrough + + # Wait for the protocol state to be CLOSED before accessing close_exc. + await asyncio.shield(self.connection_lost_waiter) + raise self.protocol.close_exc from self.recv_exc + + @overload + def recv_streaming(self, decode: Literal[True]) -> AsyncIterator[str]: ... + + @overload + def recv_streaming(self, decode: Literal[False]) -> AsyncIterator[bytes]: ... + + @overload + def recv_streaming(self, decode: bool | None = None) -> AsyncIterator[Data]: ... + + async def recv_streaming(self, decode: bool | None = None) -> AsyncIterator[Data]: + """ + Receive the next message frame by frame. + + This method is designed for receiving fragmented messages. It returns an + asynchronous iterator that yields each fragment as it is received. This + iterator must be fully consumed. Else, future calls to :meth:`recv` or + :meth:`recv_streaming` will raise + :exc:`~websockets.exceptions.ConcurrencyError`, making the connection + unusable. + + :meth:`recv_streaming` raises the same exceptions as :meth:`recv`. + + Canceling :meth:`recv_streaming` before receiving the first frame is + safe. Canceling it after receiving one or more frames leaves the + iterator in a partially consumed state, making the connection unusable. + Instead, you should close the connection with :meth:`close`. + + Args: + decode: Set this flag to override the default behavior of returning + :class:`str` or :class:`bytes`. See below for details. + + Returns: + An iterator of strings (:class:`str`) for a Text_ frame or + bytestrings (:class:`bytes`) for a Binary_ frame. + + .. _Text: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6 + .. _Binary: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6 + + You may override this behavior with the ``decode`` argument: + + * Set ``decode=False`` to disable UTF-8 decoding of Text_ frames and + yield bytestrings (:class:`bytes`). This improves performance + when decoding isn't needed. + * Set ``decode=True`` to force UTF-8 decoding of Binary_ frames and + yield strings (:class:`str`). This may be useful for servers that + send binary frames instead of text frames. + + Raises: + ConnectionClosed: When the connection is closed. + ConcurrencyError: If two coroutines call :meth:`recv` or + :meth:`recv_streaming` concurrently. + + """ + try: + async for frame in self.recv_messages.get_iter(decode): + yield frame + return + except EOFError: + pass + # fallthrough + except ConcurrencyError: + raise ConcurrencyError( + "cannot call recv_streaming while another coroutine " + "is already running recv or recv_streaming" + ) from None + except UnicodeDecodeError as exc: + async with self.send_context(): + self.protocol.fail( + CloseCode.INVALID_DATA, + f"{exc.reason} at position {exc.start}", + ) + # fallthrough + + # Wait for the protocol state to be CLOSED before accessing close_exc. + await asyncio.shield(self.connection_lost_waiter) + raise self.protocol.close_exc from self.recv_exc + + async def send( + self, + message: DataLike | Iterable[DataLike] | AsyncIterable[DataLike], + text: bool | None = None, + ) -> None: + """ + Send a message. + + A string (:class:`str`) is sent as a Text_ frame. A bytestring or + bytes-like object (:class:`bytes`, :class:`bytearray`, or + :class:`memoryview`) is sent as a Binary_ frame. + + .. _Text: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6 + .. _Binary: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6 + + You may override this behavior with the ``text`` argument: + + * Set ``text=True`` to send an UTF-8 bytestring or bytes-like object + (:class:`bytes`, :class:`bytearray`, or :class:`memoryview`) in a + Text_ frame. This improves performance when the message is already + UTF-8 encoded, for example if the message contains JSON and you're + using a JSON library that produces a bytestring. + * Set ``text=False`` to send a string (:class:`str`) in a Binary_ + frame. This may be useful for servers that expect binary frames + instead of text frames. + + :meth:`send` also accepts an iterable or asynchronous iterable of + strings, bytestrings, or bytes-like objects to enable fragmentation_. + Each item is treated as a message fragment and sent in its own frame. + All items must be of the same type, or else :meth:`send` will raise a + :exc:`TypeError` and the connection will be closed. + + .. _fragmentation: https://datatracker.ietf.org/doc/html/rfc6455#section-5.4 + + :meth:`send` rejects dict-like objects because this is often an error. + (If you really want to send the keys of a dict-like object as fragments, + call its :meth:`~dict.keys` method and pass the result to :meth:`send`.) + + Canceling :meth:`send` is discouraged. Instead, you should close the + connection with :meth:`close`. Indeed, there are only two situations + where :meth:`send` may yield control to the event loop and then get + canceled; in both cases, :meth:`close` has the same effect and the + effect is more obvious: + + 1. The write buffer is full. If you don't want to wait until enough + data is sent, your only alternative is to close the connection. + :meth:`close` will likely time out then abort the TCP connection. + 2. ``message`` is an asynchronous iterator that yields control. + Stopping in the middle of a fragmented message will cause a + protocol error and the connection will be closed. + + When the connection is closed, :meth:`send` raises + :exc:`~websockets.exceptions.ConnectionClosed`. Specifically, it + raises :exc:`~websockets.exceptions.ConnectionClosedOK` after a normal + connection closure and + :exc:`~websockets.exceptions.ConnectionClosedError` after a protocol + error or a network failure. + + Args: + message: Message to send. + text: Force sending in a Text_ or Binary_ frame. + + Raises: + ConnectionClosed: When the connection is closed. + TypeError: If ``message`` doesn't have a supported type. + + """ + # While sending a fragmented message, prevent sending other messages + # until all fragments are sent. + while self.send_in_progress is not None: + await asyncio.shield(self.send_in_progress) + + # Unfragmented message -- this case must be handled first because + # strings and bytes-like objects are iterable. + + if isinstance(message, str): + async with self.send_context(): + if text is False: + self.protocol.send_binary(message.encode()) + else: + self.protocol.send_text(message.encode()) + + elif isinstance(message, BytesLike): + async with self.send_context(): + if text is True: + self.protocol.send_text(message) + else: + self.protocol.send_binary(message) + + # Catch a common mistake -- passing a dict to send(). + + elif isinstance(message, Mapping): + raise TypeError("data is a dict-like object") + + # Fragmented message -- regular iterator. + + elif isinstance(message, Iterable): + chunks = iter(message) + try: + chunk = next(chunks) + except StopIteration: + return + + assert self.send_in_progress is None + self.send_in_progress = self.loop.create_future() + try: + # First fragment. + if isinstance(chunk, str): + async with self.send_context(): + if text is False: + self.protocol.send_binary(chunk.encode(), fin=False) + else: + self.protocol.send_text(chunk.encode(), fin=False) + encode = True + elif isinstance(chunk, BytesLike): + async with self.send_context(): + if text is True: + self.protocol.send_text(chunk, fin=False) + else: + self.protocol.send_binary(chunk, fin=False) + encode = False + else: + raise TypeError("iterable must contain bytes or str") + + # Other fragments + for chunk in chunks: + if isinstance(chunk, str) and encode: + async with self.send_context(): + self.protocol.send_continuation(chunk.encode(), fin=False) + elif isinstance(chunk, BytesLike) and not encode: + async with self.send_context(): + self.protocol.send_continuation(chunk, fin=False) + else: + raise TypeError("iterable must contain uniform types") + + # Final fragment. + async with self.send_context(): + self.protocol.send_continuation(b"", fin=True) + + except Exception: + # We're half-way through a fragmented message and we can't + # complete it. This makes the connection unusable. + async with self.send_context(): + self.protocol.fail( + CloseCode.INTERNAL_ERROR, + "error in fragmented message", + ) + raise + + finally: + self.send_in_progress.set_result(None) + self.send_in_progress = None + + # Fragmented message -- async iterator. + + elif isinstance(message, AsyncIterable): + achunks = aiter(message) + try: + chunk = await anext(achunks) + except StopAsyncIteration: + return + + assert self.send_in_progress is None + self.send_in_progress = self.loop.create_future() + try: + # First fragment. + if isinstance(chunk, str): + if text is False: + async with self.send_context(): + self.protocol.send_binary(chunk.encode(), fin=False) + else: + async with self.send_context(): + self.protocol.send_text(chunk.encode(), fin=False) + encode = True + elif isinstance(chunk, BytesLike): + if text is True: + async with self.send_context(): + self.protocol.send_text(chunk, fin=False) + else: + async with self.send_context(): + self.protocol.send_binary(chunk, fin=False) + encode = False + else: + raise TypeError("async iterable must contain bytes or str") + + # Other fragments + async for chunk in achunks: + if isinstance(chunk, str) and encode: + async with self.send_context(): + self.protocol.send_continuation(chunk.encode(), fin=False) + elif isinstance(chunk, BytesLike) and not encode: + async with self.send_context(): + self.protocol.send_continuation(chunk, fin=False) + else: + raise TypeError("async iterable must contain uniform types") + + # Final fragment. + async with self.send_context(): + self.protocol.send_continuation(b"", fin=True) + + except Exception: + # We're half-way through a fragmented message and we can't + # complete it. This makes the connection unusable. + async with self.send_context(): + self.protocol.fail( + CloseCode.INTERNAL_ERROR, + "error in fragmented message", + ) + raise + + finally: + self.send_in_progress.set_result(None) + self.send_in_progress = None + + else: + raise TypeError("data must be str, bytes, iterable, or async iterable") + + async def close( + self, + code: CloseCode | int = CloseCode.NORMAL_CLOSURE, + reason: str = "", + ) -> None: + """ + Perform the closing handshake. + + :meth:`close` waits for the other end to complete the handshake and + for the TCP connection to terminate. + + :meth:`close` is idempotent: it doesn't do anything once the + connection is closed. + + Args: + code: WebSocket close code. + reason: WebSocket close reason. + + """ + try: + # The context manager takes care of waiting for the TCP connection + # to terminate after calling a method that sends a close frame. + async with self.send_context(): + if self.send_in_progress is not None: + self.protocol.fail( + CloseCode.INTERNAL_ERROR, + "close during fragmented message", + ) + else: + self.protocol.send_close(code, reason) + except ConnectionClosed: + # Ignore ConnectionClosed exceptions raised from send_context(). + # They mean that the connection is closed, which was the goal. + pass + + async def wait_closed(self) -> None: + """ + Wait until the connection is closed. + + :meth:`wait_closed` waits for the closing handshake to complete and for + the TCP connection to terminate. + + """ + await asyncio.shield(self.connection_lost_waiter) + + async def ping(self, data: DataLike | None = None) -> Awaitable[float]: + """ + Send a Ping_. + + .. _Ping: https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.2 + + A ping may serve as a keepalive or as a check that the remote endpoint + received all messages up to this point + + Args: + data: Payload of the ping. A :class:`str` will be encoded to UTF-8. + If ``data`` is :obj:`None`, the payload is four random bytes. + + Returns: + A future that will be completed when the corresponding pong is + received. You can ignore it if you don't intend to wait. The result + of the future is the latency of the connection in seconds. + + :: + + pong_received = await ws.ping() + # only if you want to wait for the corresponding pong + latency = await pong_received + + Raises: + ConnectionClosed: When the connection is closed. + ConcurrencyError: If another ping was sent with the same data and + the corresponding pong wasn't received yet. + + """ + if isinstance(data, BytesLike): + data = bytes(data) + elif isinstance(data, str): + data = data.encode() + elif data is not None: + raise TypeError("data must be str or bytes-like") + + async with self.send_context(): + # Protect against duplicates if a payload is explicitly set. + if data in self.pending_pings: + raise ConcurrencyError("already waiting for a pong with the same data") + + # Generate a unique random payload otherwise. + while data is None or data in self.pending_pings: + data = struct.pack("!I", random.getrandbits(32)) + + pong_received = self.loop.create_future() + ping_timestamp = self.loop.time() + # The event loop's default clock is time.monotonic(). Its resolution + # is a bit low on Windows (~16ms). This is improved in Python 3.13. + self.pending_pings[data] = (pong_received, ping_timestamp) + self.protocol.send_ping(data) + return pong_received + + async def pong(self, data: DataLike = b"") -> None: + """ + Send a Pong_. + + .. _Pong: https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.3 + + An unsolicited pong may serve as a unidirectional heartbeat. + + Args: + data: Payload of the pong. A :class:`str` will be encoded to UTF-8. + + Raises: + ConnectionClosed: When the connection is closed. + + """ + if isinstance(data, BytesLike): + data = bytes(data) + elif isinstance(data, str): + data = data.encode() + else: + raise TypeError("data must be str or bytes-like") + + async with self.send_context(): + self.protocol.send_pong(data) + + # Private methods + + def process_event(self, event: Event) -> None: + """ + Process one incoming event. + + This method is overridden in subclasses to handle the handshake. + + """ + assert isinstance(event, Frame) + if event.opcode in DATA_OPCODES: + self.recv_messages.put(event) + + if event.opcode is Opcode.PONG: + self.acknowledge_pings(bytes(event.data)) + + def acknowledge_pings(self, data: bytes) -> None: + """ + Acknowledge pings when receiving a pong. + + """ + # Ignore unsolicited pong. + if data not in self.pending_pings: + return + + pong_timestamp = self.loop.time() + + # Sending a pong for only the most recent ping is legal. + # Acknowledge all previous pings too in that case. + ping_id = None + ping_ids = [] + for ping_id, (pong_received, ping_timestamp) in self.pending_pings.items(): + ping_ids.append(ping_id) + latency = pong_timestamp - ping_timestamp + if not pong_received.done(): + pong_received.set_result(latency) + if ping_id == data: + self.latency = latency + break + else: + raise AssertionError("solicited pong not found in pings") + + # Remove acknowledged pings from self.pending_pings. + for ping_id in ping_ids: + del self.pending_pings[ping_id] + + def terminate_pending_pings(self) -> None: + """ + Raise ConnectionClosed in pending pings when the connection is closed. + + """ + assert self.protocol.state is CLOSED + exc = self.protocol.close_exc + + for pong_received, _ping_timestamp in self.pending_pings.values(): + if not pong_received.done(): + pong_received.set_exception(exc) + # If the exception is never retrieved, it will be logged when ping + # is garbage-collected. This is confusing for users. + # Given that ping is done (with an exception), canceling it does + # nothing, but it prevents logging the exception. + pong_received.cancel() + + self.pending_pings.clear() + + async def keepalive(self) -> None: + """ + Send a Ping frame and wait for a Pong frame at regular intervals. + + """ + assert self.ping_interval is not None + latency = 0.0 + try: + while True: + # If self.ping_timeout > latency > self.ping_interval, + # pings will be sent immediately after receiving pongs. + # The period will be longer than self.ping_interval. + await asyncio.sleep(self.ping_interval - latency) + + # This cannot raise ConnectionClosed when the connection is + # closing because ping(), via send_context(), waits for the + # connection to be closed before raising ConnectionClosed. + # However, connection_lost() cancels keepalive_task before + # it gets a chance to resume executing. + pong_received = await self.ping() + if self.debug: + self.logger.debug("% sent keepalive ping") + + if self.ping_timeout is not None: + try: + async with asyncio_timeout(self.ping_timeout): + # connection_lost cancels keepalive immediately + # after setting a ConnectionClosed exception on + # pong_received. A CancelledError is raised here, + # not a ConnectionClosed exception. + latency = await pong_received + if self.debug: + self.logger.debug("% received keepalive pong") + except asyncio.TimeoutError: + if self.debug: + self.logger.debug("- timed out waiting for keepalive pong") + async with self.send_context(): + self.protocol.fail( + CloseCode.INTERNAL_ERROR, + "keepalive ping timeout", + ) + raise AssertionError( + "send_context() should wait for connection_lost(), " + "which cancels keepalive()" + ) + except Exception: + self.logger.error("keepalive ping failed", exc_info=True) + + def start_keepalive(self) -> None: + """ + Run :meth:`keepalive` in a task, unless keepalive is disabled. + + """ + if self.ping_interval is not None: + self.keepalive_task = self.loop.create_task(self.keepalive()) + + @contextlib.asynccontextmanager + async def send_context( + self, + *, + expected_state: State = OPEN, # CONNECTING during the opening handshake + ) -> AsyncIterator[None]: + """ + Create a context for writing to the connection from user code. + + On entry, :meth:`send_context` checks that the connection is open; on + exit, it writes outgoing data to the socket:: + + async with self.send_context(): + self.protocol.send_text(message.encode()) + + When the connection isn't open on entry, when the connection is expected + to close on exit, or when an unexpected error happens, terminating the + connection, :meth:`send_context` waits until the connection is closed + then raises :exc:`~websockets.exceptions.ConnectionClosed`. + + """ + # Should we wait until the connection is closed? + wait_for_close = False + # Should we close the transport and raise ConnectionClosed? + raise_close_exc = False + # What exception should we chain ConnectionClosed to? + original_exc: BaseException | None = None + + if self.protocol.state is expected_state: + # Let the caller interact with the protocol. + try: + yield + except (ProtocolError, ConcurrencyError): + # The protocol state wasn't changed. Exit immediately. + raise + except Exception as exc: + self.logger.error("unexpected internal error", exc_info=True) + # This branch should never run. It's a safety net in case of + # bugs. Since we don't know what happened, we will close the + # connection and raise the exception to the caller. + wait_for_close = False + raise_close_exc = True + original_exc = exc + else: + # Check if the connection is expected to close soon. + if self.protocol.close_expected(): + wait_for_close = True + # Set the close deadline based on the close timeout. + # Since we tested earlier that protocol.state is OPEN + # (or CONNECTING), self.close_deadline is still None. + assert self.close_deadline is None + if self.close_timeout is not None: + self.close_deadline = self.loop.time() + self.close_timeout + # Write outgoing data to the socket with flow control. + try: + self.send_data() + await self.drain() + except Exception as exc: + if self.debug: + self.logger.debug( + "! error while sending data", + exc_info=True, + ) + # While the only expected exception here is OSError, + # other exceptions would be treated identically. + wait_for_close = False + raise_close_exc = True + original_exc = exc + + else: # self.protocol.state is not expected_state + # Minor layering violation: we assume that the connection + # will be closing soon if it isn't in the expected state. + wait_for_close = True + # Calculate close_deadline if it wasn't set yet. + if self.close_deadline is None: + if self.close_timeout is not None: + self.close_deadline = self.loop.time() + self.close_timeout + raise_close_exc = True + + # If the connection is expected to close soon and the close timeout + # elapses, close the socket to terminate the connection. + if wait_for_close: + try: + async with asyncio_timeout_at(self.close_deadline): + await asyncio.shield(self.connection_lost_waiter) + except TimeoutError: + # There's no risk of overwriting another error because + # original_exc is never set when wait_for_close is True. + assert original_exc is None + original_exc = TimeoutError("timed out while closing connection") + # Set recv_exc before closing the transport in order to get + # proper exception reporting. + raise_close_exc = True + self.set_recv_exc(original_exc) + + # If an error occurred, close the transport to terminate the connection and + # raise an exception. + if raise_close_exc: + self.transport.abort() + # Wait for the protocol state to be CLOSED before accessing close_exc. + await asyncio.shield(self.connection_lost_waiter) + raise self.protocol.close_exc from original_exc + + def send_data(self) -> None: + """ + Send outgoing data. + + """ + for data in self.protocol.data_to_send(): + if data: + self.transport.write(data) + else: + # Half-close the TCP connection when possible i.e. no TLS. + if self.transport.can_write_eof(): + if self.debug: + self.logger.debug("x half-closing TCP connection") + # write_eof() doesn't document which exceptions it raises. + # OSError is plausible. uvloop can raise RuntimeError here. + try: + self.transport.write_eof() + except Exception: # pragma: no cover + pass + # Else, close the TCP connection. + else: # pragma: no cover + if self.debug: + self.logger.debug("x closing TCP connection") + self.transport.close() + + def set_recv_exc(self, exc: BaseException | None) -> None: + """ + Set recv_exc, if not set yet. + + This method must be called only from connection callbacks. + + """ + if self.recv_exc is None: + self.recv_exc = exc + + # asyncio.Protocol methods + + # Connection callbacks + + def connection_made(self, transport: asyncio.BaseTransport) -> None: + transport = cast(asyncio.Transport, transport) + self.recv_messages = Assembler( + self.max_queue_high, + self.max_queue_low, + pause=transport.pause_reading, + resume=transport.resume_reading, + ) + transport.set_write_buffer_limits( + self.write_limit_high, + self.write_limit_low, + ) + self.transport = transport + + def connection_lost(self, exc: Exception | None) -> None: + # Calling protocol.receive_eof() is safe because it's idempotent. + # This guarantees that the protocol state becomes CLOSED. + self.protocol.receive_eof() + assert self.protocol.state is CLOSED + + self.set_recv_exc(exc) + + # Abort recv() and pending pings with a ConnectionClosed exception. + self.recv_messages.close() + self.terminate_pending_pings() + + if self.keepalive_task is not None: + self.keepalive_task.cancel() + + # If self.connection_lost_waiter isn't pending, that's a bug, because: + # - it's set only here in connection_lost() which is called only once; + # - it must never be canceled. + self.connection_lost_waiter.set_result(None) + + # Adapted from asyncio.streams.FlowControlMixin + if self.paused: # pragma: no cover + self.paused = False + for waiter in self.drain_waiters: + if not waiter.done(): + if exc is None: + waiter.set_result(None) + else: + waiter.set_exception(exc) + + # Flow control callbacks + + def pause_writing(self) -> None: # pragma: no cover + # Adapted from asyncio.streams.FlowControlMixin + assert not self.paused + self.paused = True + + def resume_writing(self) -> None: # pragma: no cover + # Adapted from asyncio.streams.FlowControlMixin + assert self.paused + self.paused = False + for waiter in self.drain_waiters: + if not waiter.done(): + waiter.set_result(None) + + async def drain(self) -> None: # pragma: no cover + # We don't check if the connection is closed because we call drain() + # immediately after write() and write() would fail in that case. + + # Adapted from asyncio.streams.StreamWriter + # Yield to the event loop so that connection_lost() may be called. + if self.transport.is_closing(): + await asyncio.sleep(0) + + # Adapted from asyncio.streams.FlowControlMixin + if self.paused: + waiter = self.loop.create_future() + self.drain_waiters.append(waiter) + try: + await waiter + finally: + self.drain_waiters.remove(waiter) + + # Streaming protocol callbacks + + def data_received(self, data: bytes) -> None: + # Feed incoming data to the protocol. + self.protocol.receive_data(data) + + # This isn't expected to raise an exception. + events = self.protocol.events_received() + + # Write outgoing data to the transport. + try: + self.send_data() + except Exception as exc: + if self.debug: + self.logger.debug("! error while sending data", exc_info=True) + self.set_recv_exc(exc) + + # If needed, set the close deadline based on the close timeout. + if self.protocol.close_expected(): + if self.close_deadline is None: + if self.close_timeout is not None: + self.close_deadline = self.loop.time() + self.close_timeout + + # If self.send_data raised an exception, then events are lost. + # Given that automatic responses write small amounts of data, + # this should be uncommon, so we don't handle the edge case. + + for event in events: + # This isn't expected to raise an exception. + self.process_event(event) + + def eof_received(self) -> None: + # Feed the end of the data stream to the protocol. + self.protocol.receive_eof() + + # This isn't expected to raise an exception. + events = self.protocol.events_received() + + # There is no error handling because send_data() can only write + # the end of the data stream and it handles errors by itself. + self.send_data() + + # This code path is triggered when receiving an HTTP response + # without a Content-Length header. This is the only case where + # reading until EOF generates an event; all other events have + # a known length. Ignore for coverage measurement because tests + # are in test_client.py rather than test_connection.py. + for event in events: # pragma: no cover + # This isn't expected to raise an exception. + self.process_event(event) + + # The WebSocket protocol has its own closing handshake: endpoints close + # the TCP or TLS connection after sending and receiving a close frame. + # As a consequence, they never need to write after receiving EOF, so + # there's no reason to keep the transport open by returning True. + # Besides, that doesn't work on TLS connections. + + +# broadcast() is defined in the connection module even though it's primarily +# used by servers and documented in the server module because it works with +# client connections too and because it's easier to test together with the +# Connection class. + + +def broadcast( + connections: Iterable[Connection], + message: DataLike, + raise_exceptions: bool = False, + *, + text: bool | None = None, +) -> None: + """ + Broadcast a message to several WebSocket connections. + + A string (:class:`str`) is sent as a Text_ frame. A bytestring or bytes-like + object (:class:`bytes`, :class:`bytearray`, or :class:`memoryview`) is sent + as a Binary_ frame. + + .. _Text: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6 + .. _Binary: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6 + + You may override this behavior with the ``text`` argument: + + * Set ``text=True`` to send an UTF-8 bytestring or bytes-like object + (:class:`bytes`, :class:`bytearray`, or :class:`memoryview`) in a + Text_ frame. This improves performance when the message is already + UTF-8 encoded, for example if the message contains JSON and you're + using a JSON library that produces a bytestring. + * Set ``text=False`` to send a string (:class:`str`) in a Binary_ + frame. This may be useful for servers that expect binary frames + instead of text frames. + + :func:`broadcast` pushes the message synchronously to all connections even + if their write buffers are overflowing. There's no backpressure. + + If you broadcast messages faster than a connection can handle them, messages + will pile up in its write buffer until the connection times out. Keep + ``ping_interval`` and ``ping_timeout`` low to prevent excessive memory usage + from slow connections. + + Unlike :meth:`~websockets.asyncio.connection.Connection.send`, + :func:`broadcast` doesn't support sending fragmented messages. Indeed, + fragmentation is useful for sending large messages without buffering them in + memory, while :func:`broadcast` buffers one copy per connection as fast as + possible. + + :func:`broadcast` skips connections that aren't open in order to avoid + errors on connections where the closing handshake is in progress. + + :func:`broadcast` ignores failures to write the message on some connections. + It continues writing to other connections. On Python 3.11 and above, you may + set ``raise_exceptions`` to :obj:`True` to record failures and raise all + exceptions in a :pep:`654` :exc:`ExceptionGroup`. + + While :func:`broadcast` makes more sense for servers, it works identically + with clients, if you have a use case for opening connections to many servers + and broadcasting a message to them. + + Args: + websockets: WebSocket connections to which the message will be sent. + message: Message to send. + raise_exceptions: Whether to raise an exception in case of failures. + text: Force sending in Text_ or Binary_ frames. + + Raises: + TypeError: If ``message`` doesn't have a supported type. + + """ + if isinstance(message, str): + send_method = "send_binary" if text is False else "send_text" + message = message.encode() + elif isinstance(message, BytesLike): + send_method = "send_text" if text is True else "send_binary" + else: + raise TypeError("data must be str or bytes") + + if raise_exceptions: + if sys.version_info[:2] < (3, 11): # pragma: no cover + raise ValueError("raise_exceptions requires at least Python 3.11") + exceptions: list[Exception] = [] + + for connection in connections: + exception: Exception + + if connection.protocol.state is not OPEN: + continue + + if connection.send_in_progress is not None: + if raise_exceptions: + exception = ConcurrencyError("sending a fragmented message") + exceptions.append(exception) + else: + connection.logger.warning( + "skipped broadcast: sending a fragmented message", + ) + continue + + try: + # Call connection.protocol.send_text or send_binary. + # Either way, message is already converted to bytes. + getattr(connection.protocol, send_method)(message) + connection.send_data() + except Exception as write_exception: + if raise_exceptions: + exception = RuntimeError("failed to write message") + exception.__cause__ = write_exception + exceptions.append(exception) + else: + connection.logger.warning( + "skipped broadcast: failed to write message: %s", + traceback.format_exception_only(write_exception)[0].strip(), + ) + + if raise_exceptions and exceptions: + raise ExceptionGroup("skipped broadcast", exceptions) + + +# Pretend that broadcast is actually defined in the server module. +broadcast.__module__ = "websockets.asyncio.server" diff --git a/.venv/Lib/site-packages/websockets/asyncio/messages.py b/.venv/Lib/site-packages/websockets/asyncio/messages.py new file mode 100644 index 0000000000000000000000000000000000000000..37126bf5e53b46cbc665c38e62fc17b5bfea9a15 --- /dev/null +++ b/.venv/Lib/site-packages/websockets/asyncio/messages.py @@ -0,0 +1,316 @@ +from __future__ import annotations + +import asyncio +import codecs +import collections +from collections.abc import AsyncIterator, Iterable +from typing import Any, Callable, Generic, Literal, TypeVar, overload + +from ..exceptions import ConcurrencyError +from ..frames import OP_BINARY, OP_CONT, OP_TEXT, Frame +from ..typing import Data + + +__all__ = ["Assembler"] + +UTF8Decoder = codecs.getincrementaldecoder("utf-8") + +T = TypeVar("T") + + +class SimpleQueue(Generic[T]): + """ + Simplified version of :class:`asyncio.Queue`. + + Provides only the subset of functionality needed by :class:`Assembler`. + + """ + + def __init__(self) -> None: + self.loop = asyncio.get_running_loop() + self.get_waiter: asyncio.Future[None] | None = None + self.queue: collections.deque[T] = collections.deque() + + def __len__(self) -> int: + return len(self.queue) + + def put(self, item: T) -> None: + """Put an item into the queue.""" + self.queue.append(item) + if self.get_waiter is not None and not self.get_waiter.done(): + self.get_waiter.set_result(None) + + async def get(self, block: bool = True) -> T: + """Remove and return an item from the queue, waiting if necessary.""" + if not self.queue: + if not block: + raise EOFError("stream of frames ended") + assert self.get_waiter is None, "cannot call get() concurrently" + self.get_waiter = self.loop.create_future() + try: + await self.get_waiter + finally: + self.get_waiter.cancel() + self.get_waiter = None + return self.queue.popleft() + + def reset(self, items: Iterable[T]) -> None: + """Put back items into an empty, idle queue.""" + assert self.get_waiter is None, "cannot reset() while get() is running" + assert not self.queue, "cannot reset() while queue isn't empty" + self.queue.extend(items) + + def abort(self) -> None: + """Close the queue, raising EOFError in get() if necessary.""" + if self.get_waiter is not None and not self.get_waiter.done(): + self.get_waiter.set_exception(EOFError("stream of frames ended")) + + +class Assembler: + """ + Assemble messages from frames. + + :class:`Assembler` expects only data frames. The stream of frames must + respect the protocol; if it doesn't, the behavior is undefined. + + Args: + pause: Called when the buffer of frames goes above the high water mark; + should pause reading from the network. + resume: Called when the buffer of frames goes below the low water mark; + should resume reading from the network. + + """ + + def __init__( + self, + high: int | None = None, + low: int | None = None, + pause: Callable[[], Any] = lambda: None, + resume: Callable[[], Any] = lambda: None, + ) -> None: + # Queue of incoming frames. + self.frames: SimpleQueue[Frame] = SimpleQueue() + + # We cannot put a hard limit on the size of the queue because a single + # call to Protocol.data_received() could produce thousands of frames, + # which must be buffered. Instead, we pause reading when the buffer goes + # above the high limit and we resume when it goes under the low limit. + if high is not None and low is None: + low = high // 4 + if high is None and low is not None: + high = low * 4 + if high is not None and low is not None: + if low < 0: + raise ValueError("low must be positive or equal to zero") + if high < low: + raise ValueError("high must be greater than or equal to low") + self.high, self.low = high, low + self.pause = pause + self.resume = resume + self.paused = False + + # This flag prevents concurrent calls to get() by user code. + self.get_in_progress = False + + # This flag marks the end of the connection. + self.closed = False + + @overload + async def get(self, decode: Literal[True]) -> str: ... + + @overload + async def get(self, decode: Literal[False]) -> bytes: ... + + @overload + async def get(self, decode: bool | None = None) -> Data: ... + + async def get(self, decode: bool | None = None) -> Data: + """ + Read the next message. + + :meth:`get` returns a single :class:`str` or :class:`bytes`. + + If the message is fragmented, :meth:`get` waits until the last frame is + received, then it reassembles the message and returns it. To receive + messages frame by frame, use :meth:`get_iter` instead. + + Args: + decode: :obj:`False` disables UTF-8 decoding of text frames and + returns :class:`bytes`. :obj:`True` forces UTF-8 decoding of + binary frames and returns :class:`str`. + + Raises: + EOFError: If the stream of frames has ended. + UnicodeDecodeError: If a text frame contains invalid UTF-8. + ConcurrencyError: If two coroutines run :meth:`get` or + :meth:`get_iter` concurrently. + + """ + if self.get_in_progress: + raise ConcurrencyError("get() or get_iter() is already running") + self.get_in_progress = True + + # Locking with get_in_progress prevents concurrent execution + # until get() fetches a complete message or is canceled. + + try: + # Fetch the first frame. + frame = await self.frames.get(not self.closed) + self.maybe_resume() + assert frame.opcode is OP_TEXT or frame.opcode is OP_BINARY + if decode is None: + decode = frame.opcode is OP_TEXT + frames = [frame] + + # Fetch subsequent frames for fragmented messages. + while not frame.fin: + try: + frame = await self.frames.get(not self.closed) + except asyncio.CancelledError: + # Put frames already received back into the queue + # so that future calls to get() can return them. + self.frames.reset(frames) + raise + self.maybe_resume() + assert frame.opcode is OP_CONT + frames.append(frame) + + finally: + self.get_in_progress = False + + # This converts frame.data to bytes when it's a bytearray. + data = b"".join(frame.data for frame in frames) + if decode: + return data.decode() + else: + return data + + @overload + def get_iter(self, decode: Literal[True]) -> AsyncIterator[str]: ... + + @overload + def get_iter(self, decode: Literal[False]) -> AsyncIterator[bytes]: ... + + @overload + def get_iter(self, decode: bool | None = None) -> AsyncIterator[Data]: ... + + async def get_iter(self, decode: bool | None = None) -> AsyncIterator[Data]: + """ + Stream the next message. + + Iterating the return value of :meth:`get_iter` asynchronously yields a + :class:`str` or :class:`bytes` for each frame in the message. + + The iterator must be fully consumed before calling :meth:`get_iter` or + :meth:`get` again. Else, :exc:`ConcurrencyError` is raised. + + This method only makes sense for fragmented messages. If messages aren't + fragmented, use :meth:`get` instead. + + Args: + decode: :obj:`False` disables UTF-8 decoding of text frames and + returns :class:`bytes`. :obj:`True` forces UTF-8 decoding of + binary frames and returns :class:`str`. + + Raises: + EOFError: If the stream of frames has ended. + UnicodeDecodeError: If a text frame contains invalid UTF-8. + ConcurrencyError: If two coroutines run :meth:`get` or + :meth:`get_iter` concurrently. + + """ + if self.get_in_progress: + raise ConcurrencyError("get() or get_iter() is already running") + self.get_in_progress = True + + # Locking with get_in_progress prevents concurrent execution + # until get_iter() fetches a complete message or is canceled. + + # If get_iter() raises an exception e.g. in decoder.decode(), + # get_in_progress remains set and the connection becomes unusable. + + # Yield the first frame. + try: + frame = await self.frames.get(not self.closed) + except asyncio.CancelledError: + self.get_in_progress = False + raise + self.maybe_resume() + assert frame.opcode is OP_TEXT or frame.opcode is OP_BINARY + if decode is None: + decode = frame.opcode is OP_TEXT + if decode: + decoder = UTF8Decoder() + yield decoder.decode(frame.data, frame.fin) + else: + # Convert to bytes when frame.data is a bytearray. + yield bytes(frame.data) + + # Yield subsequent frames for fragmented messages. + while not frame.fin: + # We cannot handle asyncio.CancelledError because we don't buffer + # previous fragments β€” we're streaming them. Canceling get_iter() + # here will leave the assembler in a stuck state. Future calls to + # get() or get_iter() will raise ConcurrencyError. + frame = await self.frames.get(not self.closed) + self.maybe_resume() + assert frame.opcode is OP_CONT + if decode: + yield decoder.decode(frame.data, frame.fin) + else: + # Convert to bytes when frame.data is a bytearray. + yield bytes(frame.data) + + self.get_in_progress = False + + def put(self, frame: Frame) -> None: + """ + Add ``frame`` to the next message. + + Raises: + EOFError: If the stream of frames has ended. + + """ + if self.closed: + raise EOFError("stream of frames ended") + + self.frames.put(frame) + self.maybe_pause() + + def maybe_pause(self) -> None: + """Pause the writer if queue is above the high water mark.""" + # Skip if flow control is disabled. + if self.high is None: + return + + # Check for "> high" to support high = 0. + if len(self.frames) > self.high and not self.paused: + self.paused = True + self.pause() + + def maybe_resume(self) -> None: + """Resume the writer if queue is below the low water mark.""" + # Skip if flow control is disabled. + if self.low is None: + return + + # Check for "<= low" to support low = 0. + if len(self.frames) <= self.low and self.paused: + self.paused = False + self.resume() + + def close(self) -> None: + """ + End the stream of frames. + + Calling :meth:`close` concurrently with :meth:`get`, :meth:`get_iter`, + or :meth:`put` is safe. They will raise :exc:`EOFError`. + + """ + if self.closed: + return + + self.closed = True + + # Unblock get() or get_iter(). + self.frames.abort() diff --git a/.venv/Lib/site-packages/websockets/asyncio/router.py b/.venv/Lib/site-packages/websockets/asyncio/router.py new file mode 100644 index 0000000000000000000000000000000000000000..97da471f0b1f775ddf474a3c16b7db326f629086 --- /dev/null +++ b/.venv/Lib/site-packages/websockets/asyncio/router.py @@ -0,0 +1,219 @@ +from __future__ import annotations + +import http +import ssl as ssl_module +import urllib.parse +from typing import Any, Awaitable, Callable, Literal + +from ..http11 import Request, Response +from .server import Server, ServerConnection, serve + + +__all__ = ["route", "unix_route", "Router"] + + +try: + from werkzeug.exceptions import NotFound + from werkzeug.routing import Map, RequestRedirect + +except ImportError: + + def route( + url_map: Map, + *args: Any, + server_name: str | None = None, + ssl: ssl_module.SSLContext | Literal[True] | None = None, + create_router: type[Router] | None = None, + **kwargs: Any, + ) -> Awaitable[Server]: + raise ImportError("route() requires werkzeug") + + def unix_route( + url_map: Map, + path: str | None = None, + **kwargs: Any, + ) -> Awaitable[Server]: + raise ImportError("unix_route() requires werkzeug") + +else: + + def route( + url_map: Map, + *args: Any, + server_name: str | None = None, + ssl: ssl_module.SSLContext | Literal[True] | None = None, + create_router: type[Router] | None = None, + **kwargs: Any, + ) -> Awaitable[Server]: + """ + Create a WebSocket server dispatching connections to different handlers. + + This feature requires the third-party library `werkzeug`_: + + .. code-block:: console + + $ pip install werkzeug + + .. _werkzeug: https://werkzeug.palletsprojects.com/ + + :func:`route` accepts the same arguments as + :func:`~websockets.sync.server.serve`, except as described below. + + The first argument is a :class:`werkzeug.routing.Map` that maps URL patterns + to connection handlers. In addition to the connection, handlers receive + parameters captured in the URL as keyword arguments. + + Here's an example:: + + + from websockets.asyncio.router import route + from werkzeug.routing import Map, Rule + + async def channel_handler(websocket, channel_id): + ... + + url_map = Map([ + Rule("/channel/", endpoint=channel_handler), + ... + ]) + + # set this future to exit the server + stop = asyncio.get_running_loop().create_future() + + async with route(url_map, ...) as server: + await stop + + + Refer to the documentation of :mod:`werkzeug.routing` for details. + + If you define redirects with ``Rule(..., redirect_to=...)`` in the URL map, + when the server runs behind a reverse proxy that modifies the ``Host`` + header or terminates TLS, you need additional configuration: + + * Set ``server_name`` to the name of the server as seen by clients. When + not provided, websockets uses the value of the ``Host`` header. + + * Set ``ssl=True`` to generate ``wss://`` URIs without enabling TLS. + Under the hood, this bind the URL map with a ``url_scheme`` of + ``wss://`` instead of ``ws://``. + + There is no need to specify ``websocket=True`` in each rule. It is added + automatically. + + Args: + url_map: Mapping of URL patterns to connection handlers. + server_name: Name of the server as seen by clients. If :obj:`None`, + websockets uses the value of the ``Host`` header. + ssl: Configuration for enabling TLS on the connection. Set it to + :obj:`True` if a reverse proxy terminates TLS connections. + create_router: Factory for the :class:`Router` dispatching requests to + handlers. Set it to a wrapper or a subclass to customize routing. + + """ + url_scheme = "ws" if ssl is None else "wss" + if ssl is not True and ssl is not None: + kwargs["ssl"] = ssl + + if create_router is None: + create_router = Router + + router = create_router(url_map, server_name, url_scheme) + + _process_request: ( + Callable[ + [ServerConnection, Request], + Awaitable[Response | None] | Response | None, + ] + | None + ) = kwargs.pop("process_request", None) + if _process_request is None: + process_request: Callable[ + [ServerConnection, Request], + Awaitable[Response | None] | Response | None, + ] = router.route_request + else: + + async def process_request( + connection: ServerConnection, request: Request + ) -> Response | None: + response = _process_request(connection, request) + if isinstance(response, Awaitable): + response = await response + if response is not None: + return response + return router.route_request(connection, request) + + return serve(router.handler, *args, process_request=process_request, **kwargs) + + def unix_route( + url_map: Map, + path: str | None = None, + **kwargs: Any, + ) -> Awaitable[Server]: + """ + Create a WebSocket Unix server dispatching connections to different handlers. + + :func:`unix_route` combines the behaviors of :func:`route` and + :func:`~websockets.asyncio.server.unix_serve`. + + Args: + url_map: Mapping of URL patterns to connection handlers. + path: File system path to the Unix socket. + + """ + return route(url_map, unix=True, path=path, **kwargs) + + +class Router: + """WebSocket router supporting :func:`route`.""" + + def __init__( + self, + url_map: Map, + server_name: str | None = None, + url_scheme: str = "ws", + ) -> None: + self.url_map = url_map + self.server_name = server_name + self.url_scheme = url_scheme + for rule in self.url_map.iter_rules(): + rule.websocket = True + + def get_server_name(self, connection: ServerConnection, request: Request) -> str: + if self.server_name is None: + return request.headers["Host"] + else: + return self.server_name + + def redirect(self, connection: ServerConnection, url: str) -> Response: + response = connection.respond(http.HTTPStatus.FOUND, f"Found at {url}") + response.headers["Location"] = url + return response + + def not_found(self, connection: ServerConnection) -> Response: + return connection.respond(http.HTTPStatus.NOT_FOUND, "Not Found") + + def route_request( + self, connection: ServerConnection, request: Request + ) -> Response | None: + """Route incoming request.""" + url_map_adapter = self.url_map.bind( + server_name=self.get_server_name(connection, request), + url_scheme=self.url_scheme, + ) + try: + parsed = urllib.parse.urlparse(request.path) + handler, kwargs = url_map_adapter.match( + path_info=parsed.path, + query_args=parsed.query, + ) + except RequestRedirect as redirect: + return self.redirect(connection, redirect.new_url) + except NotFound: + return self.not_found(connection) + connection.handler, connection.handler_kwargs = handler, kwargs + return None + + async def handler(self, connection: ServerConnection) -> None: + """Handle a connection.""" + return await connection.handler(connection, **connection.handler_kwargs) diff --git a/.venv/Lib/site-packages/websockets/asyncio/server.py b/.venv/Lib/site-packages/websockets/asyncio/server.py new file mode 100644 index 0000000000000000000000000000000000000000..b78d7dc20b73f2a2fac377502c6de61f5f92c04d --- /dev/null +++ b/.venv/Lib/site-packages/websockets/asyncio/server.py @@ -0,0 +1,997 @@ +from __future__ import annotations + +import asyncio +import hmac +import http +import logging +import re +import socket +import sys +from collections.abc import Awaitable, Generator, Iterable, Sequence +from types import TracebackType +from typing import Any, Callable, Mapping, cast + +from ..exceptions import InvalidHeader +from ..extensions.base import ServerExtensionFactory +from ..extensions.permessage_deflate import enable_server_permessage_deflate +from ..frames import CloseCode +from ..headers import ( + build_www_authenticate_basic, + parse_authorization_basic, + validate_subprotocols, +) +from ..http11 import SERVER, Request, Response +from ..protocol import CONNECTING, OPEN, Event +from ..server import ServerProtocol +from ..typing import LoggerLike, Origin, StatusLike, Subprotocol +from .compatibility import asyncio_timeout +from .connection import Connection, broadcast + + +__all__ = [ + "broadcast", + "serve", + "unix_serve", + "ServerConnection", + "Server", + "basic_auth", +] + + +class ServerConnection(Connection): + """ + :mod:`asyncio` implementation of a WebSocket server connection. + + :class:`ServerConnection` provides :meth:`recv` and :meth:`send` methods for + receiving and sending messages. + + It supports asynchronous iteration to receive messages:: + + async for message in websocket: + await process(message) + + The iterator exits normally when the connection is closed with code + 1000 (OK) or 1001 (going away) or without a close code. It raises a + :exc:`~websockets.exceptions.ConnectionClosedError` when the connection is + closed with any other code. + + The ``ping_interval``, ``ping_timeout``, ``close_timeout``, ``max_queue``, + and ``write_limit`` arguments have the same meaning as in :func:`serve`. + + Args: + protocol: Sans-I/O connection. + server: Server that manages this connection. + + """ + + def __init__( + self, + protocol: ServerProtocol, + server: Server, + *, + ping_interval: float | None = 20, + ping_timeout: float | None = 20, + close_timeout: float | None = 10, + max_queue: int | None | tuple[int | None, int | None] = 16, + write_limit: int | tuple[int, int | None] = 2**15, + ) -> None: + self.protocol: ServerProtocol + super().__init__( + protocol, + ping_interval=ping_interval, + ping_timeout=ping_timeout, + close_timeout=close_timeout, + max_queue=max_queue, + write_limit=write_limit, + ) + self.server = server + self.request_rcvd: asyncio.Future[None] = self.loop.create_future() + self.username: str # see basic_auth() + self.handler: Callable[[ServerConnection], Awaitable[None]] # see route() + self.handler_kwargs: Mapping[str, Any] # see route() + + def respond(self, status: StatusLike, text: str) -> Response: + """ + Create a plain text HTTP response. + + ``process_request`` and ``process_response`` may call this method to + return an HTTP response instead of performing the WebSocket opening + handshake. + + You can modify the response before returning it, for example by changing + HTTP headers. + + Args: + status: HTTP status code. + text: HTTP response body; it will be encoded to UTF-8. + + Returns: + HTTP response to send to the client. + + """ + return self.protocol.reject(status, text) + + async def handshake( + self, + process_request: ( + Callable[ + [ServerConnection, Request], + Awaitable[Response | None] | Response | None, + ] + | None + ) = None, + process_response: ( + Callable[ + [ServerConnection, Request, Response], + Awaitable[Response | None] | Response | None, + ] + | None + ) = None, + server_header: str | None = SERVER, + ) -> None: + """ + Perform the opening handshake. + + """ + await asyncio.wait( + [self.request_rcvd, self.connection_lost_waiter], + return_when=asyncio.FIRST_COMPLETED, + ) + + if self.request is not None: + async with self.send_context(expected_state=CONNECTING): + response = None + + if process_request is not None: + try: + response = process_request(self, self.request) + if isinstance(response, Awaitable): + response = await response + except Exception as exc: + self.protocol.handshake_exc = exc + response = self.protocol.reject( + http.HTTPStatus.INTERNAL_SERVER_ERROR, + ( + "Failed to open a WebSocket connection.\n" + "See server log for more information.\n" + ), + ) + + if response is None: + if self.server.is_serving(): + self.response = self.protocol.accept(self.request) + else: + self.response = self.protocol.reject( + http.HTTPStatus.SERVICE_UNAVAILABLE, + "Server is shutting down.\n", + ) + else: + assert isinstance(response, Response) # help mypy + self.response = response + + if server_header: + self.response.headers["Server"] = server_header + + response = None + + if process_response is not None: + try: + response = process_response(self, self.request, self.response) + if isinstance(response, Awaitable): + response = await response + except Exception as exc: + self.protocol.handshake_exc = exc + response = self.protocol.reject( + http.HTTPStatus.INTERNAL_SERVER_ERROR, + ( + "Failed to open a WebSocket connection.\n" + "See server log for more information.\n" + ), + ) + + if response is not None: + assert isinstance(response, Response) # help mypy + self.response = response + + self.protocol.send_response(self.response) + + # self.protocol.handshake_exc is set when the connection is lost before + # receiving a request, when the request cannot be parsed, or when the + # handshake fails, including when process_request or process_response + # raises an exception. + + # It isn't set when process_request or process_response sends an HTTP + # response that rejects the handshake. + + if self.protocol.handshake_exc is not None: + raise self.protocol.handshake_exc + + def process_event(self, event: Event) -> None: + """ + Process one incoming event. + + """ + # First event - handshake request. + if self.request is None: + assert isinstance(event, Request) + self.request = event + self.request_rcvd.set_result(None) + # Later events - frames. + else: + super().process_event(event) + + def connection_made(self, transport: asyncio.BaseTransport) -> None: + super().connection_made(transport) + self.server.start_connection_handler(self) + + +class Server: + """ + WebSocket server returned by :func:`serve`. + + This class mirrors the API of :class:`asyncio.Server`. + + It keeps track of WebSocket connections in order to close them properly + when shutting down. + + Args: + handler: Connection handler. It receives the WebSocket connection, + which is a :class:`ServerConnection`, in argument. + process_request: Intercept the request during the opening handshake. + Return an HTTP response to force the response. Return :obj:`None` to + continue normally. When you force an HTTP 101 Continue response, the + handshake is successful. Else, the connection is aborted. + ``process_request`` may be a function or a coroutine. + process_response: Intercept the response during the opening handshake. + Modify the response or return a new HTTP response to force the + response. Return :obj:`None` to continue normally. When you force an + HTTP 101 Continue response, the handshake is successful. Else, the + connection is aborted. ``process_response`` may be a function or a + coroutine. + server_header: Value of the ``Server`` response header. + It defaults to ``"Python/x.y.z websockets/X.Y"``. Setting it to + :obj:`None` removes the header. + open_timeout: Timeout for opening connections in seconds. + :obj:`None` disables the timeout. + logger: Logger for this server. + It defaults to ``logging.getLogger("websockets.server")``. + See the :doc:`logging guide <../../topics/logging>` for details. + + """ + + def __init__( + self, + handler: Callable[[ServerConnection], Awaitable[None]], + *, + process_request: ( + Callable[ + [ServerConnection, Request], + Awaitable[Response | None] | Response | None, + ] + | None + ) = None, + process_response: ( + Callable[ + [ServerConnection, Request, Response], + Awaitable[Response | None] | Response | None, + ] + | None + ) = None, + server_header: str | None = SERVER, + open_timeout: float | None = 10, + logger: LoggerLike | None = None, + ) -> None: + self.loop = asyncio.get_running_loop() + self.handler = handler + self.process_request = process_request + self.process_response = process_response + self.server_header = server_header + self.open_timeout = open_timeout + if logger is None: + logger = logging.getLogger("websockets.server") + self.logger = logger + + # Keep track of active connections. + self.handlers: dict[ServerConnection, asyncio.Task[None]] = {} + + # Task responsible for closing the server and terminating connections. + self.close_task: asyncio.Task[None] | None = None + + # Completed when the server is closed and connections are terminated. + self.closed_waiter: asyncio.Future[None] = self.loop.create_future() + + @property + def connections(self) -> set[ServerConnection]: + """ + Set of active connections. + + This property contains all connections that completed the opening + handshake successfully and didn't start the closing handshake yet. + It can be useful in combination with :func:`~broadcast`. + + """ + return {connection for connection in self.handlers if connection.state is OPEN} + + def wrap(self, server: asyncio.Server) -> None: + """ + Attach to a given :class:`asyncio.Server`. + + Since :meth:`~asyncio.loop.create_server` doesn't support injecting a + custom ``Server`` class, the easiest solution that doesn't rely on + private :mod:`asyncio` APIs is to: + + - instantiate a :class:`Server` + - give the protocol factory a reference to that instance + - call :meth:`~asyncio.loop.create_server` with the factory + - attach the resulting :class:`asyncio.Server` with this method + + """ + self.server = server + for sock in server.sockets: + if sock.family == socket.AF_INET: + name = "%s:%d" % sock.getsockname() + elif sock.family == socket.AF_INET6: + name = "[%s]:%d" % sock.getsockname()[:2] + elif sock.family == socket.AF_UNIX: + name = sock.getsockname() + # In the unlikely event that someone runs websockets over a + # protocol other than IP or Unix sockets, avoid crashing. + else: # pragma: no cover + name = str(sock.getsockname()) + self.logger.info("server listening on %s", name) + + async def conn_handler(self, connection: ServerConnection) -> None: + """ + Handle the lifecycle of a WebSocket connection. + + Since this method doesn't have a caller that can handle exceptions, + it attempts to log relevant ones. + + It guarantees that the TCP connection is closed before exiting. + + """ + try: + async with asyncio_timeout(self.open_timeout): + try: + await connection.handshake( + self.process_request, + self.process_response, + self.server_header, + ) + except asyncio.CancelledError: + connection.transport.abort() + raise + except Exception: + connection.logger.error("opening handshake failed", exc_info=True) + connection.transport.abort() + return + + if connection.protocol.state is not OPEN: + # process_request or process_response rejected the handshake. + connection.transport.abort() + return + + try: + connection.start_keepalive() + await self.handler(connection) + except Exception: + connection.logger.error("connection handler failed", exc_info=True) + await connection.close(CloseCode.INTERNAL_ERROR) + else: + await connection.close() + + except TimeoutError: + # When the opening handshake times out, there's nothing to log. + pass + + except Exception: # pragma: no cover + # Don't leak connections on unexpected errors. + connection.transport.abort() + + finally: + # Registration is tied to the lifecycle of conn_handler() because + # the server waits for connection handlers to terminate, even if + # all connections are already closed. + del self.handlers[connection] + + def start_connection_handler(self, connection: ServerConnection) -> None: + """ + Register a connection with this server. + + """ + # The connection must be registered in self.handlers immediately. + # If it was registered in conn_handler(), a race condition could + # happen when closing the server after scheduling conn_handler() + # but before it starts executing. + self.handlers[connection] = self.loop.create_task(self.conn_handler(connection)) + + def close( + self, + close_connections: bool = True, + code: CloseCode | int = CloseCode.GOING_AWAY, + reason: str = "", + ) -> None: + """ + Close the server. + + * Close the underlying :class:`asyncio.Server`. + * When ``close_connections`` is :obj:`True`, which is the default, close + existing connections. Specifically: + + * Reject opening WebSocket connections with an HTTP 503 (service + unavailable) error. This happens when the server accepted the TCP + connection but didn't complete the opening handshake before closing. + * Close open WebSocket connections with code 1001 (going away). + ``code`` and ``reason`` can be customized, for example to use code + 1012 (service restart). + + * Wait until all connection handlers terminate. + + :meth:`close` is idempotent. + + """ + if self.close_task is None: + self.close_task = self.get_loop().create_task( + self._close(close_connections, code, reason) + ) + + async def _close( + self, + close_connections: bool = True, + code: CloseCode | int = CloseCode.GOING_AWAY, + reason: str = "", + ) -> None: + """ + Implementation of :meth:`close`. + + This calls :meth:`~asyncio.Server.close` on the underlying + :class:`asyncio.Server` object to stop accepting new connections and + then closes open connections. + + """ + self.logger.info("server closing") + + # Stop accepting new connections. + self.server.close() + + # Wait until all accepted connections reach connection_made() and call + # register(). See https://github.com/python/cpython/issues/79033 for + # details. This workaround can be removed when dropping Python < 3.11. + await asyncio.sleep(0) + + # After server.close(), handshake() closes OPENING connections with an + # HTTP 503 error. + + if close_connections: + # Close OPEN connections with code 1001 by default. + close_tasks = [ + asyncio.create_task(connection.close(code, reason)) + for connection in self.handlers + if connection.protocol.state is not CONNECTING + ] + # asyncio.wait doesn't accept an empty first argument. + if close_tasks: + await asyncio.wait(close_tasks) + + # Wait until all TCP connections are closed. + await self.server.wait_closed() + + # Wait until all connection handlers terminate. + # asyncio.wait doesn't accept an empty first argument. + if self.handlers: + await asyncio.wait(self.handlers.values()) + + # Tell wait_closed() to return. + self.closed_waiter.set_result(None) + + self.logger.info("server closed") + + async def wait_closed(self) -> None: + """ + Wait until the server is closed. + + When :meth:`wait_closed` returns, all TCP connections are closed and + all connection handlers have returned. + + To ensure a fast shutdown, a connection handler should always be + awaiting at least one of: + + * :meth:`~ServerConnection.recv`: when the connection is closed, + it raises :exc:`~websockets.exceptions.ConnectionClosedOK`; + * :meth:`~ServerConnection.wait_closed`: when the connection is + closed, it returns. + + Then the connection handler is immediately notified of the shutdown; + it can clean up and exit. + + """ + await asyncio.shield(self.closed_waiter) + + def get_loop(self) -> asyncio.AbstractEventLoop: + """ + See :meth:`asyncio.Server.get_loop`. + + """ + return self.server.get_loop() + + def is_serving(self) -> bool: # pragma: no cover + """ + See :meth:`asyncio.Server.is_serving`. + + """ + return self.server.is_serving() + + async def start_serving(self) -> None: # pragma: no cover + """ + See :meth:`asyncio.Server.start_serving`. + + Typical use:: + + server = await serve(..., start_serving=False) + # perform additional setup here... + # ... then start the server + await server.start_serving() + + """ + await self.server.start_serving() + + async def serve_forever(self) -> None: # pragma: no cover + """ + See :meth:`asyncio.Server.serve_forever`. + + Typical use:: + + server = await serve(...) + # this coroutine doesn't return + # canceling it stops the server + await server.serve_forever() + + This is an alternative to using :func:`serve` as an asynchronous context + manager. Shutdown is triggered by canceling :meth:`serve_forever` + instead of exiting a :func:`serve` context. + + """ + await self.server.serve_forever() + + @property + def sockets(self) -> tuple[socket.socket, ...]: + """ + See :attr:`asyncio.Server.sockets`. + + """ + return self.server.sockets + + async def __aenter__(self) -> Server: # pragma: no cover + return self + + async def __aexit__( + self, + exc_type: type[BaseException] | None, + exc_value: BaseException | None, + traceback: TracebackType | None, + ) -> None: # pragma: no cover + self.close() + await self.wait_closed() + + +# This is spelled in lower case because it's exposed as a callable in the API. +class serve: + """ + Create a WebSocket server listening on ``host`` and ``port``. + + Whenever a client connects, the server creates a :class:`ServerConnection`, + performs the opening handshake, and delegates to the ``handler`` coroutine. + + The handler receives the :class:`ServerConnection` instance, which you can + use to send and receive messages. + + Once the handler completes, either normally or with an exception, the server + performs the closing handshake and closes the connection. + + This coroutine returns a :class:`Server` whose API mirrors + :class:`asyncio.Server`. Treat it as an asynchronous context manager to + ensure that the server will be closed:: + + from websockets.asyncio.server import serve + + def handler(websocket): + ... + + # set this future to exit the server + stop = asyncio.get_running_loop().create_future() + + async with serve(handler, host, port): + await stop + + Alternatively, call :meth:`~Server.serve_forever` to serve requests and + cancel it to stop the server:: + + server = await serve(handler, host, port) + await server.serve_forever() + + Args: + handler: Connection handler. It receives the WebSocket connection, + which is a :class:`ServerConnection`, in argument. + host: Network interfaces the server binds to. + See :meth:`~asyncio.loop.create_server` for details. + port: TCP port the server listens on. + See :meth:`~asyncio.loop.create_server` for details. + origins: Acceptable values of the ``Origin`` header, for defending + against Cross-Site WebSocket Hijacking attacks. Values can be + :class:`str` to test for an exact match or regular expressions + compiled by :func:`re.compile` to test against a pattern. Include + :obj:`None` in the list if the lack of an origin is acceptable. + extensions: List of supported extensions, in order in which they + should be negotiated and run. + subprotocols: List of supported subprotocols, in order of decreasing + preference. + select_subprotocol: Callback for selecting a subprotocol among + those supported by the client and the server. It receives a + :class:`ServerConnection` (not a + :class:`~websockets.server.ServerProtocol`!) instance and a list of + subprotocols offered by the client. Other than the first argument, + it has the same behavior as the + :meth:`ServerProtocol.select_subprotocol + ` method. + compression: The "permessage-deflate" extension is enabled by default. + Set ``compression`` to :obj:`None` to disable it. See the + :doc:`compression guide <../../topics/compression>` for details. + process_request: Intercept the request during the opening handshake. + Return an HTTP response to force the response or :obj:`None` to + continue normally. When you force an HTTP 101 Continue response, the + handshake is successful. Else, the connection is aborted. + ``process_request`` may be a function or a coroutine. + process_response: Intercept the response during the opening handshake. + Return an HTTP response to force the response or :obj:`None` to + continue normally. When you force an HTTP 101 Continue response, the + handshake is successful. Else, the connection is aborted. + ``process_response`` may be a function or a coroutine. + server_header: Value of the ``Server`` response header. + It defaults to ``"Python/x.y.z websockets/X.Y"``. Setting it to + :obj:`None` removes the header. + open_timeout: Timeout for opening connections in seconds. + :obj:`None` disables the timeout. + ping_interval: Interval between keepalive pings in seconds. + :obj:`None` disables keepalive. + ping_timeout: Timeout for keepalive pings in seconds. + :obj:`None` disables timeouts. + close_timeout: Timeout for closing connections in seconds. + :obj:`None` disables the timeout. + max_size: Maximum size of incoming messages in bytes. + :obj:`None` disables the limit. You may pass a ``(max_message_size, + max_fragment_size)`` tuple to set different limits for messages and + fragments when you expect long messages sent in short fragments. + max_queue: High-water mark of the buffer where frames are received. + It defaults to 16 frames. The low-water mark defaults to ``max_queue + // 4``. You may pass a ``(high, low)`` tuple to set the high-water + and low-water marks. If you want to disable flow control entirely, + you may set it to ``None``, although that's a bad idea. + write_limit: High-water mark of write buffer in bytes. It is passed to + :meth:`~asyncio.WriteTransport.set_write_buffer_limits`. It defaults + to 32Β KiB. You may pass a ``(high, low)`` tuple to set the + high-water and low-water marks. + logger: Logger for this server. + It defaults to ``logging.getLogger("websockets.server")``. See the + :doc:`logging guide <../../topics/logging>` for details. + create_connection: Factory for the :class:`ServerConnection` managing + the connection. Set it to a wrapper or a subclass to customize + connection handling. + + Any other keyword arguments are passed to the event loop's + :meth:`~asyncio.loop.create_server` method. + + For example: + + * You can set ``ssl`` to a :class:`~ssl.SSLContext` to enable TLS. + + * You can set ``sock`` to provide a preexisting TCP socket. You may call + :func:`socket.create_server` (not to be confused with the event loop's + :meth:`~asyncio.loop.create_server` method) to create a suitable server + socket and customize it. + + * You can set ``start_serving`` to ``False`` to start accepting connections + only after you call :meth:`~Server.start_serving()` or + :meth:`~Server.serve_forever()`. + + """ + + def __init__( + self, + handler: Callable[[ServerConnection], Awaitable[None]], + host: str | None = None, + port: int | None = None, + *, + # WebSocket + origins: Sequence[Origin | re.Pattern[str] | None] | None = None, + extensions: Sequence[ServerExtensionFactory] | None = None, + subprotocols: Sequence[Subprotocol] | None = None, + select_subprotocol: ( + Callable[ + [ServerConnection, Sequence[Subprotocol]], + Subprotocol | None, + ] + | None + ) = None, + compression: str | None = "deflate", + # HTTP + process_request: ( + Callable[ + [ServerConnection, Request], + Awaitable[Response | None] | Response | None, + ] + | None + ) = None, + process_response: ( + Callable[ + [ServerConnection, Request, Response], + Awaitable[Response | None] | Response | None, + ] + | None + ) = None, + server_header: str | None = SERVER, + # Timeouts + open_timeout: float | None = 10, + ping_interval: float | None = 20, + ping_timeout: float | None = 20, + close_timeout: float | None = 10, + # Limits + max_size: int | None | tuple[int | None, int | None] = 2**20, + max_queue: int | None | tuple[int | None, int | None] = 16, + write_limit: int | tuple[int, int | None] = 2**15, + # Logging + logger: LoggerLike | None = None, + # Escape hatch for advanced customization + create_connection: type[ServerConnection] | None = None, + # Other keyword arguments are passed to loop.create_server + **kwargs: Any, + ) -> None: + if subprotocols is not None: + validate_subprotocols(subprotocols) + + if compression == "deflate": + extensions = enable_server_permessage_deflate(extensions) + elif compression is not None: + raise ValueError(f"unsupported compression: {compression}") + + if create_connection is None: + create_connection = ServerConnection + + self.server = Server( + handler, + process_request=process_request, + process_response=process_response, + server_header=server_header, + open_timeout=open_timeout, + logger=logger, + ) + + if kwargs.get("ssl") is not None: + kwargs.setdefault("ssl_handshake_timeout", open_timeout) + if sys.version_info[:2] >= (3, 11): # pragma: no branch + kwargs.setdefault("ssl_shutdown_timeout", close_timeout) + + def factory() -> ServerConnection: + """ + Create an asyncio protocol for managing a WebSocket connection. + + """ + # Create a closure to give select_subprotocol access to connection. + protocol_select_subprotocol: ( + Callable[ + [ServerProtocol, Sequence[Subprotocol]], + Subprotocol | None, + ] + | None + ) = None + if select_subprotocol is not None: + + def protocol_select_subprotocol( + protocol: ServerProtocol, + subprotocols: Sequence[Subprotocol], + ) -> Subprotocol | None: + # mypy doesn't know that select_subprotocol is immutable. + assert select_subprotocol is not None + # Ensure this function is only used in the intended context. + assert protocol is connection.protocol + return select_subprotocol(connection, subprotocols) + + # This is a protocol in the Sans-I/O implementation of websockets. + protocol = ServerProtocol( + origins=origins, + extensions=extensions, + subprotocols=subprotocols, + select_subprotocol=protocol_select_subprotocol, + max_size=max_size, + logger=logger, + ) + # This is a connection in websockets and a protocol in asyncio. + connection = create_connection( + protocol, + self.server, + ping_interval=ping_interval, + ping_timeout=ping_timeout, + close_timeout=close_timeout, + max_queue=max_queue, + write_limit=write_limit, + ) + return connection + + loop = asyncio.get_running_loop() + if kwargs.pop("unix", False): + self.create_server = loop.create_unix_server(factory, **kwargs) + else: + # mypy cannot tell that kwargs must provide sock when port is None. + self.create_server = loop.create_server(factory, host, port, **kwargs) # type: ignore[arg-type] + + # async with serve(...) as ...: ... + + async def __aenter__(self) -> Server: + return await self + + async def __aexit__( + self, + exc_type: type[BaseException] | None, + exc_value: BaseException | None, + traceback: TracebackType | None, + ) -> None: + self.server.close() + await self.server.wait_closed() + + # ... = await serve(...) + + def __await__(self) -> Generator[Any, None, Server]: + # Create a suitable iterator by calling __await__ on a coroutine. + return self.__await_impl__().__await__() + + async def __await_impl__(self) -> Server: + server = await self.create_server + self.server.wrap(server) + return self.server + + # ... = yield from serve(...) - remove when dropping Python < 3.11 + + __iter__ = __await__ + + +def unix_serve( + handler: Callable[[ServerConnection], Awaitable[None]], + path: str | None = None, + **kwargs: Any, +) -> Awaitable[Server]: + """ + Create a WebSocket server listening on a Unix socket. + + This function is identical to :func:`serve`, except the ``host`` and + ``port`` arguments are replaced by ``path``. It's only available on Unix. + + It's useful for deploying a server behind a reverse proxy such as nginx. + + Args: + handler: Connection handler. It receives the WebSocket connection, + which is a :class:`ServerConnection`, in argument. + path: File system path to the Unix socket. + + """ + return serve(handler, unix=True, path=path, **kwargs) + + +def is_credentials(credentials: Any) -> bool: + try: + username, password = credentials + except (TypeError, ValueError): + return False + else: + return isinstance(username, str) and isinstance(password, str) + + +def basic_auth( + realm: str = "", + credentials: tuple[str, str] | Iterable[tuple[str, str]] | None = None, + check_credentials: Callable[[str, str], Awaitable[bool] | bool] | None = None, +) -> Callable[[ServerConnection, Request], Awaitable[Response | None]]: + """ + Factory for ``process_request`` to enforce HTTP Basic Authentication. + + :func:`basic_auth` is designed to integrate with :func:`serve` as follows:: + + from websockets.asyncio.server import basic_auth, serve + + async with serve( + ..., + process_request=basic_auth( + realm="my dev server", + credentials=("hello", "iloveyou"), + ), + ): + + If authentication succeeds, the connection's ``username`` attribute is set. + If it fails, the server responds with an HTTP 401 Unauthorized status. + + One of ``credentials`` or ``check_credentials`` must be provided; not both. + + Args: + realm: Scope of protection. It should contain only ASCII characters + because the encoding of non-ASCII characters is undefined. Refer to + section 2.2 of :rfc:`7235` for details. + credentials: Hard coded authorized credentials. It can be a + ``(username, password)`` pair or a list of such pairs. + check_credentials: Function or coroutine that verifies credentials. + It receives ``username`` and ``password`` arguments and returns + whether they're valid. + Raises: + TypeError: If ``credentials`` or ``check_credentials`` is wrong. + ValueError: If ``credentials`` and ``check_credentials`` are both + provided or both not provided. + + """ + if (credentials is None) == (check_credentials is None): + raise ValueError("provide either credentials or check_credentials") + + if credentials is not None: + if is_credentials(credentials): + credentials_list = [cast(tuple[str, str], credentials)] + elif isinstance(credentials, Iterable): + credentials_list = list(cast(Iterable[tuple[str, str]], credentials)) + if not all(is_credentials(item) for item in credentials_list): + raise TypeError(f"invalid credentials argument: {credentials}") + else: + raise TypeError(f"invalid credentials argument: {credentials}") + + credentials_dict = dict(credentials_list) + + def check_credentials(username: str, password: str) -> bool: + try: + expected_password = credentials_dict[username] + except KeyError: + return False + return hmac.compare_digest(expected_password, password) + + assert check_credentials is not None # help mypy + + async def process_request( + connection: ServerConnection, + request: Request, + ) -> Response | None: + """ + Perform HTTP Basic Authentication. + + If it succeeds, set the connection's ``username`` attribute and return + :obj:`None`. If it fails, return an HTTP 401 Unauthorized responss. + + """ + try: + authorization = request.headers["Authorization"] + except KeyError: + response = connection.respond( + http.HTTPStatus.UNAUTHORIZED, + "Missing credentials\n", + ) + response.headers["WWW-Authenticate"] = build_www_authenticate_basic(realm) + return response + + try: + username, password = parse_authorization_basic(authorization) + except InvalidHeader: + response = connection.respond( + http.HTTPStatus.UNAUTHORIZED, + "Unsupported credentials\n", + ) + response.headers["WWW-Authenticate"] = build_www_authenticate_basic(realm) + return response + + valid_credentials = check_credentials(username, password) + if isinstance(valid_credentials, Awaitable): + valid_credentials = await valid_credentials + + if not valid_credentials: + response = connection.respond( + http.HTTPStatus.UNAUTHORIZED, + "Invalid credentials\n", + ) + response.headers["WWW-Authenticate"] = build_www_authenticate_basic(realm) + return response + + connection.username = username + return None + + return process_request diff --git a/.venv/Lib/site-packages/websockets/auth.py b/.venv/Lib/site-packages/websockets/auth.py new file mode 100644 index 0000000000000000000000000000000000000000..cbc1635e62d5e00339d9d197ac2c096004e86062 --- /dev/null +++ b/.venv/Lib/site-packages/websockets/auth.py @@ -0,0 +1,18 @@ +from __future__ import annotations + +import warnings + + +with warnings.catch_warnings(): + # Suppress redundant DeprecationWarning raised by websockets.legacy. + warnings.filterwarnings("ignore", category=DeprecationWarning) + from .legacy.auth import * + from .legacy.auth import __all__ # noqa: F401 + + +warnings.warn( # deprecated in 14.0 - 2024-11-09 + "websockets.auth, an alias for websockets.legacy.auth, is deprecated; " + "see https://websockets.readthedocs.io/en/stable/howto/upgrade.html " + "for upgrade instructions", + DeprecationWarning, +) diff --git a/.venv/Lib/site-packages/websockets/cli.py b/.venv/Lib/site-packages/websockets/cli.py new file mode 100644 index 0000000000000000000000000000000000000000..94384b503026e4e0f824d2b1551897f6d475a97d --- /dev/null +++ b/.venv/Lib/site-packages/websockets/cli.py @@ -0,0 +1,200 @@ +from __future__ import annotations + +import argparse +import asyncio +import itertools +import os +import sys +from typing import Generator + +from .asyncio.client import ClientConnection, connect +from .asyncio.messages import SimpleQueue +from .exceptions import ConnectionClosed +from .frames import Close +from .streams import StreamReader +from .version import version as websockets_version + + +__all__ = ["main"] + +# Escape ASCII control characters (0-31 and 128-159) as well as DEL (127). +# Do not escape NO-BREAK SPACE (160) and SOFT HYPHEN (173), even if Python +# considers them non-printable, since they don't cause issues in terminal. + +# >>> [i for i in range(256) if not any(( +# ... chr(i).isprintable(), +# ... i < 32, +# ... i == 127, +# ... 128 <= i < 160, +# ... ))] +# [160, 173] + +TERMINAL_ESCAPES = str.maketrans( + {i: repr(chr(i))[1:-1] for i in itertools.chain(range(32), range(127, 160))} +) + + +def escape(string: str) -> str: + """Make a string safe for a terminal by escaping control characters.""" + return string.translate(TERMINAL_ESCAPES) + + +def print_during_input(string: str) -> None: + sys.stdout.write( + # Save cursor position + "\N{ESC}7" + # Add a new line + "\N{LINE FEED}" + # Move cursor up + "\N{ESC}[A" + # Insert blank line, scroll last line down + "\N{ESC}[L" + # Print string in the inserted blank line + f"{string}\N{LINE FEED}" + # Restore cursor position + "\N{ESC}8" + # Move cursor down + "\N{ESC}[B" + ) + sys.stdout.flush() + + +def print_over_input(string: str) -> None: + sys.stdout.write( + # Move cursor to beginning of line + "\N{CARRIAGE RETURN}" + # Delete current line + "\N{ESC}[K" + # Print string + f"{string}\N{LINE FEED}" + ) + sys.stdout.flush() + + +class ReadLines(asyncio.Protocol): + def __init__(self) -> None: + self.reader = StreamReader() + self.messages: SimpleQueue[str] = SimpleQueue() + + def parse(self) -> Generator[None, None, None]: + while True: + sys.stdout.write("> ") + sys.stdout.flush() + line = yield from self.reader.read_line(sys.maxsize) + self.messages.put(line.decode().rstrip("\r\n")) + + def connection_made(self, transport: asyncio.BaseTransport) -> None: + self.parser = self.parse() + next(self.parser) + + def data_received(self, data: bytes) -> None: + self.reader.feed_data(data) + next(self.parser) + + def eof_received(self) -> None: + self.reader.feed_eof() + # next(self.parser) isn't useful and would raise EOFError. + + def connection_lost(self, exc: Exception | None) -> None: + self.reader.discard() + self.messages.abort() + + +async def print_incoming_messages(websocket: ClientConnection) -> None: + async for message in websocket: + if isinstance(message, str): + print_during_input("< " + escape(message)) + else: + print_during_input("< (binary) " + message.hex()) + + +async def send_outgoing_messages( + websocket: ClientConnection, + messages: SimpleQueue[str], +) -> None: + while True: + try: + message = await messages.get() + except EOFError: + break + try: + await websocket.send(message) + except ConnectionClosed: # pragma: no cover + break + + +async def interactive_client(uri: str) -> None: + try: + websocket = await connect(uri) + except Exception as exc: + print(f"Failed to connect to {uri}: {exc}.") + sys.exit(1) + else: + print(f"Connected to {uri}.") + + loop = asyncio.get_running_loop() + transport, protocol = await loop.connect_read_pipe(ReadLines, sys.stdin) + incoming = asyncio.create_task( + print_incoming_messages(websocket), + ) + outgoing = asyncio.create_task( + send_outgoing_messages(websocket, protocol.messages), + ) + try: + await asyncio.wait( + [incoming, outgoing], + # Clean up and exit when the server closes the connection + # or the user enters EOT (^D), whichever happens first. + return_when=asyncio.FIRST_COMPLETED, + ) + # asyncio.run() cancels the main task when the user triggers SIGINT (^C). + # https://docs.python.org/3/library/asyncio-runner.html#handling-keyboard-interruption + # Clean up and exit without re-raising CancelledError to prevent Python + # from raising KeyboardInterrupt and displaying a stack track. + except asyncio.CancelledError: # pragma: no cover + pass + finally: + incoming.cancel() + outgoing.cancel() + transport.close() + + await websocket.close() + assert websocket.close_code is not None and websocket.close_reason is not None + close_status = Close(websocket.close_code, websocket.close_reason) + print_over_input(f"Connection closed: {escape(str(close_status))}.") + + +def main(argv: list[str] | None = None) -> None: + parser = argparse.ArgumentParser( + prog="websockets", + description="Interactive WebSocket client.", + add_help=False, + ) + group = parser.add_mutually_exclusive_group() + group.add_argument("--version", action="store_true") + group.add_argument("uri", metavar="", nargs="?") + args = parser.parse_args(argv) + + if args.version: + print(f"websockets {websockets_version}") + return + + if args.uri is None: + parser.print_usage() + sys.exit(2) + + # Enable VT100 to support ANSI escape codes in Command Prompt on Windows. + # See https://github.com/python/cpython/issues/74261 for why this works. + if sys.platform == "win32": + os.system("") + + try: + import readline # noqa: F401 + except ImportError: # readline isn't available on all platforms + pass + + # Remove the try/except block when dropping Python < 3.11. + try: + asyncio.run(interactive_client(args.uri)) + except KeyboardInterrupt: # pragma: no cover + pass diff --git a/.venv/Lib/site-packages/websockets/client.py b/.venv/Lib/site-packages/websockets/client.py new file mode 100644 index 0000000000000000000000000000000000000000..462eec0ece3908d54c66a6780ccce87505be0b2e --- /dev/null +++ b/.venv/Lib/site-packages/websockets/client.py @@ -0,0 +1,391 @@ +from __future__ import annotations + +import os +import random +import warnings +from collections.abc import Generator, Sequence +from typing import Any + +from .datastructures import Headers, MultipleValuesError +from .exceptions import ( + InvalidHandshake, + InvalidHeader, + InvalidHeaderValue, + InvalidMessage, + InvalidStatus, + InvalidUpgrade, + NegotiationError, +) +from .extensions import ClientExtensionFactory, Extension +from .headers import ( + build_authorization_basic, + build_extension, + build_host, + build_subprotocol, + parse_connection, + parse_extension, + parse_subprotocol, + parse_upgrade, +) +from .http11 import Request, Response +from .imports import lazy_import +from .protocol import CLIENT, CONNECTING, OPEN, Protocol, State +from .typing import ( + ConnectionOption, + ExtensionHeader, + LoggerLike, + Origin, + Subprotocol, + UpgradeProtocol, +) +from .uri import WebSocketURI +from .utils import accept_key, generate_key + + +__all__ = ["ClientProtocol"] + + +class ClientProtocol(Protocol): + """ + Sans-I/O implementation of a WebSocket client connection. + + Args: + uri: URI of the WebSocket server, parsed + with :func:`~websockets.uri.parse_uri`. + origin: Value of the ``Origin`` header. This is useful when connecting + to a server that validates the ``Origin`` header to defend against + Cross-Site WebSocket Hijacking attacks. + extensions: List of supported extensions, in order in which they + should be tried. + subprotocols: List of supported subprotocols, in order of decreasing + preference. + state: Initial state of the WebSocket connection. + max_size: Maximum size of incoming messages in bytes. + :obj:`None` disables the limit. You may pass a ``(max_message_size, + max_fragment_size)`` tuple to set different limits for messages and + fragments when you expect long messages sent in short fragments. + logger: Logger for this connection; + defaults to ``logging.getLogger("websockets.client")``; + see the :doc:`logging guide <../../topics/logging>` for details. + + """ + + def __init__( + self, + uri: WebSocketURI, + *, + origin: Origin | None = None, + extensions: Sequence[ClientExtensionFactory] | None = None, + subprotocols: Sequence[Subprotocol] | None = None, + state: State = CONNECTING, + max_size: int | None | tuple[int | None, int | None] = 2**20, + logger: LoggerLike | None = None, + ) -> None: + super().__init__( + side=CLIENT, + state=state, + max_size=max_size, + logger=logger, + ) + self.uri = uri + self.origin = origin + self.available_extensions = extensions + self.available_subprotocols = subprotocols + self.key = generate_key() + + def connect(self) -> Request: + """ + Create a handshake request to open a connection. + + You must send the handshake request with :meth:`send_request`. + + You can modify it before sending it, for example to add HTTP headers. + + Returns: + WebSocket handshake request event to send to the server. + + """ + headers = Headers() + headers["Host"] = build_host(self.uri.host, self.uri.port, self.uri.secure) + if self.uri.user_info: + headers["Authorization"] = build_authorization_basic(*self.uri.user_info) + if self.origin is not None: + headers["Origin"] = self.origin + headers["Upgrade"] = "websocket" + headers["Connection"] = "Upgrade" + headers["Sec-WebSocket-Key"] = self.key + headers["Sec-WebSocket-Version"] = "13" + if self.available_extensions is not None: + headers["Sec-WebSocket-Extensions"] = build_extension( + [ + (extension_factory.name, extension_factory.get_request_params()) + for extension_factory in self.available_extensions + ] + ) + if self.available_subprotocols is not None: + headers["Sec-WebSocket-Protocol"] = build_subprotocol( + self.available_subprotocols + ) + return Request(self.uri.resource_name, headers) + + def process_response(self, response: Response) -> None: + """ + Check a handshake response. + + Args: + request: WebSocket handshake response received from the server. + + Raises: + InvalidHandshake: If the handshake response is invalid. + + """ + + if response.status_code != 101: + raise InvalidStatus(response) + + headers = response.headers + + connection: list[ConnectionOption] = sum( + [parse_connection(value) for value in headers.get_all("Connection")], [] + ) + if not any(value.lower() == "upgrade" for value in connection): + raise InvalidUpgrade( + "Connection", ", ".join(connection) if connection else None + ) + + upgrade: list[UpgradeProtocol] = sum( + [parse_upgrade(value) for value in headers.get_all("Upgrade")], [] + ) + # For compatibility with non-strict implementations, ignore case when + # checking the Upgrade header. It's supposed to be 'WebSocket'. + if not (len(upgrade) == 1 and upgrade[0].lower() == "websocket"): + raise InvalidUpgrade("Upgrade", ", ".join(upgrade) if upgrade else None) + + try: + s_w_accept = headers["Sec-WebSocket-Accept"] + except KeyError: + raise InvalidHeader("Sec-WebSocket-Accept") from None + except MultipleValuesError: + raise InvalidHeader("Sec-WebSocket-Accept", "multiple values") from None + if s_w_accept != accept_key(self.key): + raise InvalidHeaderValue("Sec-WebSocket-Accept", s_w_accept) + + self.extensions = self.process_extensions(headers) + self.subprotocol = self.process_subprotocol(headers) + + def process_extensions(self, headers: Headers) -> list[Extension]: + """ + Handle the Sec-WebSocket-Extensions HTTP response header. + + Check that each extension is supported, as well as its parameters. + + :rfc:`6455` leaves the rules up to the specification of each + extension. + + To provide this level of flexibility, for each extension accepted by + the server, we check for a match with each extension available in the + client configuration. If no match is found, an exception is raised. + + If several variants of the same extension are accepted by the server, + it may be configured several times, which won't make sense in general. + Extensions must implement their own requirements. For this purpose, + the list of previously accepted extensions is provided. + + Other requirements, for example related to mandatory extensions or the + order of extensions, may be implemented by overriding this method. + + Args: + headers: WebSocket handshake response headers. + + Returns: + List of accepted extensions. + + Raises: + InvalidHandshake: To abort the handshake. + + """ + accepted_extensions: list[Extension] = [] + + extensions = headers.get_all("Sec-WebSocket-Extensions") + + if extensions: + if self.available_extensions is None: + raise NegotiationError("no extensions supported") + + parsed_extensions: list[ExtensionHeader] = sum( + [parse_extension(header_value) for header_value in extensions], [] + ) + + for name, response_params in parsed_extensions: + for extension_factory in self.available_extensions: + # Skip non-matching extensions based on their name. + if extension_factory.name != name: + continue + + # Skip non-matching extensions based on their params. + try: + extension = extension_factory.process_response_params( + response_params, accepted_extensions + ) + except NegotiationError: + continue + + # Add matching extension to the final list. + accepted_extensions.append(extension) + + # Break out of the loop once we have a match. + break + + # If we didn't break from the loop, no extension in our list + # matched what the server sent. Fail the connection. + else: + raise NegotiationError( + f"Unsupported extension: " + f"name = {name}, params = {response_params}" + ) + + return accepted_extensions + + def process_subprotocol(self, headers: Headers) -> Subprotocol | None: + """ + Handle the Sec-WebSocket-Protocol HTTP response header. + + If provided, check that it contains exactly one supported subprotocol. + + Args: + headers: WebSocket handshake response headers. + + Returns: + Subprotocol, if one was selected. + + """ + subprotocol: Subprotocol | None = None + + subprotocols = headers.get_all("Sec-WebSocket-Protocol") + + if subprotocols: + if self.available_subprotocols is None: + raise NegotiationError("no subprotocols supported") + + parsed_subprotocols: Sequence[Subprotocol] = sum( + [parse_subprotocol(header_value) for header_value in subprotocols], [] + ) + if len(parsed_subprotocols) > 1: + raise InvalidHeader( + "Sec-WebSocket-Protocol", + f"multiple values: {', '.join(parsed_subprotocols)}", + ) + + subprotocol = parsed_subprotocols[0] + if subprotocol not in self.available_subprotocols: + raise NegotiationError(f"unsupported subprotocol: {subprotocol}") + + return subprotocol + + def send_request(self, request: Request) -> None: + """ + Send a handshake request to the server. + + Args: + request: WebSocket handshake request event. + + """ + if self.debug: + self.logger.debug("> GET %s HTTP/1.1", request.path) + for key, value in request.headers.raw_items(): + self.logger.debug("> %s: %s", key, value) + + self.writes.append(request.serialize()) + + def parse(self) -> Generator[None]: + if self.state is CONNECTING: + try: + response = yield from Response.parse( + self.reader.read_line, + self.reader.read_exact, + self.reader.read_to_eof, + ) + except Exception as exc: + self.handshake_exc = InvalidMessage( + "did not receive a valid HTTP response" + ) + self.handshake_exc.__cause__ = exc + self.send_eof() + self.parser = self.discard() + next(self.parser) # start coroutine + yield + + if self.debug: + code, phrase = response.status_code, response.reason_phrase + self.logger.debug("< HTTP/1.1 %d %s", code, phrase) + for key, value in response.headers.raw_items(): + self.logger.debug("< %s: %s", key, value) + if response.body: + self.logger.debug("< [body] (%d bytes)", len(response.body)) + + try: + self.process_response(response) + except InvalidHandshake as exc: + response._exception = exc + self.events.append(response) + self.handshake_exc = exc + self.send_eof() + self.parser = self.discard() + next(self.parser) # start coroutine + yield + + assert self.state is CONNECTING + self.state = OPEN + self.events.append(response) + + yield from super().parse() + + +class ClientConnection(ClientProtocol): + def __init__(self, *args: Any, **kwargs: Any) -> None: + warnings.warn( # deprecated in 11.0 - 2023-04-02 + "ClientConnection was renamed to ClientProtocol", + DeprecationWarning, + ) + super().__init__(*args, **kwargs) + + +BACKOFF_INITIAL_DELAY = float(os.environ.get("WEBSOCKETS_BACKOFF_INITIAL_DELAY", "5")) +BACKOFF_MIN_DELAY = float(os.environ.get("WEBSOCKETS_BACKOFF_MIN_DELAY", "3.1")) +BACKOFF_MAX_DELAY = float(os.environ.get("WEBSOCKETS_BACKOFF_MAX_DELAY", "90.0")) +BACKOFF_FACTOR = float(os.environ.get("WEBSOCKETS_BACKOFF_FACTOR", "1.618")) + + +def backoff( + initial_delay: float = BACKOFF_INITIAL_DELAY, + min_delay: float = BACKOFF_MIN_DELAY, + max_delay: float = BACKOFF_MAX_DELAY, + factor: float = BACKOFF_FACTOR, +) -> Generator[float]: + """ + Generate a series of backoff delays between reconnection attempts. + + Yields: + How many seconds to wait before retrying to connect. + + """ + # Add a random initial delay between 0 and 5 seconds. + # See 7.2.3. Recovering from Abnormal Closure in RFC 6455. + yield random.random() * initial_delay + delay = min_delay + while delay < max_delay: + yield delay + delay *= factor + while True: + yield max_delay + + +lazy_import( + globals(), + deprecated_aliases={ + # deprecated in 14.0 - 2024-11-09 + "WebSocketClientProtocol": ".legacy.client", + "connect": ".legacy.client", + "unix_connect": ".legacy.client", + }, +) diff --git a/.venv/Lib/site-packages/websockets/connection.py b/.venv/Lib/site-packages/websockets/connection.py new file mode 100644 index 0000000000000000000000000000000000000000..9ed99a45af81ee02911003e33ccd96c58416ab7a --- /dev/null +++ b/.venv/Lib/site-packages/websockets/connection.py @@ -0,0 +1,12 @@ +from __future__ import annotations + +import warnings + +from .protocol import SEND_EOF, Protocol as Connection, Side, State # noqa: F401 + + +warnings.warn( # deprecated in 11.0 - 2023-04-02 + "websockets.connection was renamed to websockets.protocol " + "and Connection was renamed to Protocol", + DeprecationWarning, +) diff --git a/.venv/Lib/site-packages/websockets/datastructures.py b/.venv/Lib/site-packages/websockets/datastructures.py new file mode 100644 index 0000000000000000000000000000000000000000..17fbbeaf14c564d966b2cdc7648ed67ea9e1bbef --- /dev/null +++ b/.venv/Lib/site-packages/websockets/datastructures.py @@ -0,0 +1,204 @@ +from __future__ import annotations + +import re +from collections.abc import Iterable, Iterator, Mapping, MutableMapping +from typing import Any, Protocol + + +__all__ = [ + "Headers", + "HeadersLike", + "MultipleValuesError", +] + + +class MultipleValuesError(LookupError): + """ + Exception raised when :class:`Headers` has multiple values for a key. + + """ + + def __str__(self) -> str: + # Implement the same logic as KeyError_str in Objects/exceptions.c. + if len(self.args) == 1: + return repr(self.args[0]) + return super().__str__() + + +# Obsolete line folding for header values is not supported. +is_valid_header_value = re.compile(r"[\x09\x20-\x7e\x80-\xff]*").fullmatch + + +class Headers(MutableMapping[str, str]): + """ + Efficient data structure for manipulating HTTP headers. + + A :class:`list` of ``(name, values)`` is inefficient for lookups. + + A :class:`dict` doesn't suffice because header names are case-insensitive + and multiple occurrences of headers with the same name are possible. + + :class:`Headers` stores HTTP headers in a hybrid data structure to provide + efficient insertions and lookups while preserving the original data. + + In order to account for multiple values with minimal hassle, + :class:`Headers` follows this logic: + + - When getting a header with ``headers[name]``: + - if there's no value, :exc:`KeyError` is raised; + - if there's exactly one value, it's returned; + - if there's more than one value, :exc:`MultipleValuesError` is raised. + + - When setting a header with ``headers[name] = value``, the value is + appended to the list of values for that header. + + - When deleting a header with ``del headers[name]``, all values for that + header are removed (this is slow). + + Other methods for manipulating headers are consistent with this logic. + + As long as no header occurs multiple times, :class:`Headers` behaves like + :class:`dict`, except keys are lower-cased to provide case-insensitivity. + + Two methods support manipulating multiple values explicitly: + + - :meth:`get_all` returns a list of all values for a header; + - :meth:`raw_items` returns an iterator of ``(name, values)`` pairs. + + """ + + __slots__ = ["_dict", "_list"] + + # Like dict, Headers accepts an optional "mapping or iterable" argument. + def __init__(self, *args: HeadersLike, **kwargs: str) -> None: + self._dict: dict[str, list[str]] = {} + self._list: list[tuple[str, str]] = [] + self.update(*args, **kwargs) + + def __str__(self) -> str: + return "".join(f"{key}: {value}\r\n" for key, value in self._list) + "\r\n" + + def __repr__(self) -> str: + return f"{self.__class__.__name__}({self._list!r})" + + def copy(self) -> Headers: + copy = self.__class__() + copy._dict = self._dict.copy() + copy._list = self._list.copy() + return copy + + def serialize(self) -> bytes: + # Since headers only contain ASCII characters, we can keep this simple. + return str(self).encode() + + # Collection methods + + def __contains__(self, key: object) -> bool: + return isinstance(key, str) and key.lower() in self._dict + + def __iter__(self) -> Iterator[str]: + return iter(self._dict) + + def __len__(self) -> int: + return len(self._dict) + + # MutableMapping methods + + def __getitem__(self, key: str) -> str: + value = self._dict[key.lower()] + if len(value) == 1: + return value[0] + else: + raise MultipleValuesError(key) + + def __setitem__(self, key: str, value: str) -> None: + if not is_valid_header_value(str(value)): + raise InvalidHeaderValue(key, value) + self._dict.setdefault(key.lower(), []).append(value) + self._list.append((key, value)) + + def __delitem__(self, key: str) -> None: + key_lower = key.lower() + self._dict.__delitem__(key_lower) + # This is inefficient. Fortunately deleting HTTP headers is uncommon. + self._list = [(k, v) for k, v in self._list if k.lower() != key_lower] + + def __eq__(self, other: Any) -> bool: + if not isinstance(other, Headers): + return NotImplemented + return self._dict == other._dict + + def clear(self) -> None: + """ + Remove all headers. + + """ + self._dict = {} + self._list = [] + + def update(self, *args: HeadersLike, **kwargs: str) -> None: + """ + Update from a :class:`Headers` instance and/or keyword arguments. + + """ + args = tuple( + arg.raw_items() if isinstance(arg, Headers) else arg for arg in args + ) + super().update(*args, **kwargs) + + # Methods for handling multiple values + + def get_all(self, key: str) -> list[str]: + """ + Return the (possibly empty) list of all values for a header. + + Args: + key: Header name. + + """ + return self._dict.get(key.lower(), []) + + def raw_items(self) -> Iterator[tuple[str, str]]: + """ + Return an iterator of all values as ``(name, value)`` pairs. + + """ + return iter(self._list) + + # Internal methods + + def set_insecure(self, key: str, value: str) -> None: + """ + Set a header without validating its value. + + """ + self._dict.setdefault(key.lower(), []).append(value) + self._list.append((key, value)) + + +# copy of _typeshed.SupportsKeysAndGetItem. +class SupportsKeysAndGetItem(Protocol): # pragma: no cover + """ + Dict-like types with ``keys() -> str`` and ``__getitem__(key: str) -> str`` methods. + + """ + + def keys(self) -> Iterable[str]: ... + + def __getitem__(self, key: str) -> str: ... + + +HeadersLike = ( + Headers | Mapping[str, str] | Iterable[tuple[str, str]] | SupportsKeysAndGetItem +) +""" +Types accepted where :class:`Headers` is expected. + +In addition to :class:`Headers` itself, this includes dict-like types where both +keys and values are :class:`str`. + +""" + + +# At the bottom to break an import cycle. +from .exceptions import InvalidHeaderValue # noqa: E402 diff --git a/.venv/Lib/site-packages/websockets/exceptions.py b/.venv/Lib/site-packages/websockets/exceptions.py new file mode 100644 index 0000000000000000000000000000000000000000..00777386102b9dde8310ca15e7afa7c7ffa6f374 --- /dev/null +++ b/.venv/Lib/site-packages/websockets/exceptions.py @@ -0,0 +1,473 @@ +""" +:mod:`websockets.exceptions` defines the following hierarchy of exceptions. + +* :exc:`WebSocketException` + * :exc:`ConnectionClosed` + * :exc:`ConnectionClosedOK` + * :exc:`ConnectionClosedError` + * :exc:`InvalidURI` + * :exc:`InvalidProxy` + * :exc:`InvalidHandshake` + * :exc:`SecurityError` + * :exc:`ProxyError` + * :exc:`InvalidProxyMessage` + * :exc:`InvalidProxyStatus` + * :exc:`InvalidMessage` + * :exc:`InvalidStatus` + * :exc:`InvalidStatusCode` (legacy) + * :exc:`InvalidHeader` + * :exc:`InvalidHeaderFormat` + * :exc:`InvalidHeaderValue` + * :exc:`InvalidOrigin` + * :exc:`InvalidUpgrade` + * :exc:`NegotiationError` + * :exc:`DuplicateParameter` + * :exc:`InvalidParameterName` + * :exc:`InvalidParameterValue` + * :exc:`AbortHandshake` (legacy) + * :exc:`RedirectHandshake` (legacy) + * :exc:`ProtocolError` (Sans-I/O) + * :exc:`PayloadTooBig` (Sans-I/O) + * :exc:`InvalidState` (Sans-I/O) + * :exc:`ConcurrencyError` + +""" + +from __future__ import annotations + +import warnings + +from .imports import lazy_import + + +__all__ = [ + "WebSocketException", + "ConnectionClosed", + "ConnectionClosedOK", + "ConnectionClosedError", + "InvalidURI", + "InvalidProxy", + "InvalidHandshake", + "SecurityError", + "ProxyError", + "InvalidProxyMessage", + "InvalidProxyStatus", + "InvalidMessage", + "InvalidStatus", + "InvalidHeader", + "InvalidHeaderFormat", + "InvalidHeaderValue", + "InvalidOrigin", + "InvalidUpgrade", + "NegotiationError", + "DuplicateParameter", + "InvalidParameterName", + "InvalidParameterValue", + "ProtocolError", + "PayloadTooBig", + "InvalidState", + "ConcurrencyError", +] + + +class WebSocketException(Exception): + """ + Base class for all exceptions defined by websockets. + + """ + + +class ConnectionClosed(WebSocketException): + """ + Raised when trying to interact with a closed connection. + + Attributes: + rcvd: If a close frame was received, its code and reason are available + in ``rcvd.code`` and ``rcvd.reason``. + sent: If a close frame was sent, its code and reason are available + in ``sent.code`` and ``sent.reason``. + rcvd_then_sent: If close frames were received and sent, this attribute + tells in which order this happened, from the perspective of this + side of the connection. + + """ + + def __init__( + self, + rcvd: frames.Close | None, + sent: frames.Close | None, + rcvd_then_sent: bool | None = None, + ) -> None: + self.rcvd = rcvd + self.sent = sent + self.rcvd_then_sent = rcvd_then_sent + assert (self.rcvd_then_sent is None) == (self.rcvd is None or self.sent is None) + + def __str__(self) -> str: + if self.rcvd is None: + if self.sent is None: + return "no close frame received or sent" + else: + return f"sent {self.sent}; no close frame received" + else: + if self.sent is None: + return f"received {self.rcvd}; no close frame sent" + else: + if self.rcvd_then_sent: + return f"received {self.rcvd}; then sent {self.sent}" + else: + return f"sent {self.sent}; then received {self.rcvd}" + + # code and reason attributes are provided for backwards-compatibility + + @property + def code(self) -> int: + warnings.warn( # deprecated in 13.1 - 2024-09-21 + "ConnectionClosed.code is deprecated; " + "use Protocol.close_code or ConnectionClosed.rcvd.code", + DeprecationWarning, + ) + if self.rcvd is None: + return frames.CloseCode.ABNORMAL_CLOSURE + return self.rcvd.code + + @property + def reason(self) -> str: + warnings.warn( # deprecated in 13.1 - 2024-09-21 + "ConnectionClosed.reason is deprecated; " + "use Protocol.close_reason or ConnectionClosed.rcvd.reason", + DeprecationWarning, + ) + if self.rcvd is None: + return "" + return self.rcvd.reason + + +class ConnectionClosedOK(ConnectionClosed): + """ + Like :exc:`ConnectionClosed`, when the connection terminated properly. + + A close code with code 1000 (OK) or 1001 (going away) or without a code was + received and sent. + + """ + + +class ConnectionClosedError(ConnectionClosed): + """ + Like :exc:`ConnectionClosed`, when the connection terminated with an error. + + A close frame with a code other than 1000 (OK) or 1001 (going away) was + received or sent, or the closing handshake didn't complete properly. + + """ + + +class InvalidURI(WebSocketException): + """ + Raised when connecting to a URI that isn't a valid WebSocket URI. + + """ + + def __init__(self, uri: str, msg: str) -> None: + self.uri = uri + self.msg = msg + + def __str__(self) -> str: + return f"{self.uri} isn't a valid URI: {self.msg}" + + +class InvalidProxy(WebSocketException): + """ + Raised when connecting via a proxy that isn't valid. + + """ + + def __init__(self, proxy: str, msg: str) -> None: + self.proxy = proxy + self.msg = msg + + def __str__(self) -> str: + return f"{self.proxy} isn't a valid proxy: {self.msg}" + + +class InvalidHandshake(WebSocketException): + """ + Base class for exceptions raised when the opening handshake fails. + + """ + + +class SecurityError(InvalidHandshake): + """ + Raised when a handshake request or response breaks a security rule. + + Security limits can be configured with :doc:`environment variables + <../reference/variables>`. + + """ + + +class ProxyError(InvalidHandshake): + """ + Raised when failing to connect to a proxy. + + """ + + +class InvalidProxyMessage(ProxyError): + """ + Raised when an HTTP proxy response is malformed. + + """ + + +class InvalidProxyStatus(ProxyError): + """ + Raised when an HTTP proxy rejects the connection. + + """ + + def __init__(self, response: http11.Response) -> None: + self.response = response + + def __str__(self) -> str: + return f"proxy rejected connection: HTTP {self.response.status_code:d}" + + +class InvalidMessage(InvalidHandshake): + """ + Raised when a handshake request or response is malformed. + + """ + + +class InvalidStatus(InvalidHandshake): + """ + Raised when a handshake response rejects the WebSocket upgrade. + + """ + + def __init__(self, response: http11.Response) -> None: + self.response = response + + def __str__(self) -> str: + return ( + f"server rejected WebSocket connection: HTTP {self.response.status_code:d}" + ) + + +class InvalidHeader(InvalidHandshake): + """ + Raised when an HTTP header doesn't have a valid format or value. + + """ + + def __init__(self, name: str, value: str | None = None) -> None: + self.name = name + self.value = value + + def __str__(self) -> str: + if self.value is None: + return f"missing {self.name} header" + elif self.value == "": + return f"empty {self.name} header" + else: + return f"invalid {self.name} header: {self.value}" + + +class InvalidHeaderFormat(InvalidHeader): + """ + Raised when an HTTP header cannot be parsed. + + The format of the header doesn't match the grammar for that header. + + """ + + def __init__(self, name: str, error: str, header: str, pos: int) -> None: + super().__init__(name, f"{error} at {pos} in {header}") + + +class InvalidHeaderValue(InvalidHeader): + """ + Raised when an HTTP header has a wrong value. + + The format of the header is correct but the value isn't acceptable. + + """ + + +class InvalidOrigin(InvalidHeader): + """ + Raised when the Origin header in a request isn't allowed. + + """ + + def __init__(self, origin: str | None) -> None: + super().__init__("Origin", origin) + + +class InvalidUpgrade(InvalidHeader): + """ + Raised when the Upgrade or Connection header isn't correct. + + """ + + +class NegotiationError(InvalidHandshake): + """ + Raised when negotiating an extension or a subprotocol fails. + + """ + + +class DuplicateParameter(NegotiationError): + """ + Raised when a parameter name is repeated in an extension header. + + """ + + def __init__(self, name: str) -> None: + self.name = name + + def __str__(self) -> str: + return f"duplicate parameter: {self.name}" + + +class InvalidParameterName(NegotiationError): + """ + Raised when a parameter name in an extension header is invalid. + + """ + + def __init__(self, name: str) -> None: + self.name = name + + def __str__(self) -> str: + return f"invalid parameter name: {self.name}" + + +class InvalidParameterValue(NegotiationError): + """ + Raised when a parameter value in an extension header is invalid. + + """ + + def __init__(self, name: str, value: str | None) -> None: + self.name = name + self.value = value + + def __str__(self) -> str: + if self.value is None: + return f"missing value for parameter {self.name}" + elif self.value == "": + return f"empty value for parameter {self.name}" + else: + return f"invalid value for parameter {self.name}: {self.value}" + + +class ProtocolError(WebSocketException): + """ + Raised when receiving or sending a frame that breaks the protocol. + + The Sans-I/O implementation raises this exception when: + + * receiving or sending a frame that contains invalid data; + * receiving or sending an invalid sequence of frames. + + """ + + +class PayloadTooBig(WebSocketException): + """ + Raised when parsing a frame with a payload that exceeds the maximum size. + + The Sans-I/O layer uses this exception internally. It doesn't bubble up to + the I/O layer. + + The :meth:`~websockets.extensions.Extension.decode` method of extensions + must raise :exc:`PayloadTooBig` if decoding a frame would exceed the limit. + + """ + + def __init__( + self, + size_or_message: int | None | str, + max_size: int | None = None, + current_size: int | None = None, + ) -> None: + if isinstance(size_or_message, str): + assert max_size is None + assert current_size is None + warnings.warn( # deprecated in 14.0 - 2024-11-09 + "PayloadTooBig(message) is deprecated; " + "change to PayloadTooBig(size, max_size)", + DeprecationWarning, + ) + self.message: str | None = size_or_message + else: + self.message = None + self.size: int | None = size_or_message + assert max_size is not None + self.max_size: int = max_size + self.current_size: int | None = None + self.set_current_size(current_size) + + def __str__(self) -> str: + if self.message is not None: + return self.message + else: + message = "frame " + if self.size is not None: + message += f"with {self.size} bytes " + if self.current_size is not None: + message += f"after reading {self.current_size} bytes " + message += f"exceeds limit of {self.max_size} bytes" + return message + + def set_current_size(self, current_size: int | None) -> None: + assert self.current_size is None + if current_size is not None: + self.max_size += current_size + self.current_size = current_size + + +class InvalidState(WebSocketException, AssertionError): + """ + Raised when sending a frame is forbidden in the current state. + + Specifically, the Sans-I/O layer raises this exception when: + + * sending a data frame to a connection in a state other + :attr:`~websockets.protocol.State.OPEN`; + * sending a control frame to a connection in a state other than + :attr:`~websockets.protocol.State.OPEN` or + :attr:`~websockets.protocol.State.CLOSING`. + + """ + + +class ConcurrencyError(WebSocketException, RuntimeError): + """ + Raised when receiving or sending messages concurrently. + + WebSocket is a connection-oriented protocol. Reads must be serialized; so + must be writes. However, reading and writing concurrently is possible. + + """ + + +# At the bottom to break import cycles created by type annotations. +from . import frames, http11 # noqa: E402 + + +lazy_import( + globals(), + deprecated_aliases={ + # deprecated in 14.0 - 2024-11-09 + "AbortHandshake": ".legacy.exceptions", + "InvalidStatusCode": ".legacy.exceptions", + "RedirectHandshake": ".legacy.exceptions", + "WebSocketProtocolError": ".legacy.exceptions", + }, +) diff --git a/.venv/Lib/site-packages/websockets/extensions/__init__.py b/.venv/Lib/site-packages/websockets/extensions/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..84d77e4aff3c4c22b80299b7466088514c007ede --- /dev/null +++ b/.venv/Lib/site-packages/websockets/extensions/__init__.py @@ -0,0 +1,4 @@ +from .base import * + + +__all__ = ["Extension", "ClientExtensionFactory", "ServerExtensionFactory"] diff --git a/.venv/Lib/site-packages/websockets/extensions/base.py b/.venv/Lib/site-packages/websockets/extensions/base.py new file mode 100644 index 0000000000000000000000000000000000000000..e5b55f616b03084f19454552fa203ef84b4b2d83 --- /dev/null +++ b/.venv/Lib/site-packages/websockets/extensions/base.py @@ -0,0 +1,123 @@ +from __future__ import annotations + +from collections.abc import Sequence + +from ..frames import Frame +from ..typing import ExtensionName, ExtensionParameter + + +__all__ = ["Extension", "ClientExtensionFactory", "ServerExtensionFactory"] + + +class Extension: + """ + Base class for extensions. + + """ + + name: ExtensionName + """Extension identifier.""" + + def decode(self, frame: Frame, *, max_size: int | None = None) -> Frame: + """ + Decode an incoming frame. + + Args: + frame: Incoming frame. + max_size: Maximum payload size in bytes. + + Returns: + Decoded frame. + + Raises: + PayloadTooBig: If decoding the payload exceeds ``max_size``. + + """ + raise NotImplementedError + + def encode(self, frame: Frame) -> Frame: + """ + Encode an outgoing frame. + + Args: + frame: Outgoing frame. + + Returns: + Encoded frame. + + """ + raise NotImplementedError + + +class ClientExtensionFactory: + """ + Base class for client-side extension factories. + + """ + + name: ExtensionName + """Extension identifier.""" + + def get_request_params(self) -> Sequence[ExtensionParameter]: + """ + Build parameters to send to the server for this extension. + + Returns: + Parameters to send to the server. + + """ + raise NotImplementedError + + def process_response_params( + self, + params: Sequence[ExtensionParameter], + accepted_extensions: Sequence[Extension], + ) -> Extension: + """ + Process parameters received from the server. + + Args: + params: Parameters received from the server for this extension. + accepted_extensions: List of previously accepted extensions. + + Returns: + An extension instance. + + Raises: + NegotiationError: If parameters aren't acceptable. + + """ + raise NotImplementedError + + +class ServerExtensionFactory: + """ + Base class for server-side extension factories. + + """ + + name: ExtensionName + """Extension identifier.""" + + def process_request_params( + self, + params: Sequence[ExtensionParameter], + accepted_extensions: Sequence[Extension], + ) -> tuple[list[ExtensionParameter], Extension]: + """ + Process parameters received from the client. + + Args: + params: Parameters received from the client for this extension. + accepted_extensions: List of previously accepted extensions. + + Returns: + To accept the offer, parameters to send to the client for this + extension and an extension instance. + + Raises: + NegotiationError: To reject the offer, if parameters received from + the client aren't acceptable. + + """ + raise NotImplementedError diff --git a/.venv/Lib/site-packages/websockets/extensions/permessage_deflate.py b/.venv/Lib/site-packages/websockets/extensions/permessage_deflate.py new file mode 100644 index 0000000000000000000000000000000000000000..66118b0588a11fedb6124cc1cec21d270d569cc0 --- /dev/null +++ b/.venv/Lib/site-packages/websockets/extensions/permessage_deflate.py @@ -0,0 +1,701 @@ +from __future__ import annotations + +import zlib +from collections.abc import Sequence +from typing import Any, Literal + +from .. import frames +from ..exceptions import ( + DuplicateParameter, + InvalidParameterName, + InvalidParameterValue, + NegotiationError, + PayloadTooBig, + ProtocolError, +) +from ..typing import BytesLike, ExtensionName, ExtensionParameter +from .base import ClientExtensionFactory, Extension, ServerExtensionFactory + + +__all__ = [ + "PerMessageDeflate", + "ClientPerMessageDeflateFactory", + "enable_client_permessage_deflate", + "ServerPerMessageDeflateFactory", + "enable_server_permessage_deflate", +] + +_EMPTY_UNCOMPRESSED_BLOCK = b"\x00\x00\xff\xff" + +_MAX_WINDOW_BITS_VALUES = [str(bits) for bits in range(8, 16)] + + +class PerMessageDeflate(Extension): + """ + Per-Message Deflate extension. + + """ + + name = ExtensionName("permessage-deflate") + + def __init__( + self, + remote_no_context_takeover: bool, + local_no_context_takeover: bool, + remote_max_window_bits: int, + local_max_window_bits: int, + compress_settings: dict[Any, Any] | None = None, + ) -> None: + """ + Configure the Per-Message Deflate extension. + + """ + if compress_settings is None: + compress_settings = {} + + assert remote_no_context_takeover in [False, True] + assert local_no_context_takeover in [False, True] + assert 8 <= remote_max_window_bits <= 15 + assert 8 <= local_max_window_bits <= 15 + assert "wbits" not in compress_settings + + self.remote_no_context_takeover = remote_no_context_takeover + self.local_no_context_takeover = local_no_context_takeover + self.remote_max_window_bits = remote_max_window_bits + self.local_max_window_bits = local_max_window_bits + self.compress_settings = compress_settings + + if not self.remote_no_context_takeover: + self.decoder = zlib.decompressobj(wbits=-self.remote_max_window_bits) + + if not self.local_no_context_takeover: + self.encoder = zlib.compressobj( + wbits=-self.local_max_window_bits, + **self.compress_settings, + ) + + # To handle continuation frames properly, we must keep track of + # whether that initial frame was encoded. + self.decode_cont_data = False + # There's no need for self.encode_cont_data because we always encode + # outgoing frames, so it would always be True. + + def __repr__(self) -> str: + return ( + f"PerMessageDeflate(" + f"remote_no_context_takeover={self.remote_no_context_takeover}, " + f"local_no_context_takeover={self.local_no_context_takeover}, " + f"remote_max_window_bits={self.remote_max_window_bits}, " + f"local_max_window_bits={self.local_max_window_bits})" + ) + + def decode( + self, + frame: frames.Frame, + *, + max_size: int | None = None, + ) -> frames.Frame: + """ + Decode an incoming frame. + + """ + # Skip control frames. + if frame.opcode in frames.CTRL_OPCODES: + return frame + + # Handle continuation data frames: + # - skip if the message isn't encoded + # - reset "decode continuation data" flag if it's a final frame + if frame.opcode is frames.OP_CONT: + if not self.decode_cont_data: + return frame + if frame.rsv1: + raise ProtocolError("RSV1 bit set in continuation frame") + if frame.fin: + self.decode_cont_data = False + + # Handle text and binary data frames: + # - skip if the message isn't encoded + # - unset the rsv1 flag on the first frame of a compressed message + # - set "decode continuation data" flag if it's a non-final frame + else: + if not frame.rsv1: + return frame + if not frame.fin: + self.decode_cont_data = True + + # Re-initialize per-message decoder. + if self.remote_no_context_takeover: + self.decoder = zlib.decompressobj(wbits=-self.remote_max_window_bits) + + # Uncompress data. Protect against zip bombs by preventing zlib from + # decompressing more than max_length bytes (except when the limit is + # disabled with max_size = None). + data: BytesLike + if frame.fin and len(frame.data) < 2044: + # Profiling shows that appending four bytes, which makes a copy, is + # faster than calling decompress() again when data is less than 2kB. + data = bytes(frame.data) + _EMPTY_UNCOMPRESSED_BLOCK + else: + data = frame.data + max_length = 0 if max_size is None else max_size + try: + data = self.decoder.decompress(data, max_length) + if self.decoder.unconsumed_tail: + raise PayloadTooBig(None, max_size) + if frame.fin and len(frame.data) >= 2044: + # In edge cases, flushing may yield data held back by max_size. + if self.decoder.decompress(_EMPTY_UNCOMPRESSED_BLOCK, 1): + raise PayloadTooBig(None, max_size) + except zlib.error as exc: + raise ProtocolError("decompression failed") from exc + + # Allow garbage collection of the decoder if it won't be reused. + if frame.fin and self.remote_no_context_takeover: + del self.decoder + + return frames.Frame( + frame.opcode, + data, + frame.fin, + # Unset the rsv1 flag on the first frame of a compressed message. + False, + frame.rsv2, + frame.rsv3, + ) + + def encode(self, frame: frames.Frame) -> frames.Frame: + """ + Encode an outgoing frame. + + """ + # Skip control frames. + if frame.opcode in frames.CTRL_OPCODES: + return frame + + # Since we always encode messages, there's no "encode continuation + # data" flag similar to "decode continuation data" at this time. + + if frame.opcode is not frames.OP_CONT: + # Re-initialize per-message decoder. + if self.local_no_context_takeover: + self.encoder = zlib.compressobj( + wbits=-self.local_max_window_bits, + **self.compress_settings, + ) + + # Compress data. + data: BytesLike + data = self.encoder.compress(frame.data) + self.encoder.flush(zlib.Z_SYNC_FLUSH) + if frame.fin: + # Sync flush generates between 5 or 6 bytes, ending with the bytes + # 0x00 0x00 0xff 0xff, which must be removed. + assert data[-4:] == _EMPTY_UNCOMPRESSED_BLOCK + # Making a copy is faster than memoryview(a)[:-4] until 2kB. + if len(data) < 2048: + data = data[:-4] + else: + data = memoryview(data)[:-4] + + # Allow garbage collection of the encoder if it won't be reused. + if frame.fin and self.local_no_context_takeover: + del self.encoder + + return frames.Frame( + frame.opcode, + data, + frame.fin, + # Set the rsv1 flag on the first frame of a compressed message. + frame.opcode is not frames.OP_CONT, + frame.rsv2, + frame.rsv3, + ) + + +def _build_parameters( + server_no_context_takeover: bool, + client_no_context_takeover: bool, + server_max_window_bits: int | None, + client_max_window_bits: int | Literal[True] | None, +) -> list[ExtensionParameter]: + """ + Build a list of ``(name, value)`` pairs for some compression parameters. + + """ + params: list[ExtensionParameter] = [] + if server_no_context_takeover: + params.append(("server_no_context_takeover", None)) + if client_no_context_takeover: + params.append(("client_no_context_takeover", None)) + if server_max_window_bits: + params.append(("server_max_window_bits", str(server_max_window_bits))) + if client_max_window_bits is True: # only in handshake requests + params.append(("client_max_window_bits", None)) + elif client_max_window_bits: + params.append(("client_max_window_bits", str(client_max_window_bits))) + return params + + +def _extract_parameters( + params: Sequence[ExtensionParameter], *, is_server: bool +) -> tuple[bool, bool, int | None, int | Literal[True] | None]: + """ + Extract compression parameters from a list of ``(name, value)`` pairs. + + If ``is_server`` is :obj:`True`, ``client_max_window_bits`` may be + provided without a value. This is only allowed in handshake requests. + + """ + server_no_context_takeover: bool = False + client_no_context_takeover: bool = False + server_max_window_bits: int | None = None + client_max_window_bits: int | Literal[True] | None = None + + for name, value in params: + if name == "server_no_context_takeover": + if server_no_context_takeover: + raise DuplicateParameter(name) + if value is None: + server_no_context_takeover = True + else: + raise InvalidParameterValue(name, value) + + elif name == "client_no_context_takeover": + if client_no_context_takeover: + raise DuplicateParameter(name) + if value is None: + client_no_context_takeover = True + else: + raise InvalidParameterValue(name, value) + + elif name == "server_max_window_bits": + if server_max_window_bits is not None: + raise DuplicateParameter(name) + if value in _MAX_WINDOW_BITS_VALUES: + server_max_window_bits = int(value) + else: + raise InvalidParameterValue(name, value) + + elif name == "client_max_window_bits": + if client_max_window_bits is not None: + raise DuplicateParameter(name) + if is_server and value is None: # only in handshake requests + client_max_window_bits = True + elif value in _MAX_WINDOW_BITS_VALUES: + client_max_window_bits = int(value) + else: + raise InvalidParameterValue(name, value) + + else: + raise InvalidParameterName(name) + + return ( + server_no_context_takeover, + client_no_context_takeover, + server_max_window_bits, + client_max_window_bits, + ) + + +class ClientPerMessageDeflateFactory(ClientExtensionFactory): + """ + Client-side extension factory for the Per-Message Deflate extension. + + Parameters behave as described in `section 7.1 of RFC 7692`_. + + .. _section 7.1 of RFC 7692: https://datatracker.ietf.org/doc/html/rfc7692#section-7.1 + + Set them to :obj:`True` to include them in the negotiation offer without a + value or to an integer value to include them with this value. + + Args: + server_no_context_takeover: Prevent server from using context takeover. + client_no_context_takeover: Prevent client from using context takeover. + server_max_window_bits: Maximum size of the server's LZ77 sliding window + in bits, between 8 and 15. + client_max_window_bits: Maximum size of the client's LZ77 sliding window + in bits, between 8 and 15, or :obj:`True` to indicate support without + setting a limit. + compress_settings: Additional keyword arguments for :func:`zlib.compressobj`, + excluding ``wbits``. + + """ + + name = ExtensionName("permessage-deflate") + + def __init__( + self, + server_no_context_takeover: bool = False, + client_no_context_takeover: bool = False, + server_max_window_bits: int | None = None, + client_max_window_bits: int | Literal[True] | None = True, + compress_settings: dict[str, Any] | None = None, + ) -> None: + """ + Configure the Per-Message Deflate extension factory. + + """ + if not (server_max_window_bits is None or 8 <= server_max_window_bits <= 15): + raise ValueError("server_max_window_bits must be between 8 and 15") + if not ( + client_max_window_bits is None + or client_max_window_bits is True + or 8 <= client_max_window_bits <= 15 + ): + raise ValueError("client_max_window_bits must be between 8 and 15") + if compress_settings is not None and "wbits" in compress_settings: + raise ValueError( + "compress_settings must not include wbits, " + "set client_max_window_bits instead" + ) + + self.server_no_context_takeover = server_no_context_takeover + self.client_no_context_takeover = client_no_context_takeover + self.server_max_window_bits = server_max_window_bits + self.client_max_window_bits = client_max_window_bits + self.compress_settings = compress_settings + + def get_request_params(self) -> Sequence[ExtensionParameter]: + """ + Build request parameters. + + """ + return _build_parameters( + self.server_no_context_takeover, + self.client_no_context_takeover, + self.server_max_window_bits, + self.client_max_window_bits, + ) + + def process_response_params( + self, + params: Sequence[ExtensionParameter], + accepted_extensions: Sequence[Extension], + ) -> PerMessageDeflate: + """ + Process response parameters. + + Return an extension instance. + + """ + if any(other.name == self.name for other in accepted_extensions): + raise NegotiationError(f"received duplicate {self.name}") + + # Request parameters are available in instance variables. + + # Load response parameters in local variables. + ( + server_no_context_takeover, + client_no_context_takeover, + server_max_window_bits, + client_max_window_bits, + ) = _extract_parameters(params, is_server=False) + + # After comparing the request and the response, the final + # configuration must be available in the local variables. + + # server_no_context_takeover + # + # Req. Resp. Result + # ------ ------ -------------------------------------------------- + # False False False + # False True True + # True False Error! + # True True True + + if self.server_no_context_takeover: + if not server_no_context_takeover: + raise NegotiationError("expected server_no_context_takeover") + + # client_no_context_takeover + # + # Req. Resp. Result + # ------ ------ -------------------------------------------------- + # False False False + # False True True + # True False True - must change value + # True True True + + if self.client_no_context_takeover: + if not client_no_context_takeover: + client_no_context_takeover = True + + # server_max_window_bits + + # Req. Resp. Result + # ------ ------ -------------------------------------------------- + # None None None + # None 8≀M≀15 M + # 8≀N≀15 None Error! + # 8≀N≀15 8≀M≀N M + # 8≀N≀15 N self.server_max_window_bits: + raise NegotiationError("unsupported server_max_window_bits") + + # client_max_window_bits + + # Req. Resp. Result + # ------ ------ -------------------------------------------------- + # None None None + # None 8≀M≀15 Error! + # True None None + # True 8≀M≀15 M + # 8≀N≀15 None N - must change value + # 8≀N≀15 8≀M≀N M + # 8≀N≀15 N self.client_max_window_bits: + raise NegotiationError("unsupported client_max_window_bits") + + return PerMessageDeflate( + server_no_context_takeover, # remote_no_context_takeover + client_no_context_takeover, # local_no_context_takeover + server_max_window_bits or 15, # remote_max_window_bits + client_max_window_bits or 15, # local_max_window_bits + self.compress_settings, + ) + + +def enable_client_permessage_deflate( + extensions: Sequence[ClientExtensionFactory] | None, +) -> Sequence[ClientExtensionFactory]: + """ + Enable Per-Message Deflate with default settings in client extensions. + + If the extension is already present, perhaps with non-default settings, + the configuration isn't changed. + + """ + if extensions is None: + extensions = [] + if not any( + extension_factory.name == ClientPerMessageDeflateFactory.name + for extension_factory in extensions + ): + extensions = list(extensions) + [ + ClientPerMessageDeflateFactory( + compress_settings={"memLevel": 5}, + ) + ] + return extensions + + +class ServerPerMessageDeflateFactory(ServerExtensionFactory): + """ + Server-side extension factory for the Per-Message Deflate extension. + + Parameters behave as described in `section 7.1 of RFC 7692`_. + + .. _section 7.1 of RFC 7692: https://datatracker.ietf.org/doc/html/rfc7692#section-7.1 + + Set them to :obj:`True` to include them in the negotiation offer without a + value or to an integer value to include them with this value. + + Args: + server_no_context_takeover: Prevent server from using context takeover. + client_no_context_takeover: Prevent client from using context takeover. + server_max_window_bits: Maximum size of the server's LZ77 sliding window + in bits, between 8 and 15. + client_max_window_bits: Maximum size of the client's LZ77 sliding window + in bits, between 8 and 15. + compress_settings: Additional keyword arguments for :func:`zlib.compressobj`, + excluding ``wbits``. + require_client_max_window_bits: Do not enable compression at all if + client doesn't advertise support for ``client_max_window_bits``; + the default behavior is to enable compression without enforcing + ``client_max_window_bits``. + + """ + + name = ExtensionName("permessage-deflate") + + def __init__( + self, + server_no_context_takeover: bool = False, + client_no_context_takeover: bool = False, + server_max_window_bits: int | None = None, + client_max_window_bits: int | None = None, + compress_settings: dict[str, Any] | None = None, + require_client_max_window_bits: bool = False, + ) -> None: + """ + Configure the Per-Message Deflate extension factory. + + """ + if not (server_max_window_bits is None or 8 <= server_max_window_bits <= 15): + raise ValueError("server_max_window_bits must be between 8 and 15") + if not (client_max_window_bits is None or 8 <= client_max_window_bits <= 15): + raise ValueError("client_max_window_bits must be between 8 and 15") + if compress_settings is not None and "wbits" in compress_settings: + raise ValueError( + "compress_settings must not include wbits, " + "set server_max_window_bits instead" + ) + if client_max_window_bits is None and require_client_max_window_bits: + raise ValueError( + "require_client_max_window_bits is enabled, " + "but client_max_window_bits isn't configured" + ) + + self.server_no_context_takeover = server_no_context_takeover + self.client_no_context_takeover = client_no_context_takeover + self.server_max_window_bits = server_max_window_bits + self.client_max_window_bits = client_max_window_bits + self.compress_settings = compress_settings + self.require_client_max_window_bits = require_client_max_window_bits + + def process_request_params( + self, + params: Sequence[ExtensionParameter], + accepted_extensions: Sequence[Extension], + ) -> tuple[list[ExtensionParameter], PerMessageDeflate]: + """ + Process request parameters. + + Return response params and an extension instance. + + """ + if any(other.name == self.name for other in accepted_extensions): + raise NegotiationError(f"skipped duplicate {self.name}") + + # Load request parameters in local variables. + ( + server_no_context_takeover, + client_no_context_takeover, + server_max_window_bits, + client_max_window_bits, + ) = _extract_parameters(params, is_server=True) + + # Configuration parameters are available in instance variables. + + # After comparing the request and the configuration, the response must + # be available in the local variables. + + # server_no_context_takeover + # + # Config Req. Resp. + # ------ ------ -------------------------------------------------- + # False False False + # False True True + # True False True - must change value to True + # True True True + + if self.server_no_context_takeover: + if not server_no_context_takeover: + server_no_context_takeover = True + + # client_no_context_takeover + # + # Config Req. Resp. + # ------ ------ -------------------------------------------------- + # False False False + # False True True (or False) + # True False True - must change value to True + # True True True (or False) + + if self.client_no_context_takeover: + if not client_no_context_takeover: + client_no_context_takeover = True + + # server_max_window_bits + + # Config Req. Resp. + # ------ ------ -------------------------------------------------- + # None None None + # None 8≀M≀15 M + # 8≀N≀15 None N - must change value + # 8≀N≀15 8≀M≀N M + # 8≀N≀15 N self.server_max_window_bits: + server_max_window_bits = self.server_max_window_bits + + # client_max_window_bits + + # Config Req. Resp. + # ------ ------ -------------------------------------------------- + # None None None + # None True None - must change value + # None 8≀M≀15 M (or None) + # 8≀N≀15 None None or Error! + # 8≀N≀15 True N - must change value + # 8≀N≀15 8≀M≀N M (or None) + # 8≀N≀15 N Sequence[ServerExtensionFactory]: + """ + Enable Per-Message Deflate with default settings in server extensions. + + If the extension is already present, perhaps with non-default settings, + the configuration isn't changed. + + """ + if extensions is None: + extensions = [] + if not any( + ext_factory.name == ServerPerMessageDeflateFactory.name + for ext_factory in extensions + ): + extensions = list(extensions) + [ + ServerPerMessageDeflateFactory( + server_max_window_bits=12, + client_max_window_bits=12, + compress_settings={"memLevel": 5}, + ) + ] + return extensions diff --git a/.venv/Lib/site-packages/websockets/frames.py b/.venv/Lib/site-packages/websockets/frames.py new file mode 100644 index 0000000000000000000000000000000000000000..efce6c1634ec356ac9f6e3cf95be72d163de4c48 --- /dev/null +++ b/.venv/Lib/site-packages/websockets/frames.py @@ -0,0 +1,552 @@ +from __future__ import annotations + +import dataclasses +import enum +import io +import os +import secrets +import struct +from collections.abc import Generator, Sequence +from typing import Callable + +from .exceptions import PayloadTooBig, ProtocolError +from .typing import BytesLike + + +try: + from .speedups import apply_mask +except ImportError: + from .utils import apply_mask + + +__all__ = [ + "Opcode", + "OP_CONT", + "OP_TEXT", + "OP_BINARY", + "OP_CLOSE", + "OP_PING", + "OP_PONG", + "DATA_OPCODES", + "CTRL_OPCODES", + "CloseCode", + "Frame", + "Close", +] + + +class Opcode(enum.IntEnum): + """Opcode values for WebSocket frames.""" + + CONT, TEXT, BINARY = 0x00, 0x01, 0x02 + CLOSE, PING, PONG = 0x08, 0x09, 0x0A + + +OP_CONT = Opcode.CONT +OP_TEXT = Opcode.TEXT +OP_BINARY = Opcode.BINARY +OP_CLOSE = Opcode.CLOSE +OP_PING = Opcode.PING +OP_PONG = Opcode.PONG + +DATA_OPCODES = OP_CONT, OP_TEXT, OP_BINARY +CTRL_OPCODES = OP_CLOSE, OP_PING, OP_PONG + + +class CloseCode(enum.IntEnum): + """Close code values for WebSocket close frames.""" + + NORMAL_CLOSURE = 1000 + GOING_AWAY = 1001 + PROTOCOL_ERROR = 1002 + UNSUPPORTED_DATA = 1003 + # 1004 is reserved + NO_STATUS_RCVD = 1005 + ABNORMAL_CLOSURE = 1006 + INVALID_DATA = 1007 + POLICY_VIOLATION = 1008 + MESSAGE_TOO_BIG = 1009 + MANDATORY_EXTENSION = 1010 + INTERNAL_ERROR = 1011 + SERVICE_RESTART = 1012 + TRY_AGAIN_LATER = 1013 + BAD_GATEWAY = 1014 + TLS_HANDSHAKE = 1015 + + +# See https://www.iana.org/assignments/websocket/websocket.xhtml +CLOSE_CODE_EXPLANATIONS: dict[int, str] = { + CloseCode.NORMAL_CLOSURE: "OK", + CloseCode.GOING_AWAY: "going away", + CloseCode.PROTOCOL_ERROR: "protocol error", + CloseCode.UNSUPPORTED_DATA: "unsupported data", + CloseCode.NO_STATUS_RCVD: "no status received [internal]", + CloseCode.ABNORMAL_CLOSURE: "abnormal closure [internal]", + CloseCode.INVALID_DATA: "invalid frame payload data", + CloseCode.POLICY_VIOLATION: "policy violation", + CloseCode.MESSAGE_TOO_BIG: "message too big", + CloseCode.MANDATORY_EXTENSION: "mandatory extension", + CloseCode.INTERNAL_ERROR: "internal error", + CloseCode.SERVICE_RESTART: "service restart", + CloseCode.TRY_AGAIN_LATER: "try again later", + CloseCode.BAD_GATEWAY: "bad gateway", + CloseCode.TLS_HANDSHAKE: "TLS handshake failure [internal]", +} + + +# Close code that are allowed in a close frame. +# Using a set optimizes `code in EXTERNAL_CLOSE_CODES`. +EXTERNAL_CLOSE_CODES = { + CloseCode.NORMAL_CLOSURE, + CloseCode.GOING_AWAY, + CloseCode.PROTOCOL_ERROR, + CloseCode.UNSUPPORTED_DATA, + CloseCode.INVALID_DATA, + CloseCode.POLICY_VIOLATION, + CloseCode.MESSAGE_TOO_BIG, + CloseCode.MANDATORY_EXTENSION, + CloseCode.INTERNAL_ERROR, + CloseCode.SERVICE_RESTART, + CloseCode.TRY_AGAIN_LATER, + CloseCode.BAD_GATEWAY, +} + + +OK_CLOSE_CODES = { + CloseCode.NORMAL_CLOSURE, + CloseCode.GOING_AWAY, + CloseCode.NO_STATUS_RCVD, +} + + +@dataclasses.dataclass +class Frame: + """ + WebSocket frame. + + Attributes: + opcode: Opcode. + data: Payload data. + fin: FIN bit. + rsv1: RSV1 bit. + rsv2: RSV2 bit. + rsv3: RSV3 bit. + + Only these fields are needed. The MASK bit, payload length and masking-key + are handled on the fly when parsing and serializing frames. + + """ + + opcode: Opcode + data: BytesLike + fin: bool = True + rsv1: bool = False + rsv2: bool = False + rsv3: bool = False + + # Configure if you want to see more in logs. Should be a multiple of 3. + MAX_LOG_SIZE = int(os.environ.get("WEBSOCKETS_MAX_LOG_SIZE", "75")) + + DEFAULT_IS_TEXT = {OP_TEXT: True, OP_BINARY: False, OP_CLOSE: True} + + def __str__(self) -> str: + """ + Return a human-readable representation of a frame. + + This function is intended for logging and debugging. It doesn't aim to + support round-tripping because payloads can be too long for displaying + conveniently. Instead, it shows the beginning and the end. It's robust + to incorrect data. + + It attempts to decode UTF-8 payloads whenever possible, even for binary + frames and control frames, because those frequently contain UTF-8 data. + It applies the same logic to continuation frames, because we don't know + if they continue a text frame or a binary frame. + + """ + expect_text = self.DEFAULT_IS_TEXT.get(self.opcode) + data_repr, is_text = self._data_repr() + + data_type = "" if expect_text == is_text else ("text" if is_text else "binary") + length = f"{len(self.data)} byte{'' if len(self.data) == 1 else 's'}" + non_final = "" if self.fin else "continued" + metadata = ", ".join(filter(None, [data_type, length, non_final])) + + return f"{self.opcode.name} {data_repr} [{metadata}]" + + def _data_repr(self) -> tuple[str, bool | None]: + """ + Return a human-readable representation of the payload. + + Also returns whether the payload is text. + + The representation is elided to fit ``MAX_LOG_SIZE``. + + This is a helper for the __str__ method. + + """ + if not self.data: + return "''", self.DEFAULT_IS_TEXT.get(self.opcode) + + # Special case for close frames: parse close code and reason. + # Fall back to the standard case if the payload is malformed. + + if self.opcode is OP_CLOSE: + try: + return str(Close.parse(self.data)), True + except (ProtocolError, UnicodeDecodeError): + pass + + # Guess whether the payload is UTF-8 or binary, regardless of opcode, to + # display UTF-8 text in binary frames nicely and generally to be helpful + # and robust. Also support frames fragmented within UTF-8 sequences. + + if len(self.data) > 4 * self.MAX_LOG_SIZE: + # Process only the start and the end, as the middle will be elided. + # Cast to bytes because self.data could be a memoryview. + data_start = bytes(self.data[: 8 * self.MAX_LOG_SIZE // 3]) + data_end = bytes(self.data[-4 * self.MAX_LOG_SIZE // 3 :]) + is_text = is_utf8_fragment( + data_start, + must_start_clean=self.opcode != OP_CONT, + ) and is_utf8_fragment( + data_end, + must_end_clean=self.fin, + ) + if is_text: + data_repr = repr((data_start + data_end).decode(errors="replace")) + + else: + # Cast to bytes because self.data could be a memoryview. + data = bytes(self.data) + is_text = is_utf8_fragment( + data, + must_start_clean=self.opcode != OP_CONT, + must_end_clean=self.fin, + ) + if is_text: + data_repr = repr(data.decode(errors="replace")) + + # When the payload is text (except perhaps for boundaries), we decoded + # enough in ``data_repr``. Now, do the same when the payload is binary. + + if not is_text: + binary = self.data + if len(binary) > self.MAX_LOG_SIZE // 3: + cut = (self.MAX_LOG_SIZE // 3 - 1) // 3 # by default cut = 8 + # Encode two dummy bytes to force eliding and adding an ellipsis. + binary = b"".join([binary[: 2 * cut], b"\x00\x00", binary[-cut:]]) + data_repr = " ".join(f"{byte:02x}" for byte in binary) + + # Elide the middle of the representation to fit the maximum log size. + + if len(data_repr) > self.MAX_LOG_SIZE: + cut = self.MAX_LOG_SIZE // 3 - 1 # by default cut = 24 + data_repr = data_repr[: 2 * cut] + "..." + data_repr[-cut:] + + return data_repr, is_text + + @classmethod + def parse( + cls, + read_exact: Callable[[int], Generator[None, None, bytes | bytearray]], + *, + mask: bool, + max_size: int | None = None, + extensions: Sequence[extensions.Extension] | None = None, + ) -> Generator[None, None, Frame]: + """ + Parse a WebSocket frame. + + This is a generator-based coroutine. + + Args: + read_exact: Generator-based coroutine that reads the requested + bytes or raises an exception if there isn't enough data. + mask: Whether the frame should be masked i.e. whether the read + happens on the server side. + max_size: Maximum payload size in bytes. + extensions: List of extensions, applied in reverse order. + + Raises: + EOFError: If the connection is closed without a full WebSocket frame. + PayloadTooBig: If the frame's payload size exceeds ``max_size``. + ProtocolError: If the frame contains incorrect values. + + """ + # Read the header. + data = yield from read_exact(2) + head1, head2 = struct.unpack("!BB", data) + + # While not Pythonic, this is marginally faster than calling bool(). + fin = True if head1 & 0b10000000 else False + rsv1 = True if head1 & 0b01000000 else False + rsv2 = True if head1 & 0b00100000 else False + rsv3 = True if head1 & 0b00010000 else False + + try: + opcode = Opcode(head1 & 0b00001111) + except ValueError as exc: + raise ProtocolError("invalid opcode") from exc + + if (True if head2 & 0b10000000 else False) != mask: + raise ProtocolError("incorrect masking") + + length = head2 & 0b01111111 + if length == 126: + data = yield from read_exact(2) + (length,) = struct.unpack("!H", data) + elif length == 127: + data = yield from read_exact(8) + (length,) = struct.unpack("!Q", data) + if max_size is not None and length > max_size: + raise PayloadTooBig(length, max_size) + if mask: + mask_bytes = yield from read_exact(4) + + # Read the data. + data = yield from read_exact(length) + if mask: + data = apply_mask(data, mask_bytes) + + frame = cls(opcode, data, fin, rsv1, rsv2, rsv3) + + if extensions is None: + extensions = [] + for extension in reversed(extensions): + frame = extension.decode(frame, max_size=max_size) + + frame.check() + + return frame + + def serialize( + self, + *, + mask: bool, + extensions: Sequence[extensions.Extension] | None = None, + ) -> bytes: + """ + Serialize a WebSocket frame. + + Args: + mask: Whether the frame should be masked i.e. whether the write + happens on the client side. + extensions: List of extensions, applied in order. + + Raises: + ProtocolError: If the frame contains incorrect values. + + """ + self.check() + + if extensions is None: + extensions = [] + for extension in extensions: + self = extension.encode(self) + + output = io.BytesIO() + + # Prepare the header. + head1 = ( + (0b10000000 if self.fin else 0) + | (0b01000000 if self.rsv1 else 0) + | (0b00100000 if self.rsv2 else 0) + | (0b00010000 if self.rsv3 else 0) + | self.opcode + ) + + head2 = 0b10000000 if mask else 0 + + length = len(self.data) + if length < 126: + output.write(struct.pack("!BB", head1, head2 | length)) + elif length < 65536: + output.write(struct.pack("!BBH", head1, head2 | 126, length)) + else: + output.write(struct.pack("!BBQ", head1, head2 | 127, length)) + + if mask: + mask_bytes = secrets.token_bytes(4) + output.write(mask_bytes) + + # Prepare the data. + data: BytesLike + if mask: + data = apply_mask(self.data, mask_bytes) + else: + data = self.data + output.write(data) + + return output.getvalue() + + def check(self) -> None: + """ + Check that reserved bits and opcode have acceptable values. + + Raises: + ProtocolError: If a reserved bit or the opcode is invalid. + + """ + if self.rsv1 or self.rsv2 or self.rsv3: + raise ProtocolError("reserved bits must be 0") + + if self.opcode in CTRL_OPCODES: + if len(self.data) > 125: + raise ProtocolError("control frame too long") + if not self.fin: + raise ProtocolError("fragmented control frame") + + +@dataclasses.dataclass +class Close: + """ + Code and reason for WebSocket close frames. + + Attributes: + code: Close code. + reason: Close reason. + + """ + + code: CloseCode | int + reason: str + + def __str__(self) -> str: + """ + Return a human-readable representation of a close code and reason. + + """ + if 3000 <= self.code < 4000: + explanation = "registered" + elif 4000 <= self.code < 5000: + explanation = "private use" + else: + explanation = CLOSE_CODE_EXPLANATIONS.get(self.code, "unknown") + result = f"{self.code} ({explanation})" + + if self.reason: + result = f"{result} {self.reason}" + + return result + + @classmethod + def parse(cls, data: BytesLike) -> Close: + """ + Parse the payload of a close frame. + + Args: + data: Payload of the close frame. + + Raises: + ProtocolError: If data is ill-formed. + UnicodeDecodeError: If the reason isn't valid UTF-8. + + """ + if isinstance(data, memoryview): + raise AssertionError("only compressed outgoing frames use memoryview") + if len(data) >= 2: + (code,) = struct.unpack("!H", data[:2]) + reason = data[2:].decode() + close = cls(code, reason) + close.check() + return close + elif len(data) == 0: + return cls(CloseCode.NO_STATUS_RCVD, "") + else: + raise ProtocolError("close frame too short") + + def serialize(self) -> bytes: + """ + Serialize the payload of a close frame. + + """ + self.check() + return struct.pack("!H", self.code) + self.reason.encode() + + def check(self) -> None: + """ + Check that the close code has a valid value for a close frame. + + Raises: + ProtocolError: If the close code is invalid. + + """ + if not (self.code in EXTERNAL_CLOSE_CODES or 3000 <= self.code < 5000): + raise ProtocolError("invalid status code") + + +def is_utf8_fragment( + data: bytes, + must_start_clean: bool = False, + must_end_clean: bool = False, +) -> bool: + """Guess if data is a fragment of UTF-8 text.""" + # Possible byte sequences for UTF-8 characters are: + # 0xxxxxxx + # 110xxxxx 10xxxxxx + # 1110xxxx 10xxxxxx 10xxxxxx + # 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + + # The algorithm determines ``start`` and ``end`` so that ``data[start:end]`` + # must be a valid UTF-8 sequence for data to be a valid UTF-8 fragment. + + start, end = 0, len(data) + + if not must_start_clean: + # Remove continuation bytes from the beginning. + max_start = min(3, len(data)) + while start < max_start: + byte = data[start] + + # Continuation byte + if byte & 0b11000000 == 0b10000000: + start += 1 + continue + + break + + if not must_end_clean: + # Remove a partial multibyte sequence from the end. + end -= 1 # index of the last byte + min_end = max(len(data) - 4, start) + while end >= min_end: + byte = data[end] + # Continuation byte + if byte & 0b11000000 == 0b10000000: + end -= 1 + continue + + # ASCII byte + if byte & 0b10000000 == 0b00000000: + seq_len = 1 + # Leading byte of a 2-byte sequence + elif byte & 0b11100000 == 0b11000000: + seq_len = 2 + # Leading byte of a 3-byte sequence + elif byte & 0b11110000 == 0b11100000: + seq_len = 3 + # Leading byte of a 4-byte sequence + elif byte & 0b11111000 == 0b11110000: + seq_len = 4 + # Invalid byte + else: + seq_len = 0 + + # Cut only when there's an incomplete sequence at the end. + if seq_len <= len(data) - end: + end = len(data) + + break + + try: + text = data[start:end].decode() + except UnicodeDecodeError: + return False + else: + # Non-printable characters signal binary data. + return "\\x" not in repr(text) + + +# At the bottom to break import cycles created by type annotations. +from . import extensions # noqa: E402 diff --git a/.venv/Lib/site-packages/websockets/headers.py b/.venv/Lib/site-packages/websockets/headers.py new file mode 100644 index 0000000000000000000000000000000000000000..0bfb255376f01a078134f825cf56610a381ab4ab --- /dev/null +++ b/.venv/Lib/site-packages/websockets/headers.py @@ -0,0 +1,586 @@ +from __future__ import annotations + +import base64 +import binascii +import ipaddress +import re +from collections.abc import Sequence +from typing import Callable, TypeVar, cast + +from .exceptions import InvalidHeaderFormat, InvalidHeaderValue +from .typing import ( + ConnectionOption, + ExtensionHeader, + ExtensionName, + ExtensionParameter, + Subprotocol, + UpgradeProtocol, +) + + +__all__ = [ + "build_host", + "parse_connection", + "parse_upgrade", + "parse_extension", + "build_extension", + "parse_subprotocol", + "build_subprotocol", + "validate_subprotocols", + "build_www_authenticate_basic", + "parse_authorization_basic", + "build_authorization_basic", +] + + +T = TypeVar("T") + + +def build_host( + host: str, + port: int, + secure: bool, + *, + always_include_port: bool = False, +) -> str: + """ + Build a ``Host`` header. + + """ + # https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2 + # IPv6 addresses must be enclosed in brackets. + try: + address = ipaddress.ip_address(host) + except ValueError: + # host is a hostname + pass + else: + # host is an IP address + if address.version == 6: + host = f"[{host}]" + + if always_include_port or port != (443 if secure else 80): + host = f"{host}:{port}" + + return host + + +# To avoid a dependency on a parsing library, we implement manually the ABNF +# described in https://datatracker.ietf.org/doc/html/rfc6455#section-9.1 and +# https://datatracker.ietf.org/doc/html/rfc7230#appendix-B. + + +def peek_ahead(header: str, pos: int) -> str | None: + """ + Return the next character from ``header`` at the given position. + + Return :obj:`None` at the end of ``header``. + + We never need to peek more than one character ahead. + + """ + return None if pos == len(header) else header[pos] + + +_OWS_re = re.compile(r"[\t ]*") + + +def parse_OWS(header: str, pos: int) -> int: + """ + Parse optional whitespace from ``header`` at the given position. + + Return the new position. + + The whitespace itself isn't returned because it isn't significant. + + """ + # There's always a match, possibly empty, whose content doesn't matter. + match = _OWS_re.match(header, pos) + assert match is not None + return match.end() + + +_token_re = re.compile(r"[-!#$%&\'*+.^_`|~0-9a-zA-Z]+") + + +def parse_token(header: str, pos: int, header_name: str) -> tuple[str, int]: + """ + Parse a token from ``header`` at the given position. + + Return the token value and the new position. + + Raises: + InvalidHeaderFormat: On invalid inputs. + + """ + match = _token_re.match(header, pos) + if match is None: + raise InvalidHeaderFormat(header_name, "expected token", header, pos) + return match.group(), match.end() + + +_quoted_string_re = re.compile( + r'"(?:[\x09\x20-\x21\x23-\x5b\x5d-\x7e]|\\[\x09\x20-\x7e\x80-\xff])*"' +) + + +_unquote_re = re.compile(r"\\([\x09\x20-\x7e\x80-\xff])") + + +def parse_quoted_string(header: str, pos: int, header_name: str) -> tuple[str, int]: + """ + Parse a quoted string from ``header`` at the given position. + + Return the unquoted value and the new position. + + Raises: + InvalidHeaderFormat: On invalid inputs. + + """ + match = _quoted_string_re.match(header, pos) + if match is None: + raise InvalidHeaderFormat(header_name, "expected quoted string", header, pos) + return _unquote_re.sub(r"\1", match.group()[1:-1]), match.end() + + +_quotable_re = re.compile(r"[\x09\x20-\x7e\x80-\xff]*") + + +_quote_re = re.compile(r"([\x22\x5c])") + + +def build_quoted_string(value: str) -> str: + """ + Format ``value`` as a quoted string. + + This is the reverse of :func:`parse_quoted_string`. + + """ + match = _quotable_re.fullmatch(value) + if match is None: + raise ValueError("invalid characters for quoted-string encoding") + return '"' + _quote_re.sub(r"\\\1", value) + '"' + + +def parse_list( + parse_item: Callable[[str, int, str], tuple[T, int]], + header: str, + pos: int, + header_name: str, +) -> list[T]: + """ + Parse a comma-separated list from ``header`` at the given position. + + This is appropriate for parsing values with the following grammar: + + 1#item + + ``parse_item`` parses one item. + + ``header`` is assumed not to start or end with whitespace. + + (This function is designed for parsing an entire header value and + :func:`~websockets.http.read_headers` strips whitespace from values.) + + Return a list of items. + + Raises: + InvalidHeaderFormat: On invalid inputs. + + """ + # Per https://datatracker.ietf.org/doc/html/rfc7230#section-7, "a recipient + # MUST parse and ignore a reasonable number of empty list elements"; + # hence while loops that remove extra delimiters. + + # Remove extra delimiters before the first item. + while peek_ahead(header, pos) == ",": + pos = parse_OWS(header, pos + 1) + + items = [] + while True: + # Loop invariant: a item starts at pos in header. + item, pos = parse_item(header, pos, header_name) + items.append(item) + pos = parse_OWS(header, pos) + + # We may have reached the end of the header. + if pos == len(header): + break + + # There must be a delimiter after each element except the last one. + if peek_ahead(header, pos) == ",": + pos = parse_OWS(header, pos + 1) + else: + raise InvalidHeaderFormat(header_name, "expected comma", header, pos) + + # Remove extra delimiters before the next item. + while peek_ahead(header, pos) == ",": + pos = parse_OWS(header, pos + 1) + + # We may have reached the end of the header. + if pos == len(header): + break + + # Since we only advance in the header by one character with peek_ahead() + # or with the end position of a regex match, we can't overshoot the end. + assert pos == len(header) + + return items + + +def parse_connection_option( + header: str, pos: int, header_name: str +) -> tuple[ConnectionOption, int]: + """ + Parse a Connection option from ``header`` at the given position. + + Return the protocol value and the new position. + + Raises: + InvalidHeaderFormat: On invalid inputs. + + """ + item, pos = parse_token(header, pos, header_name) + return cast(ConnectionOption, item), pos + + +def parse_connection(header: str) -> list[ConnectionOption]: + """ + Parse a ``Connection`` header. + + Return a list of HTTP connection options. + + Args + header: value of the ``Connection`` header. + + Raises: + InvalidHeaderFormat: On invalid inputs. + + """ + return parse_list(parse_connection_option, header, 0, "Connection") + + +_protocol_re = re.compile( + r"[-!#$%&\'*+.^_`|~0-9a-zA-Z]+(?:/[-!#$%&\'*+.^_`|~0-9a-zA-Z]+)?" +) + + +def parse_upgrade_protocol( + header: str, pos: int, header_name: str +) -> tuple[UpgradeProtocol, int]: + """ + Parse an Upgrade protocol from ``header`` at the given position. + + Return the protocol value and the new position. + + Raises: + InvalidHeaderFormat: On invalid inputs. + + """ + match = _protocol_re.match(header, pos) + if match is None: + raise InvalidHeaderFormat(header_name, "expected protocol", header, pos) + return cast(UpgradeProtocol, match.group()), match.end() + + +def parse_upgrade(header: str) -> list[UpgradeProtocol]: + """ + Parse an ``Upgrade`` header. + + Return a list of HTTP protocols. + + Args: + header: Value of the ``Upgrade`` header. + + Raises: + InvalidHeaderFormat: On invalid inputs. + + """ + return parse_list(parse_upgrade_protocol, header, 0, "Upgrade") + + +def parse_extension_item_param( + header: str, pos: int, header_name: str +) -> tuple[ExtensionParameter, int]: + """ + Parse a single extension parameter from ``header`` at the given position. + + Return a ``(name, value)`` pair and the new position. + + Raises: + InvalidHeaderFormat: On invalid inputs. + + """ + # Extract parameter name. + name, pos = parse_token(header, pos, header_name) + pos = parse_OWS(header, pos) + # Extract parameter value, if there is one. + value: str | None = None + if peek_ahead(header, pos) == "=": + pos = parse_OWS(header, pos + 1) + if peek_ahead(header, pos) == '"': + pos_before = pos # for proper error reporting below + value, pos = parse_quoted_string(header, pos, header_name) + # https://datatracker.ietf.org/doc/html/rfc6455#section-9.1 says: + # the value after quoted-string unescaping MUST conform to + # the 'token' ABNF. + if _token_re.fullmatch(value) is None: + raise InvalidHeaderFormat( + header_name, "invalid quoted header content", header, pos_before + ) + else: + value, pos = parse_token(header, pos, header_name) + pos = parse_OWS(header, pos) + + return (name, value), pos + + +def parse_extension_item( + header: str, pos: int, header_name: str +) -> tuple[ExtensionHeader, int]: + """ + Parse an extension definition from ``header`` at the given position. + + Return an ``(extension name, parameters)`` pair, where ``parameters`` is a + list of ``(name, value)`` pairs, and the new position. + + Raises: + InvalidHeaderFormat: On invalid inputs. + + """ + # Extract extension name. + name, pos = parse_token(header, pos, header_name) + pos = parse_OWS(header, pos) + # Extract all parameters. + parameters = [] + while peek_ahead(header, pos) == ";": + pos = parse_OWS(header, pos + 1) + parameter, pos = parse_extension_item_param(header, pos, header_name) + parameters.append(parameter) + return (cast(ExtensionName, name), parameters), pos + + +def parse_extension(header: str) -> list[ExtensionHeader]: + """ + Parse a ``Sec-WebSocket-Extensions`` header. + + Return a list of WebSocket extensions and their parameters in this format:: + + [ + ( + 'extension name', + [ + ('parameter name', 'parameter value'), + .... + ] + ), + ... + ] + + Parameter values are :obj:`None` when no value is provided. + + Raises: + InvalidHeaderFormat: On invalid inputs. + + """ + return parse_list(parse_extension_item, header, 0, "Sec-WebSocket-Extensions") + + +parse_extension_list = parse_extension # alias for backwards compatibility + + +def build_extension_item( + name: ExtensionName, parameters: Sequence[ExtensionParameter] +) -> str: + """ + Build an extension definition. + + This is the reverse of :func:`parse_extension_item`. + + """ + return "; ".join( + [cast(str, name)] + + [ + # Quoted strings aren't necessary because values are always tokens. + name if value is None else f"{name}={value}" + for name, value in parameters + ] + ) + + +def build_extension(extensions: Sequence[ExtensionHeader]) -> str: + """ + Build a ``Sec-WebSocket-Extensions`` header. + + This is the reverse of :func:`parse_extension`. + + """ + return ", ".join( + build_extension_item(name, parameters) for name, parameters in extensions + ) + + +build_extension_list = build_extension # alias for backwards compatibility + + +def parse_subprotocol_item( + header: str, pos: int, header_name: str +) -> tuple[Subprotocol, int]: + """ + Parse a subprotocol from ``header`` at the given position. + + Return the subprotocol value and the new position. + + Raises: + InvalidHeaderFormat: On invalid inputs. + + """ + item, pos = parse_token(header, pos, header_name) + return cast(Subprotocol, item), pos + + +def parse_subprotocol(header: str) -> list[Subprotocol]: + """ + Parse a ``Sec-WebSocket-Protocol`` header. + + Return a list of WebSocket subprotocols. + + Raises: + InvalidHeaderFormat: On invalid inputs. + + """ + return parse_list(parse_subprotocol_item, header, 0, "Sec-WebSocket-Protocol") + + +parse_subprotocol_list = parse_subprotocol # alias for backwards compatibility + + +def build_subprotocol(subprotocols: Sequence[Subprotocol]) -> str: + """ + Build a ``Sec-WebSocket-Protocol`` header. + + This is the reverse of :func:`parse_subprotocol`. + + """ + return ", ".join(subprotocols) + + +build_subprotocol_list = build_subprotocol # alias for backwards compatibility + + +def validate_subprotocols(subprotocols: Sequence[Subprotocol]) -> None: + """ + Validate that ``subprotocols`` is suitable for :func:`build_subprotocol`. + + """ + if not isinstance(subprotocols, Sequence): + raise TypeError("subprotocols must be a list") + if isinstance(subprotocols, str): + raise TypeError("subprotocols must be a list, not a str") + for subprotocol in subprotocols: + if not _token_re.fullmatch(subprotocol): + raise ValueError(f"invalid subprotocol: {subprotocol}") + + +def build_www_authenticate_basic(realm: str) -> str: + """ + Build a ``WWW-Authenticate`` header for HTTP Basic Auth. + + Args: + realm: Identifier of the protection space. + + """ + # https://datatracker.ietf.org/doc/html/rfc7617#section-2 + realm = build_quoted_string(realm) + charset = build_quoted_string("UTF-8") + return f"Basic realm={realm}, charset={charset}" + + +_token68_re = re.compile(r"[A-Za-z0-9-._~+/]+=*") + + +def parse_token68(header: str, pos: int, header_name: str) -> tuple[str, int]: + """ + Parse a token68 from ``header`` at the given position. + + Return the token value and the new position. + + Raises: + InvalidHeaderFormat: On invalid inputs. + + """ + match = _token68_re.match(header, pos) + if match is None: + raise InvalidHeaderFormat(header_name, "expected token68", header, pos) + return match.group(), match.end() + + +def parse_end(header: str, pos: int, header_name: str) -> None: + """ + Check that parsing reached the end of header. + + """ + if pos < len(header): + raise InvalidHeaderFormat(header_name, "trailing data", header, pos) + + +def parse_authorization_basic(header: str) -> tuple[str, str]: + """ + Parse an ``Authorization`` header for HTTP Basic Auth. + + Return a ``(username, password)`` tuple. + + Args: + header: Value of the ``Authorization`` header. + + Raises: + InvalidHeaderFormat: On invalid inputs. + InvalidHeaderValue: On unsupported inputs. + + """ + # https://datatracker.ietf.org/doc/html/rfc7235#section-2.1 + # https://datatracker.ietf.org/doc/html/rfc7617#section-2 + scheme, pos = parse_token(header, 0, "Authorization") + if scheme.lower() != "basic": + raise InvalidHeaderValue( + "Authorization", + f"unsupported scheme: {scheme}", + ) + if peek_ahead(header, pos) != " ": + raise InvalidHeaderFormat( + "Authorization", "expected space after scheme", header, pos + ) + pos += 1 + basic_credentials, pos = parse_token68(header, pos, "Authorization") + parse_end(header, pos, "Authorization") + + try: + user_pass = base64.b64decode(basic_credentials.encode()).decode() + except binascii.Error: + raise InvalidHeaderValue( + "Authorization", + "expected base64-encoded credentials", + ) from None + try: + username, password = user_pass.split(":", 1) + except ValueError: + raise InvalidHeaderValue( + "Authorization", + "expected username:password credentials", + ) from None + + return username, password + + +def build_authorization_basic(username: str, password: str) -> str: + """ + Build an ``Authorization`` header for HTTP Basic Auth. + + This is the reverse of :func:`parse_authorization_basic`. + + """ + # https://datatracker.ietf.org/doc/html/rfc7617#section-2 + assert ":" not in username + user_pass = f"{username}:{password}" + basic_credentials = base64.b64encode(user_pass.encode()).decode() + return "Basic " + basic_credentials diff --git a/.venv/Lib/site-packages/websockets/http.py b/.venv/Lib/site-packages/websockets/http.py new file mode 100644 index 0000000000000000000000000000000000000000..24a0ee310cd5c8a88bec90b2a0aab39dd6e6c61e --- /dev/null +++ b/.venv/Lib/site-packages/websockets/http.py @@ -0,0 +1,20 @@ +from __future__ import annotations + +import warnings + +from .datastructures import Headers, MultipleValuesError # noqa: F401 + + +with warnings.catch_warnings(): + # Suppress redundant DeprecationWarning raised by websockets.legacy. + warnings.filterwarnings("ignore", category=DeprecationWarning) + from .legacy.http import read_request, read_response # noqa: F401 + + +warnings.warn( # deprecated in 9.0 - 2021-09-01 + "Headers and MultipleValuesError were moved " + "from websockets.http to websockets.datastructures" + "and read_request and read_response were moved " + "from websockets.http to websockets.legacy.http", + DeprecationWarning, +) diff --git a/.venv/Lib/site-packages/websockets/http11.py b/.venv/Lib/site-packages/websockets/http11.py new file mode 100644 index 0000000000000000000000000000000000000000..c6843e38f0a3958ee6420fefd111ba499374012c --- /dev/null +++ b/.venv/Lib/site-packages/websockets/http11.py @@ -0,0 +1,449 @@ +from __future__ import annotations + +import dataclasses +import os +import re +import sys +import warnings +from collections.abc import Generator +from typing import Callable + +from .datastructures import Headers +from .exceptions import SecurityError +from .version import version as websockets_version + + +__all__ = [ + "SERVER", + "USER_AGENT", + "Request", + "Response", +] + + +PYTHON_VERSION = "{}.{}".format(*sys.version_info) + +# User-Agent header for HTTP requests. +USER_AGENT = os.environ.get( + "WEBSOCKETS_USER_AGENT", + f"Python/{PYTHON_VERSION} websockets/{websockets_version}", +) + +# Server header for HTTP responses. +SERVER = os.environ.get( + "WEBSOCKETS_SERVER", + f"Python/{PYTHON_VERSION} websockets/{websockets_version}", +) + +# Maximum total size of headers is around 128 * 8 KiB = 1 MiB. +MAX_NUM_HEADERS = int(os.environ.get("WEBSOCKETS_MAX_NUM_HEADERS", "128")) + +# Limit request line and header lines. 8KiB is the most common default +# configuration of popular HTTP servers. +MAX_LINE_LENGTH = int(os.environ.get("WEBSOCKETS_MAX_LINE_LENGTH", "8192")) + +# Support for HTTP response bodies is intended to read an error message +# returned by a server. It isn't designed to perform large file transfers. +MAX_BODY_SIZE = int(os.environ.get("WEBSOCKETS_MAX_BODY_SIZE", "1_048_576")) # 1 MiB + + +def d(value: bytes | bytearray) -> str: + """ + Decode a bytestring for interpolating into an error message. + + """ + return value.decode(errors="backslashreplace") + + +# See https://datatracker.ietf.org/doc/html/rfc7230#appendix-B. + +# Regex for validating header names. + +_token_re = re.compile(rb"[-!#$%&\'*+.^_`|~0-9a-zA-Z]+") + +# Regex for validating header values. + +# We don't attempt to support obsolete line folding. + +# Include HTAB (\x09), SP (\x20), VCHAR (\x21-\x7e), obs-text (\x80-\xff). + +# The ABNF is complicated because it attempts to express that optional +# whitespace is ignored. We strip whitespace and don't revalidate that. + +# See also https://www.rfc-editor.org/errata_search.php?rfc=7230&eid=4189 + +_value_re = re.compile(rb"[\x09\x20-\x7e\x80-\xff]*") + + +@dataclasses.dataclass +class Request: + """ + WebSocket handshake request. + + Attributes: + path: Request path, including optional query. + headers: Request headers. + """ + + path: str + headers: Headers + # body isn't useful is the context of this library. + + _exception: Exception | None = None + + @property + def exception(self) -> Exception | None: # pragma: no cover + warnings.warn( # deprecated in 10.3 - 2022-04-17 + "Request.exception is deprecated; use ServerProtocol.handshake_exc instead", + DeprecationWarning, + ) + return self._exception + + @classmethod + def parse( + cls, + read_line: Callable[[int], Generator[None, None, bytes | bytearray]], + ) -> Generator[None, None, Request]: + """ + Parse a WebSocket handshake request. + + This is a generator-based coroutine. + + The request path isn't URL-decoded or validated in any way. + + The request path and headers are expected to contain only ASCII + characters. Other characters are represented with surrogate escapes. + + :meth:`parse` doesn't attempt to read the request body because + WebSocket handshake requests don't have one. If the request contains a + body, it may be read from the data stream after :meth:`parse` returns. + + Args: + read_line: Generator-based coroutine that reads a LF-terminated + line or raises an exception if there isn't enough data + + Raises: + EOFError: If the connection is closed without a full HTTP request. + SecurityError: If the request exceeds a security limit. + ValueError: If the request isn't well formatted. + + """ + # https://datatracker.ietf.org/doc/html/rfc7230#section-3.1.1 + + # Parsing is simple because fixed values are expected for method and + # version and because path isn't checked. Since WebSocket software tends + # to implement HTTP/1.1 strictly, there's little need for lenient parsing. + + try: + request_line = yield from parse_line(read_line) + except EOFError as exc: + raise EOFError("connection closed while reading HTTP request line") from exc + + try: + method, raw_path, protocol = request_line.split(b" ", 2) + except ValueError: # not enough values to unpack (expected 3, got 1-2) + raise ValueError(f"invalid HTTP request line: {d(request_line)}") from None + if protocol != b"HTTP/1.1": + raise ValueError( + f"unsupported protocol; expected HTTP/1.1: {d(request_line)}" + ) + if method != b"GET": + raise ValueError(f"unsupported HTTP method; expected GET; got {d(method)}") + + # RFC 9110 defers the definition of URIs to RFC 3986, which allows only + # a subset of ASCII. Non-ASCII IRIs must be UTF-8 then percent-encoded. + path = raw_path.decode("ascii") + + headers = yield from parse_headers(read_line) + + # https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.3 + + if "Transfer-Encoding" in headers: + raise NotImplementedError("transfer codings aren't supported") + + if "Content-Length" in headers: + # Some devices send a Content-Length header with a value of 0. + # This raises ValueError if Content-Length isn't an integer too. + if int(headers["Content-Length"]) != 0: + raise ValueError("unsupported request body") + + return cls(path, headers) + + def serialize(self) -> bytes: + """ + Serialize a WebSocket handshake request. + + """ + # Since the request line and headers only contain ASCII characters, + # we can keep this simple. + request = f"GET {self.path} HTTP/1.1\r\n".encode() + request += self.headers.serialize() + return request + + +@dataclasses.dataclass +class Response: + """ + WebSocket handshake response. + + Attributes: + status_code: Response code. + reason_phrase: Response reason. + headers: Response headers. + body: Response body. + + """ + + status_code: int + reason_phrase: str + headers: Headers + body: bytes | bytearray = b"" + + _exception: Exception | None = None + + @property + def exception(self) -> Exception | None: # pragma: no cover + warnings.warn( # deprecated in 10.3 - 2022-04-17 + "Response.exception is deprecated; " + "use ClientProtocol.handshake_exc instead", + DeprecationWarning, + ) + return self._exception + + @classmethod + def parse( + cls, + read_line: Callable[[int], Generator[None, None, bytes | bytearray]], + read_exact: Callable[[int], Generator[None, None, bytes | bytearray]], + read_to_eof: Callable[[int], Generator[None, None, bytes | bytearray]], + proxy: bool = False, + ) -> Generator[None, None, Response]: + """ + Parse a WebSocket handshake response. + + This is a generator-based coroutine. + + The reason phrase and headers are expected to contain only ASCII + characters. Other characters are represented with surrogate escapes. + + Args: + read_line: Generator-based coroutine that reads a LF-terminated + line or raises an exception if there isn't enough data. + read_exact: Generator-based coroutine that reads the requested + bytes or raises an exception if there isn't enough data. + read_to_eof: Generator-based coroutine that reads until the end + of the stream. + + Raises: + EOFError: If the connection is closed without a full HTTP response. + SecurityError: If the response exceeds a security limit. + LookupError: If the response isn't well formatted. + ValueError: If the response isn't well formatted. + + """ + # https://datatracker.ietf.org/doc/html/rfc7230#section-3.1.2 + + try: + status_line = yield from parse_line(read_line) + except EOFError as exc: + raise EOFError("connection closed while reading HTTP status line") from exc + + try: + protocol, raw_status_code, raw_reason = status_line.split(b" ", 2) + except ValueError: # not enough values to unpack (expected 3, got 1-2) + raise ValueError(f"invalid HTTP status line: {d(status_line)}") from None + if proxy: # some proxies still use HTTP/1.0 + if protocol not in [b"HTTP/1.1", b"HTTP/1.0"]: + raise ValueError( + f"unsupported protocol; expected HTTP/1.1 or HTTP/1.0: " + f"{d(status_line)}" + ) + else: + if protocol != b"HTTP/1.1": + raise ValueError( + f"unsupported protocol; expected HTTP/1.1: {d(status_line)}" + ) + try: + status_code = int(raw_status_code) + except ValueError: # invalid literal for int() with base 10 + raise ValueError( + f"invalid status code; expected integer; got {d(raw_status_code)}" + ) from None + if not 100 <= status_code < 600: + raise ValueError( + f"invalid status code; expected 100–599; got {d(raw_status_code)}" + ) + if not _value_re.fullmatch(raw_reason): + raise ValueError(f"invalid HTTP reason phrase: {d(raw_reason)}") + + # RFC 2616 implies ISO-8859-1. It's easy to reverse and cannot crash. + # Non-ASCII never worked reliably and the reason isn't useful anyway. + reason = raw_reason.decode("iso-8859-1") + + headers = yield from parse_headers(read_line) + + body: bytes | bytearray + if proxy: + body = b"" + else: + body = yield from read_body( + status_code, headers, read_line, read_exact, read_to_eof + ) + + return cls(status_code, reason, headers, body) + + def serialize(self) -> bytes: + """ + Serialize a WebSocket handshake response. + + """ + # Since the status line and headers only contain ASCII characters, + # we can keep this simple. + response = f"HTTP/1.1 {self.status_code} {self.reason_phrase}\r\n".encode() + response += self.headers.serialize() + response += self.body + return response + + +def parse_line( + read_line: Callable[[int], Generator[None, None, bytes | bytearray]], +) -> Generator[None, None, bytes | bytearray]: + """ + Parse a single line. + + CRLF is stripped from the return value. + + Args: + read_line: Generator-based coroutine that reads a LF-terminated line + or raises an exception if there isn't enough data. + + Raises: + EOFError: If the connection is closed without a CRLF. + SecurityError: If the response exceeds a security limit. + + """ + try: + line = yield from read_line(MAX_LINE_LENGTH) + except RuntimeError: + raise SecurityError("line too long") + # Not mandatory but safe - https://datatracker.ietf.org/doc/html/rfc7230#section-3.5 + if not line.endswith(b"\r\n"): + raise EOFError("line without CRLF") + return line[:-2] + + +def parse_headers( + read_line: Callable[[int], Generator[None, None, bytes | bytearray]], +) -> Generator[None, None, Headers]: + """ + Parse HTTP headers. + + Non-ASCII characters are represented with surrogate escapes. + + Args: + read_line: Generator-based coroutine that reads a LF-terminated line + or raises an exception if there isn't enough data. + + Raises: + EOFError: If the connection is closed without complete headers. + SecurityError: If the request exceeds a security limit. + ValueError: If the request isn't well formatted. + + """ + # https://datatracker.ietf.org/doc/html/rfc7230#section-3.2 + + # We don't attempt to support obsolete line folding. + + headers = Headers() + for _ in range(MAX_NUM_HEADERS + 1): + try: + line = yield from parse_line(read_line) + except EOFError as exc: + raise EOFError("connection closed while reading HTTP headers") from exc + if line == b"": + break + + try: + raw_name, raw_value = line.split(b":", 1) + except ValueError: # not enough values to unpack (expected 2, got 1) + raise ValueError(f"invalid HTTP header line: {d(line)}") from None + if not _token_re.fullmatch(raw_name): + raise ValueError(f"invalid HTTP header name: {d(raw_name)}") + raw_value = raw_value.strip(b" \t") + if not _value_re.fullmatch(raw_value): + raise ValueError(f"invalid HTTP header value: {d(raw_value)}") + + name = raw_name.decode("ascii") # guaranteed to be ASCII at this point + # Headers should be ASCII. Section 5.5 of RFC 9110 says: "Historically, + # HTTP allowed field content with text in the ISO-8859-1 charset." + # It's easy to reverse and cannot crash, making it a decent choice. + value = raw_value.decode("iso-8859-1") + + # Since we just validated raw_value, we don't need to revalidate it. + headers.set_insecure(name, value) + + else: + raise SecurityError("too many HTTP headers") + + return headers + + +def read_body( + status_code: int, + headers: Headers, + read_line: Callable[[int], Generator[None, None, bytes | bytearray]], + read_exact: Callable[[int], Generator[None, None, bytes | bytearray]], + read_to_eof: Callable[[int], Generator[None, None, bytes | bytearray]], +) -> Generator[None, None, bytes | bytearray]: + # https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.3 + + # Since websockets only does GET requests (no HEAD, no CONNECT), all + # responses except 1xx, 204, and 304 include a message body. + if 100 <= status_code < 200 or status_code == 204 or status_code == 304: + return b"" + + # MultipleValuesError is sufficiently unlikely that we don't attempt to + # handle it when accessing headers. Instead we document that its parent + # class, LookupError, may be raised. + # Conversions from str to int are protected by sys.set_int_max_str_digits.. + + elif (coding := headers.get("Transfer-Encoding")) is not None: + if coding != "chunked": + raise NotImplementedError(f"transfer coding {coding} isn't supported") + + body = b"" + while True: + chunk_size_line = yield from parse_line(read_line) + raw_chunk_size = chunk_size_line.split(b";", 1)[0] + # Set a lower limit than default_max_str_digits; 1 EB is plenty. + if len(raw_chunk_size) > 15: + str_chunk_size = raw_chunk_size.decode(errors="backslashreplace") + raise SecurityError(f"chunk too large: 0x{str_chunk_size} bytes") + chunk_size = int(raw_chunk_size, 16) + if chunk_size == 0: + break + if len(body) + chunk_size > MAX_BODY_SIZE: + raise SecurityError( + f"chunk too large: {chunk_size} bytes after {len(body)} bytes" + ) + body += yield from read_exact(chunk_size) + if (yield from read_exact(2)) != b"\r\n": + raise ValueError("chunk without CRLF") + # Read the trailer. + yield from parse_headers(read_line) + return body + + elif (raw_content_length := headers.get("Content-Length")) is not None: + # Set a lower limit than default_max_str_digits; 1 EiB is plenty. + if len(raw_content_length) > 18: + raise SecurityError(f"body too large: {raw_content_length} bytes") + content_length = int(raw_content_length) + if content_length > MAX_BODY_SIZE: + raise SecurityError(f"body too large: {content_length} bytes") + return (yield from read_exact(content_length)) + + else: + try: + return (yield from read_to_eof(MAX_BODY_SIZE)) + except RuntimeError: + raise SecurityError(f"body too large: over {MAX_BODY_SIZE} bytes") diff --git a/.venv/Lib/site-packages/websockets/imports.py b/.venv/Lib/site-packages/websockets/imports.py new file mode 100644 index 0000000000000000000000000000000000000000..b86166408438ee23208a62241c2da6fee7a45ec5 --- /dev/null +++ b/.venv/Lib/site-packages/websockets/imports.py @@ -0,0 +1,100 @@ +from __future__ import annotations + +import warnings +from collections.abc import Iterable +from typing import Any + + +__all__ = ["lazy_import"] + + +def import_name(name: str, source: str, namespace: dict[str, Any]) -> Any: + """ + Import ``name`` from ``source`` in ``namespace``. + + There are two use cases: + + - ``name`` is an object defined in ``source``; + - ``name`` is a submodule of ``source``. + + Neither :func:`__import__` nor :func:`~importlib.import_module` does + exactly this. :func:`__import__` is closer to the intended behavior. + + """ + level = 0 + while source[level] == ".": + level += 1 + assert level < len(source), "importing from parent isn't supported" + module = __import__(source[level:], namespace, None, [name], level) + return getattr(module, name) + + +def lazy_import( + namespace: dict[str, Any], + aliases: dict[str, str] | None = None, + deprecated_aliases: dict[str, str] | None = None, +) -> None: + """ + Provide lazy, module-level imports. + + Typical use:: + + __getattr__, __dir__ = lazy_import( + globals(), + aliases={ + "": "", + ... + }, + deprecated_aliases={ + ..., + } + ) + + This function defines ``__getattr__`` and ``__dir__`` per :pep:`562`. + + """ + if aliases is None: + aliases = {} + if deprecated_aliases is None: + deprecated_aliases = {} + + namespace_set = set(namespace) + aliases_set = set(aliases) + deprecated_aliases_set = set(deprecated_aliases) + + assert not namespace_set & aliases_set, "namespace conflict" + assert not namespace_set & deprecated_aliases_set, "namespace conflict" + assert not aliases_set & deprecated_aliases_set, "namespace conflict" + + package = namespace["__name__"] + + def __getattr__(name: str) -> Any: + assert aliases is not None # mypy cannot figure this out + try: + source = aliases[name] + except KeyError: + pass + else: + return import_name(name, source, namespace) + + assert deprecated_aliases is not None # mypy cannot figure this out + try: + source = deprecated_aliases[name] + except KeyError: + pass + else: + warnings.warn( + f"{package}.{name} is deprecated", + DeprecationWarning, + stacklevel=2, + ) + return import_name(name, source, namespace) + + raise AttributeError(f"module {package!r} has no attribute {name!r}") + + namespace["__getattr__"] = __getattr__ + + def __dir__() -> Iterable[str]: + return sorted(namespace_set | aliases_set | deprecated_aliases_set) + + namespace["__dir__"] = __dir__ diff --git a/.venv/Lib/site-packages/websockets/legacy/__init__.py b/.venv/Lib/site-packages/websockets/legacy/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..070ec2d04a0e48f86364c8ebf99bfd9f2124836b --- /dev/null +++ b/.venv/Lib/site-packages/websockets/legacy/__init__.py @@ -0,0 +1,11 @@ +from __future__ import annotations + +import warnings + + +warnings.warn( # deprecated in 14.0 - 2024-11-09 + "websockets.legacy is deprecated; " + "see https://websockets.readthedocs.io/en/stable/howto/upgrade.html " + "for upgrade instructions", + DeprecationWarning, +) diff --git a/.venv/Lib/site-packages/websockets/legacy/auth.py b/.venv/Lib/site-packages/websockets/legacy/auth.py new file mode 100644 index 0000000000000000000000000000000000000000..853f379bb3af6bb637c311bb23401d3a10331ea1 --- /dev/null +++ b/.venv/Lib/site-packages/websockets/legacy/auth.py @@ -0,0 +1,190 @@ +from __future__ import annotations + +import functools +import hmac +import http +from collections.abc import Awaitable, Iterable +from typing import Any, Callable, cast + +from ..datastructures import Headers +from ..exceptions import InvalidHeader +from ..headers import build_www_authenticate_basic, parse_authorization_basic +from .server import HTTPResponse, WebSocketServerProtocol + + +__all__ = ["BasicAuthWebSocketServerProtocol", "basic_auth_protocol_factory"] + +Credentials = tuple[str, str] + + +def is_credentials(value: Any) -> bool: + try: + username, password = value + except (TypeError, ValueError): + return False + else: + return isinstance(username, str) and isinstance(password, str) + + +class BasicAuthWebSocketServerProtocol(WebSocketServerProtocol): + """ + WebSocket server protocol that enforces HTTP Basic Auth. + + """ + + realm: str = "" + """ + Scope of protection. + + If provided, it should contain only ASCII characters because the + encoding of non-ASCII characters is undefined. + """ + + username: str | None = None + """Username of the authenticated user.""" + + def __init__( + self, + *args: Any, + realm: str | None = None, + check_credentials: Callable[[str, str], Awaitable[bool]] | None = None, + **kwargs: Any, + ) -> None: + if realm is not None: + self.realm = realm # shadow class attribute + self._check_credentials = check_credentials + super().__init__(*args, **kwargs) + + async def check_credentials(self, username: str, password: str) -> bool: + """ + Check whether credentials are authorized. + + This coroutine may be overridden in a subclass, for example to + authenticate against a database or an external service. + + Args: + username: HTTP Basic Auth username. + password: HTTP Basic Auth password. + + Returns: + :obj:`True` if the handshake should continue; + :obj:`False` if it should fail with an HTTP 401 error. + + """ + if self._check_credentials is not None: + return await self._check_credentials(username, password) + + return False + + async def process_request( + self, + path: str, + request_headers: Headers, + ) -> HTTPResponse | None: + """ + Check HTTP Basic Auth and return an HTTP 401 response if needed. + + """ + try: + authorization = request_headers["Authorization"] + except KeyError: + return ( + http.HTTPStatus.UNAUTHORIZED, + [("WWW-Authenticate", build_www_authenticate_basic(self.realm))], + b"Missing credentials\n", + ) + + try: + username, password = parse_authorization_basic(authorization) + except InvalidHeader: + return ( + http.HTTPStatus.UNAUTHORIZED, + [("WWW-Authenticate", build_www_authenticate_basic(self.realm))], + b"Unsupported credentials\n", + ) + + if not await self.check_credentials(username, password): + return ( + http.HTTPStatus.UNAUTHORIZED, + [("WWW-Authenticate", build_www_authenticate_basic(self.realm))], + b"Invalid credentials\n", + ) + + self.username = username + + return await super().process_request(path, request_headers) + + +def basic_auth_protocol_factory( + realm: str | None = None, + credentials: Credentials | Iterable[Credentials] | None = None, + check_credentials: Callable[[str, str], Awaitable[bool]] | None = None, + create_protocol: Callable[..., BasicAuthWebSocketServerProtocol] | None = None, +) -> Callable[..., BasicAuthWebSocketServerProtocol]: + """ + Protocol factory that enforces HTTP Basic Auth. + + :func:`basic_auth_protocol_factory` is designed to integrate with + :func:`~websockets.legacy.server.serve` like this:: + + serve( + ..., + create_protocol=basic_auth_protocol_factory( + realm="my dev server", + credentials=("hello", "iloveyou"), + ) + ) + + Args: + realm: Scope of protection. It should contain only ASCII characters + because the encoding of non-ASCII characters is undefined. + Refer to section 2.2 of :rfc:`7235` for details. + credentials: Hard coded authorized credentials. It can be a + ``(username, password)`` pair or a list of such pairs. + check_credentials: Coroutine that verifies credentials. + It receives ``username`` and ``password`` arguments + and returns a :class:`bool`. One of ``credentials`` or + ``check_credentials`` must be provided but not both. + create_protocol: Factory that creates the protocol. By default, this + is :class:`BasicAuthWebSocketServerProtocol`. It can be replaced + by a subclass. + Raises: + TypeError: If the ``credentials`` or ``check_credentials`` argument is + wrong. + + """ + if (credentials is None) == (check_credentials is None): + raise TypeError("provide either credentials or check_credentials") + + if credentials is not None: + if is_credentials(credentials): + credentials_list = [cast(Credentials, credentials)] + elif isinstance(credentials, Iterable): + credentials_list = list(cast(Iterable[Credentials], credentials)) + if not all(is_credentials(item) for item in credentials_list): + raise TypeError(f"invalid credentials argument: {credentials}") + else: + raise TypeError(f"invalid credentials argument: {credentials}") + + credentials_dict = dict(credentials_list) + + async def check_credentials(username: str, password: str) -> bool: + try: + expected_password = credentials_dict[username] + except KeyError: + return False + return hmac.compare_digest(expected_password, password) + + if create_protocol is None: + create_protocol = BasicAuthWebSocketServerProtocol + + # Help mypy and avoid this error: "type[BasicAuthWebSocketServerProtocol] | + # Callable[..., BasicAuthWebSocketServerProtocol]" not callable [misc] + create_protocol = cast( + Callable[..., BasicAuthWebSocketServerProtocol], create_protocol + ) + return functools.partial( + create_protocol, + realm=realm, + check_credentials=check_credentials, + ) diff --git a/.venv/Lib/site-packages/websockets/legacy/client.py b/.venv/Lib/site-packages/websockets/legacy/client.py new file mode 100644 index 0000000000000000000000000000000000000000..1ba2536354456d183144ac9a6d13923d5b2618c8 --- /dev/null +++ b/.venv/Lib/site-packages/websockets/legacy/client.py @@ -0,0 +1,714 @@ +from __future__ import annotations + +import asyncio +import functools +import logging +import os +import random +import traceback +import urllib.parse +import warnings +from collections.abc import AsyncIterator, Generator, Sequence +from types import TracebackType +from typing import Any, Callable, cast + +from ..asyncio.compatibility import asyncio_timeout +from ..datastructures import Headers, HeadersLike +from ..exceptions import ( + InvalidHeader, + InvalidHeaderValue, + InvalidMessage, + NegotiationError, + SecurityError, +) +from ..extensions import ClientExtensionFactory, Extension +from ..extensions.permessage_deflate import enable_client_permessage_deflate +from ..headers import ( + build_authorization_basic, + build_extension, + build_host, + build_subprotocol, + parse_extension, + parse_subprotocol, + validate_subprotocols, +) +from ..http11 import USER_AGENT +from ..typing import ExtensionHeader, LoggerLike, Origin, Subprotocol +from ..uri import WebSocketURI, parse_uri +from .exceptions import InvalidStatusCode, RedirectHandshake +from .handshake import build_request, check_response +from .http import read_response +from .protocol import WebSocketCommonProtocol + + +__all__ = ["connect", "unix_connect", "WebSocketClientProtocol"] + + +class WebSocketClientProtocol(WebSocketCommonProtocol): + """ + WebSocket client connection. + + :class:`WebSocketClientProtocol` provides :meth:`recv` and :meth:`send` + coroutines for receiving and sending messages. + + It supports asynchronous iteration to receive messages:: + + async for message in websocket: + await process(message) + + The iterator exits normally when the connection is closed with close code + 1000 (OK) or 1001 (going away) or without a close code. It raises + a :exc:`~websockets.exceptions.ConnectionClosedError` when the connection + is closed with any other code. + + See :func:`connect` for the documentation of ``logger``, ``origin``, + ``extensions``, ``subprotocols``, ``extra_headers``, and + ``user_agent_header``. + + See :class:`~websockets.legacy.protocol.WebSocketCommonProtocol` for the + documentation of ``ping_interval``, ``ping_timeout``, ``close_timeout``, + ``max_size``, ``max_queue``, ``read_limit``, and ``write_limit``. + + """ + + is_client = True + side = "client" + + def __init__( + self, + *, + logger: LoggerLike | None = None, + origin: Origin | None = None, + extensions: Sequence[ClientExtensionFactory] | None = None, + subprotocols: Sequence[Subprotocol] | None = None, + extra_headers: HeadersLike | None = None, + user_agent_header: str | None = USER_AGENT, + **kwargs: Any, + ) -> None: + if logger is None: + logger = logging.getLogger("websockets.client") + super().__init__(logger=logger, **kwargs) + self.origin = origin + self.available_extensions = extensions + self.available_subprotocols = subprotocols + self.extra_headers = extra_headers + self.user_agent_header = user_agent_header + + def write_http_request(self, path: str, headers: Headers) -> None: + """ + Write request line and headers to the HTTP request. + + """ + self.path = path + self.request_headers = headers + + if self.debug: + self.logger.debug("> GET %s HTTP/1.1", path) + for key, value in headers.raw_items(): + self.logger.debug("> %s: %s", key, value) + + # Since the path and headers only contain ASCII characters, + # we can keep this simple. + request = f"GET {path} HTTP/1.1\r\n" + request += str(headers) + + self.transport.write(request.encode()) + + async def read_http_response(self) -> tuple[int, Headers]: + """ + Read status line and headers from the HTTP response. + + If the response contains a body, it may be read from ``self.reader`` + after this coroutine returns. + + Raises: + InvalidMessage: If the HTTP message is malformed or isn't an + HTTP/1.1 GET response. + + """ + try: + status_code, reason, headers = await read_response(self.reader) + except Exception as exc: + raise InvalidMessage("did not receive a valid HTTP response") from exc + + if self.debug: + self.logger.debug("< HTTP/1.1 %d %s", status_code, reason) + for key, value in headers.raw_items(): + self.logger.debug("< %s: %s", key, value) + + self.response_headers = headers + + return status_code, self.response_headers + + @staticmethod + def process_extensions( + headers: Headers, + available_extensions: Sequence[ClientExtensionFactory] | None, + ) -> list[Extension]: + """ + Handle the Sec-WebSocket-Extensions HTTP response header. + + Check that each extension is supported, as well as its parameters. + + Return the list of accepted extensions. + + Raise :exc:`~websockets.exceptions.InvalidHandshake` to abort the + connection. + + :rfc:`6455` leaves the rules up to the specification of each + :extension. + + To provide this level of flexibility, for each extension accepted by + the server, we check for a match with each extension available in the + client configuration. If no match is found, an exception is raised. + + If several variants of the same extension are accepted by the server, + it may be configured several times, which won't make sense in general. + Extensions must implement their own requirements. For this purpose, + the list of previously accepted extensions is provided. + + Other requirements, for example related to mandatory extensions or the + order of extensions, may be implemented by overriding this method. + + """ + accepted_extensions: list[Extension] = [] + + header_values = headers.get_all("Sec-WebSocket-Extensions") + + if header_values: + if available_extensions is None: + raise NegotiationError("no extensions supported") + + parsed_header_values: list[ExtensionHeader] = sum( + [parse_extension(header_value) for header_value in header_values], [] + ) + + for name, response_params in parsed_header_values: + for extension_factory in available_extensions: + # Skip non-matching extensions based on their name. + if extension_factory.name != name: + continue + + # Skip non-matching extensions based on their params. + try: + extension = extension_factory.process_response_params( + response_params, accepted_extensions + ) + except NegotiationError: + continue + + # Add matching extension to the final list. + accepted_extensions.append(extension) + + # Break out of the loop once we have a match. + break + + # If we didn't break from the loop, no extension in our list + # matched what the server sent. Fail the connection. + else: + raise NegotiationError( + f"Unsupported extension: " + f"name = {name}, params = {response_params}" + ) + + return accepted_extensions + + @staticmethod + def process_subprotocol( + headers: Headers, available_subprotocols: Sequence[Subprotocol] | None + ) -> Subprotocol | None: + """ + Handle the Sec-WebSocket-Protocol HTTP response header. + + Check that it contains exactly one supported subprotocol. + + Return the selected subprotocol. + + """ + subprotocol: Subprotocol | None = None + + header_values = headers.get_all("Sec-WebSocket-Protocol") + + if header_values: + if available_subprotocols is None: + raise NegotiationError("no subprotocols supported") + + parsed_header_values: Sequence[Subprotocol] = sum( + [parse_subprotocol(header_value) for header_value in header_values], [] + ) + + if len(parsed_header_values) > 1: + raise InvalidHeaderValue( + "Sec-WebSocket-Protocol", + f"multiple values: {', '.join(parsed_header_values)}", + ) + + subprotocol = parsed_header_values[0] + + if subprotocol not in available_subprotocols: + raise NegotiationError(f"unsupported subprotocol: {subprotocol}") + + return subprotocol + + async def handshake( + self, + wsuri: WebSocketURI, + origin: Origin | None = None, + available_extensions: Sequence[ClientExtensionFactory] | None = None, + available_subprotocols: Sequence[Subprotocol] | None = None, + extra_headers: HeadersLike | None = None, + ) -> None: + """ + Perform the client side of the opening handshake. + + Args: + wsuri: URI of the WebSocket server. + origin: Value of the ``Origin`` header. + extensions: List of supported extensions, in order in which they + should be negotiated and run. + subprotocols: List of supported subprotocols, in order of decreasing + preference. + extra_headers: Arbitrary HTTP headers to add to the handshake request. + + Raises: + InvalidHandshake: If the handshake fails. + + """ + request_headers = Headers() + + request_headers["Host"] = build_host(wsuri.host, wsuri.port, wsuri.secure) + + if wsuri.user_info: + request_headers["Authorization"] = build_authorization_basic( + *wsuri.user_info + ) + + if origin is not None: + request_headers["Origin"] = origin + + key = build_request(request_headers) + + if available_extensions is not None: + extensions_header = build_extension( + [ + (extension_factory.name, extension_factory.get_request_params()) + for extension_factory in available_extensions + ] + ) + request_headers["Sec-WebSocket-Extensions"] = extensions_header + + if available_subprotocols is not None: + protocol_header = build_subprotocol(available_subprotocols) + request_headers["Sec-WebSocket-Protocol"] = protocol_header + + if self.extra_headers is not None: + request_headers.update(self.extra_headers) + + if self.user_agent_header: + request_headers.setdefault("User-Agent", self.user_agent_header) + + self.write_http_request(wsuri.resource_name, request_headers) + + status_code, response_headers = await self.read_http_response() + if status_code in (301, 302, 303, 307, 308): + if "Location" not in response_headers: + raise InvalidHeader("Location") + raise RedirectHandshake(response_headers["Location"]) + elif status_code != 101: + raise InvalidStatusCode(status_code, response_headers) + + check_response(response_headers, key) + + self.extensions = self.process_extensions( + response_headers, available_extensions + ) + + self.subprotocol = self.process_subprotocol( + response_headers, available_subprotocols + ) + + self.connection_open() + + +class Connect: + """ + Connect to the WebSocket server at ``uri``. + + Awaiting :func:`connect` yields a :class:`WebSocketClientProtocol` which + can then be used to send and receive messages. + + :func:`connect` can be used as a asynchronous context manager:: + + async with connect(...) as websocket: + ... + + The connection is closed automatically when exiting the context. + + :func:`connect` can be used as an infinite asynchronous iterator to + reconnect automatically on errors:: + + async for websocket in connect(...): + try: + ... + except websockets.exceptions.ConnectionClosed: + continue + + The connection is closed automatically after each iteration of the loop. + + If an error occurs while establishing the connection, :func:`connect` + retries with exponential backoff. The backoff delay starts at three + seconds and increases up to one minute. + + If an error occurs in the body of the loop, you can handle the exception + and :func:`connect` will reconnect with the next iteration; or you can + let the exception bubble up and break out of the loop. This lets you + decide which errors trigger a reconnection and which errors are fatal. + + Args: + uri: URI of the WebSocket server. + create_protocol: Factory for the :class:`asyncio.Protocol` managing + the connection. It defaults to :class:`WebSocketClientProtocol`. + Set it to a wrapper or a subclass to customize connection handling. + logger: Logger for this client. + It defaults to ``logging.getLogger("websockets.client")``. + See the :doc:`logging guide <../../topics/logging>` for details. + compression: The "permessage-deflate" extension is enabled by default. + Set ``compression`` to :obj:`None` to disable it. See the + :doc:`compression guide <../../topics/compression>` for details. + origin: Value of the ``Origin`` header, for servers that require it. + extensions: List of supported extensions, in order in which they + should be negotiated and run. + subprotocols: List of supported subprotocols, in order of decreasing + preference. + extra_headers: Arbitrary HTTP headers to add to the handshake request. + user_agent_header: Value of the ``User-Agent`` request header. + It defaults to ``"Python/x.y.z websockets/X.Y"``. + Setting it to :obj:`None` removes the header. + open_timeout: Timeout for opening the connection in seconds. + :obj:`None` disables the timeout. + + See :class:`~websockets.legacy.protocol.WebSocketCommonProtocol` for the + documentation of ``ping_interval``, ``ping_timeout``, ``close_timeout``, + ``max_size``, ``max_queue``, ``read_limit``, and ``write_limit``. + + Any other keyword arguments are passed the event loop's + :meth:`~asyncio.loop.create_connection` method. + + For example: + + * You can set ``ssl`` to a :class:`~ssl.SSLContext` to enforce TLS + settings. When connecting to a ``wss://`` URI, if ``ssl`` isn't + provided, a TLS context is created + with :func:`~ssl.create_default_context`. + + * You can set ``host`` and ``port`` to connect to a different host and + port from those found in ``uri``. This only changes the destination of + the TCP connection. The host name from ``uri`` is still used in the TLS + handshake for secure connections and in the ``Host`` header. + + Raises: + InvalidURI: If ``uri`` isn't a valid WebSocket URI. + OSError: If the TCP connection fails. + InvalidHandshake: If the opening handshake fails. + ~asyncio.TimeoutError: If the opening handshake times out. + + """ + + MAX_REDIRECTS_ALLOWED = int(os.environ.get("WEBSOCKETS_MAX_REDIRECTS", "10")) + + def __init__( + self, + uri: str, + *, + create_protocol: Callable[..., WebSocketClientProtocol] | None = None, + logger: LoggerLike | None = None, + compression: str | None = "deflate", + origin: Origin | None = None, + extensions: Sequence[ClientExtensionFactory] | None = None, + subprotocols: Sequence[Subprotocol] | None = None, + extra_headers: HeadersLike | None = None, + user_agent_header: str | None = USER_AGENT, + open_timeout: float | None = 10, + ping_interval: float | None = 20, + ping_timeout: float | None = 20, + close_timeout: float | None = None, + max_size: int | None = 2**20, + max_queue: int | None = 2**5, + read_limit: int = 2**16, + write_limit: int = 2**16, + **kwargs: Any, + ) -> None: + # Backwards compatibility: close_timeout used to be called timeout. + timeout: float | None = kwargs.pop("timeout", None) + if timeout is None: + timeout = 10 + else: + warnings.warn("rename timeout to close_timeout", DeprecationWarning) + # If both are specified, timeout is ignored. + if close_timeout is None: + close_timeout = timeout + + # Backwards compatibility: create_protocol used to be called klass. + klass: type[WebSocketClientProtocol] | None = kwargs.pop("klass", None) + if klass is None: + klass = WebSocketClientProtocol + else: + warnings.warn("rename klass to create_protocol", DeprecationWarning) + # If both are specified, klass is ignored. + if create_protocol is None: + create_protocol = klass + + # Backwards compatibility: recv() used to return None on closed connections + legacy_recv: bool = kwargs.pop("legacy_recv", False) + + # Backwards compatibility: the loop parameter used to be supported. + _loop: asyncio.AbstractEventLoop | None = kwargs.pop("loop", None) + if _loop is None: + loop = asyncio.get_event_loop() + else: + loop = _loop + warnings.warn("remove loop argument", DeprecationWarning) + + wsuri = parse_uri(uri) + if wsuri.secure: + kwargs.setdefault("ssl", True) + elif kwargs.get("ssl") is not None: + raise ValueError( + "connect() received a ssl argument for a ws:// URI, " + "use a wss:// URI to enable TLS" + ) + + if compression == "deflate": + extensions = enable_client_permessage_deflate(extensions) + elif compression is not None: + raise ValueError(f"unsupported compression: {compression}") + + if subprotocols is not None: + validate_subprotocols(subprotocols) + + # Help mypy and avoid this error: "type[WebSocketClientProtocol] | + # Callable[..., WebSocketClientProtocol]" not callable [misc] + create_protocol = cast(Callable[..., WebSocketClientProtocol], create_protocol) + factory = functools.partial( + create_protocol, + logger=logger, + origin=origin, + extensions=extensions, + subprotocols=subprotocols, + extra_headers=extra_headers, + user_agent_header=user_agent_header, + ping_interval=ping_interval, + ping_timeout=ping_timeout, + close_timeout=close_timeout, + max_size=max_size, + max_queue=max_queue, + read_limit=read_limit, + write_limit=write_limit, + host=wsuri.host, + port=wsuri.port, + secure=wsuri.secure, + legacy_recv=legacy_recv, + loop=_loop, + ) + + if kwargs.pop("unix", False): + path: str | None = kwargs.pop("path", None) + create_connection = functools.partial( + loop.create_unix_connection, factory, path, **kwargs + ) + else: + host: str | None + port: int | None + if kwargs.get("sock") is None: + host, port = wsuri.host, wsuri.port + else: + # If sock is given, host and port shouldn't be specified. + host, port = None, None + if kwargs.get("ssl"): + kwargs.setdefault("server_hostname", wsuri.host) + # If host and port are given, override values from the URI. + host = kwargs.pop("host", host) + port = kwargs.pop("port", port) + create_connection = functools.partial( + loop.create_connection, factory, host, port, **kwargs + ) + + self.open_timeout = open_timeout + if logger is None: + logger = logging.getLogger("websockets.client") + self.logger = logger + + # This is a coroutine function. + self._create_connection = create_connection + self._uri = uri + self._wsuri = wsuri + + def handle_redirect(self, uri: str) -> None: + # Update the state of this instance to connect to a new URI. + old_uri = self._uri + old_wsuri = self._wsuri + new_uri = urllib.parse.urljoin(old_uri, uri) + new_wsuri = parse_uri(new_uri) + + # Forbid TLS downgrade. + if old_wsuri.secure and not new_wsuri.secure: + raise SecurityError("redirect from WSS to WS") + + same_origin = ( + old_wsuri.secure == new_wsuri.secure + and old_wsuri.host == new_wsuri.host + and old_wsuri.port == new_wsuri.port + ) + + # Rewrite secure, host, and port for cross-origin redirects. + # This preserves connection overrides with the host and port + # arguments if the redirect points to the same host and port. + if not same_origin: + factory = self._create_connection.args[0] + # Support TLS upgrade. + if not old_wsuri.secure and new_wsuri.secure: + factory.keywords["secure"] = True + self._create_connection.keywords.setdefault("ssl", True) + # Strip credentials to avoid leaking them to a different origin. + extra_headers = factory.keywords.get("extra_headers") + if extra_headers is not None: # pragma: no cover + factory.keywords["extra_headers"] = Headers( + ( + (key, value) + for key, value in Headers(extra_headers).raw_items() + if key.lower() + not in ["authorization", "cookie", "proxy-authorization"] + ) + ) + # Replace secure, host, and port arguments of the protocol factory. + factory = functools.partial( + factory.func, + *factory.args, + **dict(factory.keywords, host=new_wsuri.host, port=new_wsuri.port), + ) + # Replace secure, host, and port arguments of create_connection. + self._create_connection = functools.partial( + self._create_connection.func, + *(factory, new_wsuri.host, new_wsuri.port), + **self._create_connection.keywords, + ) + + # Set the new WebSocket URI. This suffices for same-origin redirects. + self._uri = new_uri + self._wsuri = new_wsuri + + # async for ... in connect(...): + + BACKOFF_INITIAL = float(os.environ.get("WEBSOCKETS_BACKOFF_INITIAL_DELAY", "5")) + BACKOFF_MIN = float(os.environ.get("WEBSOCKETS_BACKOFF_MIN_DELAY", "3.1")) + BACKOFF_MAX = float(os.environ.get("WEBSOCKETS_BACKOFF_MAX_DELAY", "90.0")) + BACKOFF_FACTOR = float(os.environ.get("WEBSOCKETS_BACKOFF_FACTOR", "1.618")) + + async def __aiter__(self) -> AsyncIterator[WebSocketClientProtocol]: + backoff_delay = self.BACKOFF_MIN / self.BACKOFF_FACTOR + while True: + try: + async with self as protocol: + yield protocol + except Exception as exc: + # Add a random initial delay between 0 and 5 seconds. + # See 7.2.3. Recovering from Abnormal Closure in RFC 6455. + if backoff_delay == self.BACKOFF_MIN: + initial_delay = random.random() * self.BACKOFF_INITIAL + self.logger.info( + "connect failed; reconnecting in %.1f seconds: %s", + initial_delay, + traceback.format_exception_only(exc)[0].strip(), + ) + await asyncio.sleep(initial_delay) + else: + self.logger.info( + "connect failed again; retrying in %d seconds: %s", + int(backoff_delay), + traceback.format_exception_only(exc)[0].strip(), + ) + await asyncio.sleep(int(backoff_delay)) + # Increase delay with truncated exponential backoff. + backoff_delay = backoff_delay * self.BACKOFF_FACTOR + backoff_delay = min(backoff_delay, self.BACKOFF_MAX) + continue + else: + # Connection succeeded - reset backoff delay + backoff_delay = self.BACKOFF_MIN + + # async with connect(...) as ...: + + async def __aenter__(self) -> WebSocketClientProtocol: + return await self + + async def __aexit__( + self, + exc_type: type[BaseException] | None, + exc_value: BaseException | None, + traceback: TracebackType | None, + ) -> None: + await self.protocol.close() + + # ... = await connect(...) + + def __await__(self) -> Generator[Any, None, WebSocketClientProtocol]: + # Create a suitable iterator by calling __await__ on a coroutine. + return self.__await_impl__().__await__() + + async def __await_impl__(self) -> WebSocketClientProtocol: + async with asyncio_timeout(self.open_timeout): + for _redirects in range(self.MAX_REDIRECTS_ALLOWED): + _transport, protocol = await self._create_connection() + try: + await protocol.handshake( + self._wsuri, + origin=protocol.origin, + available_extensions=protocol.available_extensions, + available_subprotocols=protocol.available_subprotocols, + extra_headers=protocol.extra_headers, + ) + except RedirectHandshake as exc: + protocol.fail_connection() + await protocol.wait_closed() + self.handle_redirect(exc.uri) + # Avoid leaking a connected socket when the handshake fails. + except (Exception, asyncio.CancelledError): + protocol.fail_connection() + await protocol.wait_closed() + raise + else: + self.protocol = protocol + return protocol + else: + raise SecurityError("too many redirects") + + # ... = yield from connect(...) - remove when dropping Python < 3.11 + + __iter__ = __await__ + + +connect = Connect + + +def unix_connect( + path: str | None = None, + uri: str = "ws://localhost/", + **kwargs: Any, +) -> Connect: + """ + Similar to :func:`connect`, but for connecting to a Unix socket. + + This function builds upon the event loop's + :meth:`~asyncio.loop.create_unix_connection` method. + + It is only available on Unix. + + It's mainly useful for debugging servers listening on Unix sockets. + + Args: + path: File system path to the Unix socket. + uri: URI of the WebSocket server; the host is used in the TLS + handshake for secure connections and in the ``Host`` header. + + """ + return connect(uri=uri, path=path, unix=True, **kwargs) diff --git a/.venv/Lib/site-packages/websockets/legacy/exceptions.py b/.venv/Lib/site-packages/websockets/legacy/exceptions.py new file mode 100644 index 0000000000000000000000000000000000000000..03d7ac6d31bd025afb1e8ae67132ab691915e154 --- /dev/null +++ b/.venv/Lib/site-packages/websockets/legacy/exceptions.py @@ -0,0 +1,71 @@ +import http + +from .. import datastructures +from ..exceptions import ( + InvalidHandshake, + # InvalidMessage was incorrectly moved here in versions 14.0 and 14.1. + InvalidMessage, # noqa: F401 + ProtocolError as WebSocketProtocolError, # noqa: F401 +) +from ..typing import StatusLike + + +class InvalidStatusCode(InvalidHandshake): + """ + Raised when a handshake response status code is invalid. + + """ + + def __init__(self, status_code: int, headers: datastructures.Headers) -> None: + self.status_code = status_code + self.headers = headers + + def __str__(self) -> str: + return f"server rejected WebSocket connection: HTTP {self.status_code}" + + +class AbortHandshake(InvalidHandshake): + """ + Raised to abort the handshake on purpose and return an HTTP response. + + This exception is an implementation detail. + + The public API is + :meth:`~websockets.legacy.server.WebSocketServerProtocol.process_request`. + + Attributes: + status (~http.HTTPStatus): HTTP status code. + headers (Headers): HTTP response headers. + body (bytes): HTTP response body. + """ + + def __init__( + self, + status: StatusLike, + headers: datastructures.HeadersLike, + body: bytes = b"", + ) -> None: + # If a user passes an int instead of an HTTPStatus, fix it automatically. + self.status = http.HTTPStatus(status) + self.headers = datastructures.Headers(headers) + self.body = body + + def __str__(self) -> str: + return ( + f"HTTP {self.status:d}, {len(self.headers)} headers, {len(self.body)} bytes" + ) + + +class RedirectHandshake(InvalidHandshake): + """ + Raised when a handshake gets redirected. + + This exception is an implementation detail. + + """ + + def __init__(self, uri: str) -> None: + self.uri = uri + + def __str__(self) -> str: + return f"redirect to {self.uri}" diff --git a/.venv/Lib/site-packages/websockets/legacy/framing.py b/.venv/Lib/site-packages/websockets/legacy/framing.py new file mode 100644 index 0000000000000000000000000000000000000000..e63e7a28cbc5886929ad444d65c13efc50f5af0b --- /dev/null +++ b/.venv/Lib/site-packages/websockets/legacy/framing.py @@ -0,0 +1,224 @@ +from __future__ import annotations + +import struct +from collections.abc import Awaitable, Sequence +from typing import Any, Callable, NamedTuple + +from .. import extensions, frames +from ..exceptions import PayloadTooBig, ProtocolError +from ..typing import BytesLike, DataLike + + +try: + from ..speedups import apply_mask +except ImportError: + from ..utils import apply_mask + + +class Frame(NamedTuple): + fin: bool + opcode: frames.Opcode + data: BytesLike + rsv1: bool = False + rsv2: bool = False + rsv3: bool = False + + @property + def new_frame(self) -> frames.Frame: + return frames.Frame( + self.opcode, + self.data, + self.fin, + self.rsv1, + self.rsv2, + self.rsv3, + ) + + def __str__(self) -> str: + return str(self.new_frame) + + def check(self) -> None: + return self.new_frame.check() + + @classmethod + async def read( + cls, + reader: Callable[[int], Awaitable[bytes]], + *, + mask: bool, + max_size: int | None = None, + extensions: Sequence[extensions.Extension] | None = None, + ) -> Frame: + """ + Read a WebSocket frame. + + Args: + reader: Coroutine that reads exactly the requested number of + bytes, unless the end of file is reached. + mask: Whether the frame should be masked i.e. whether the read + happens on the server side. + max_size: Maximum payload size in bytes. + extensions: List of extensions, applied in reverse order. + + Raises: + PayloadTooBig: If the frame exceeds ``max_size``. + ProtocolError: If the frame contains incorrect values. + + """ + + # Read the header. + data = await reader(2) + head1, head2 = struct.unpack("!BB", data) + + # While not Pythonic, this is marginally faster than calling bool(). + fin = True if head1 & 0b10000000 else False + rsv1 = True if head1 & 0b01000000 else False + rsv2 = True if head1 & 0b00100000 else False + rsv3 = True if head1 & 0b00010000 else False + + try: + opcode = frames.Opcode(head1 & 0b00001111) + except ValueError as exc: + raise ProtocolError("invalid opcode") from exc + + if (True if head2 & 0b10000000 else False) != mask: + raise ProtocolError("incorrect masking") + + length = head2 & 0b01111111 + if length == 126: + data = await reader(2) + (length,) = struct.unpack("!H", data) + elif length == 127: + data = await reader(8) + (length,) = struct.unpack("!Q", data) + if max_size is not None and length > max_size: + raise PayloadTooBig(length, max_size) + if mask: + mask_bits = await reader(4) + + # Read the data. + data = await reader(length) + if mask: + data = apply_mask(data, mask_bits) + + new_frame = frames.Frame(opcode, data, fin, rsv1, rsv2, rsv3) + + if extensions is None: + extensions = [] + for extension in reversed(extensions): + new_frame = extension.decode(new_frame, max_size=max_size) + + new_frame.check() + + return cls( + new_frame.fin, + new_frame.opcode, + new_frame.data, + new_frame.rsv1, + new_frame.rsv2, + new_frame.rsv3, + ) + + def write( + self, + write: Callable[[bytes], Any], + *, + mask: bool, + extensions: Sequence[extensions.Extension] | None = None, + ) -> None: + """ + Write a WebSocket frame. + + Args: + frame: Frame to write. + write: Function that writes bytes. + mask: Whether the frame should be masked i.e. whether the write + happens on the client side. + extensions: List of extensions, applied in order. + + Raises: + ProtocolError: If the frame contains incorrect values. + + """ + # The frame is written in a single call to write in order to prevent + # TCP fragmentation. See #68 for details. This also makes it safe to + # send frames concurrently from multiple coroutines. + write(self.new_frame.serialize(mask=mask, extensions=extensions)) + + +def prepare_data(data: DataLike) -> tuple[int, BytesLike]: + """ + Convert a string or byte-like object to an opcode and a bytes-like object. + + This function is designed for data frames. + + If ``data`` is a :class:`str`, return ``OP_TEXT`` and a :class:`bytes` + object encoding ``data`` in UTF-8. + + If ``data`` is a bytes-like object, return ``OP_BINARY`` and a bytes-like + object. + + Raises: + TypeError: If ``data`` doesn't have a supported type. + + """ + if isinstance(data, str): + return frames.Opcode.TEXT, data.encode() + elif isinstance(data, BytesLike): + return frames.Opcode.BINARY, data + else: + raise TypeError("data must be str or bytes-like") + + +def prepare_ctrl(data: DataLike) -> bytes: + """ + Convert a string or byte-like object to bytes. + + This function is designed for ping and pong frames. + + If ``data`` is a :class:`str`, return a :class:`bytes` object encoding + ``data`` in UTF-8. + + If ``data`` is a bytes-like object, return a :class:`bytes` object. + + Raises: + TypeError: If ``data`` doesn't have a supported type. + + """ + if isinstance(data, str): + return data.encode() + elif isinstance(data, BytesLike): + return bytes(data) + else: + raise TypeError("data must be str or bytes-like") + + +# Backwards compatibility with previously documented public APIs +encode_data = prepare_ctrl + +# Backwards compatibility with previously documented public APIs +from ..frames import Close # noqa: E402 F401, I001 + + +def parse_close(data: bytes) -> tuple[int, str]: + """ + Parse the payload from a close frame. + + Returns: + Close code and reason. + + Raises: + ProtocolError: If data is ill-formed. + UnicodeDecodeError: If the reason isn't valid UTF-8. + + """ + close = Close.parse(data) + return close.code, close.reason + + +def serialize_close(code: int, reason: str) -> bytes: + """ + Serialize the payload for a close frame. + + """ + return Close(code, reason).serialize() diff --git a/.venv/Lib/site-packages/websockets/legacy/handshake.py b/.venv/Lib/site-packages/websockets/legacy/handshake.py new file mode 100644 index 0000000000000000000000000000000000000000..312db7a458591c75c1081da99bdd5168ac2bbba5 --- /dev/null +++ b/.venv/Lib/site-packages/websockets/legacy/handshake.py @@ -0,0 +1,158 @@ +from __future__ import annotations + +import base64 +import binascii + +from ..datastructures import Headers, MultipleValuesError +from ..exceptions import InvalidHeader, InvalidHeaderValue, InvalidUpgrade +from ..headers import parse_connection, parse_upgrade +from ..typing import ConnectionOption, UpgradeProtocol +from ..utils import accept_key as accept, generate_key + + +__all__ = ["build_request", "check_request", "build_response", "check_response"] + + +def build_request(headers: Headers) -> str: + """ + Build a handshake request to send to the server. + + Update request headers passed in argument. + + Args: + headers: Handshake request headers. + + Returns: + ``key`` that must be passed to :func:`check_response`. + + """ + key = generate_key() + headers["Upgrade"] = "websocket" + headers["Connection"] = "Upgrade" + headers["Sec-WebSocket-Key"] = key + headers["Sec-WebSocket-Version"] = "13" + return key + + +def check_request(headers: Headers) -> str: + """ + Check a handshake request received from the client. + + This function doesn't verify that the request is an HTTP/1.1 or higher GET + request and doesn't perform ``Host`` and ``Origin`` checks. These controls + are usually performed earlier in the HTTP request handling code. They're + the responsibility of the caller. + + Args: + headers: Handshake request headers. + + Returns: + ``key`` that must be passed to :func:`build_response`. + + Raises: + InvalidHandshake: If the handshake request is invalid. + Then, the server must return a 400 Bad Request error. + + """ + connection: list[ConnectionOption] = sum( + [parse_connection(value) for value in headers.get_all("Connection")], [] + ) + + if not any(value.lower() == "upgrade" for value in connection): + raise InvalidUpgrade("Connection", ", ".join(connection)) + + upgrade: list[UpgradeProtocol] = sum( + [parse_upgrade(value) for value in headers.get_all("Upgrade")], [] + ) + + # For compatibility with non-strict implementations, ignore case when + # checking the Upgrade header. The RFC always uses "websocket", except + # in section 11.2. (IANA registration) where it uses "WebSocket". + if not (len(upgrade) == 1 and upgrade[0].lower() == "websocket"): + raise InvalidUpgrade("Upgrade", ", ".join(upgrade)) + + try: + s_w_key = headers["Sec-WebSocket-Key"] + except KeyError as exc: + raise InvalidHeader("Sec-WebSocket-Key") from exc + except MultipleValuesError as exc: + raise InvalidHeader("Sec-WebSocket-Key", "multiple values") from exc + + try: + raw_key = base64.b64decode(s_w_key.encode(), validate=True) + except binascii.Error as exc: + raise InvalidHeaderValue("Sec-WebSocket-Key", s_w_key) from exc + if len(raw_key) != 16: + raise InvalidHeaderValue("Sec-WebSocket-Key", s_w_key) + + try: + s_w_version = headers["Sec-WebSocket-Version"] + except KeyError as exc: + raise InvalidHeader("Sec-WebSocket-Version") from exc + except MultipleValuesError as exc: + raise InvalidHeader("Sec-WebSocket-Version", "multiple values") from exc + + if s_w_version != "13": + raise InvalidHeaderValue("Sec-WebSocket-Version", s_w_version) + + return s_w_key + + +def build_response(headers: Headers, key: str) -> None: + """ + Build a handshake response to send to the client. + + Update response headers passed in argument. + + Args: + headers: Handshake response headers. + key: Returned by :func:`check_request`. + + """ + headers["Upgrade"] = "websocket" + headers["Connection"] = "Upgrade" + headers["Sec-WebSocket-Accept"] = accept(key) + + +def check_response(headers: Headers, key: str) -> None: + """ + Check a handshake response received from the server. + + This function doesn't verify that the response is an HTTP/1.1 or higher + response with a 101 status code. These controls are the responsibility of + the caller. + + Args: + headers: Handshake response headers. + key: Returned by :func:`build_request`. + + Raises: + InvalidHandshake: If the handshake response is invalid. + + """ + connection: list[ConnectionOption] = sum( + [parse_connection(value) for value in headers.get_all("Connection")], [] + ) + + if not any(value.lower() == "upgrade" for value in connection): + raise InvalidUpgrade("Connection", " ".join(connection)) + + upgrade: list[UpgradeProtocol] = sum( + [parse_upgrade(value) for value in headers.get_all("Upgrade")], [] + ) + + # For compatibility with non-strict implementations, ignore case when + # checking the Upgrade header. The RFC always uses "websocket", except + # in section 11.2. (IANA registration) where it uses "WebSocket". + if not (len(upgrade) == 1 and upgrade[0].lower() == "websocket"): + raise InvalidUpgrade("Upgrade", ", ".join(upgrade)) + + try: + s_w_accept = headers["Sec-WebSocket-Accept"] + except KeyError as exc: + raise InvalidHeader("Sec-WebSocket-Accept") from exc + except MultipleValuesError as exc: + raise InvalidHeader("Sec-WebSocket-Accept", "multiple values") from exc + + if s_w_accept != accept(key): + raise InvalidHeaderValue("Sec-WebSocket-Accept", s_w_accept) diff --git a/.venv/Lib/site-packages/websockets/legacy/http.py b/.venv/Lib/site-packages/websockets/legacy/http.py new file mode 100644 index 0000000000000000000000000000000000000000..cca5f14eb85f5b69079861724be71a025a863c72 --- /dev/null +++ b/.venv/Lib/site-packages/websockets/legacy/http.py @@ -0,0 +1,201 @@ +from __future__ import annotations + +import asyncio +import os +import re + +from ..datastructures import Headers +from ..exceptions import SecurityError + + +__all__ = ["read_request", "read_response"] + +MAX_NUM_HEADERS = int(os.environ.get("WEBSOCKETS_MAX_NUM_HEADERS", "128")) +MAX_LINE_LENGTH = int(os.environ.get("WEBSOCKETS_MAX_LINE_LENGTH", "8192")) + + +def d(value: bytes) -> str: + """ + Decode a bytestring for interpolating into an error message. + + """ + return value.decode(errors="backslashreplace") + + +# See https://datatracker.ietf.org/doc/html/rfc7230#appendix-B. + +# Regex for validating header names. + +_token_re = re.compile(rb"[-!#$%&\'*+.^_`|~0-9a-zA-Z]+") + +# Regex for validating header values. + +# We don't attempt to support obsolete line folding. + +# Include HTAB (\x09), SP (\x20), VCHAR (\x21-\x7e), obs-text (\x80-\xff). + +# The ABNF is complicated because it attempts to express that optional +# whitespace is ignored. We strip whitespace and don't revalidate that. + +# See also https://www.rfc-editor.org/errata_search.php?rfc=7230&eid=4189 + +_value_re = re.compile(rb"[\x09\x20-\x7e\x80-\xff]*") + + +async def read_request(stream: asyncio.StreamReader) -> tuple[str, Headers]: + """ + Read an HTTP/1.1 GET request and return ``(path, headers)``. + + ``path`` isn't URL-decoded or validated in any way. + + ``path`` and ``headers`` are expected to contain only ASCII characters. + Other characters are represented with surrogate escapes. + + :func:`read_request` doesn't attempt to read the request body because + WebSocket handshake requests don't have one. If the request contains a + body, it may be read from ``stream`` after this coroutine returns. + + Args: + stream: Input to read the request from. + + Raises: + EOFError: If the connection is closed without a full HTTP request. + SecurityError: If the request exceeds a security limit. + ValueError: If the request isn't well formatted. + + """ + # https://datatracker.ietf.org/doc/html/rfc7230#section-3.1.1 + + # Parsing is simple because fixed values are expected for method and + # version and because path isn't checked. Since WebSocket software tends + # to implement HTTP/1.1 strictly, there's little need for lenient parsing. + + try: + request_line = await read_line(stream) + except EOFError as exc: + raise EOFError("connection closed while reading HTTP request line") from exc + + try: + method, raw_path, version = request_line.split(b" ", 2) + except ValueError: # not enough values to unpack (expected 3, got 1-2) + raise ValueError(f"invalid HTTP request line: {d(request_line)}") from None + + if method != b"GET": + raise ValueError(f"unsupported HTTP method: {d(method)}") + if version != b"HTTP/1.1": + raise ValueError(f"unsupported HTTP version: {d(version)}") + path = raw_path.decode("ascii", "surrogateescape") + + headers = await read_headers(stream) + + return path, headers + + +async def read_response(stream: asyncio.StreamReader) -> tuple[int, str, Headers]: + """ + Read an HTTP/1.1 response and return ``(status_code, reason, headers)``. + + ``reason`` and ``headers`` are expected to contain only ASCII characters. + Other characters are represented with surrogate escapes. + + :func:`read_request` doesn't attempt to read the response body because + WebSocket handshake responses don't have one. If the response contains a + body, it may be read from ``stream`` after this coroutine returns. + + Args: + stream: Input to read the response from. + + Raises: + EOFError: If the connection is closed without a full HTTP response. + SecurityError: If the response exceeds a security limit. + ValueError: If the response isn't well formatted. + + """ + # https://datatracker.ietf.org/doc/html/rfc7230#section-3.1.2 + + # As in read_request, parsing is simple because a fixed value is expected + # for version, status_code is a 3-digit number, and reason can be ignored. + + try: + status_line = await read_line(stream) + except EOFError as exc: + raise EOFError("connection closed while reading HTTP status line") from exc + + try: + version, raw_status_code, raw_reason = status_line.split(b" ", 2) + except ValueError: # not enough values to unpack (expected 3, got 1-2) + raise ValueError(f"invalid HTTP status line: {d(status_line)}") from None + + if version != b"HTTP/1.1": + raise ValueError(f"unsupported HTTP version: {d(version)}") + try: + status_code = int(raw_status_code) + except ValueError: # invalid literal for int() with base 10 + raise ValueError(f"invalid HTTP status code: {d(raw_status_code)}") from None + if not 100 <= status_code < 1000: + raise ValueError(f"unsupported HTTP status code: {d(raw_status_code)}") + if not _value_re.fullmatch(raw_reason): + raise ValueError(f"invalid HTTP reason phrase: {d(raw_reason)}") + reason = raw_reason.decode() + + headers = await read_headers(stream) + + return status_code, reason, headers + + +async def read_headers(stream: asyncio.StreamReader) -> Headers: + """ + Read HTTP headers from ``stream``. + + Non-ASCII characters are represented with surrogate escapes. + + """ + # https://datatracker.ietf.org/doc/html/rfc7230#section-3.2 + + # We don't attempt to support obsolete line folding. + + headers = Headers() + for _ in range(MAX_NUM_HEADERS + 1): + try: + line = await read_line(stream) + except EOFError as exc: + raise EOFError("connection closed while reading HTTP headers") from exc + if line == b"": + break + + try: + raw_name, raw_value = line.split(b":", 1) + except ValueError: # not enough values to unpack (expected 2, got 1) + raise ValueError(f"invalid HTTP header line: {d(line)}") from None + if not _token_re.fullmatch(raw_name): + raise ValueError(f"invalid HTTP header name: {d(raw_name)}") + raw_value = raw_value.strip(b" \t") + if not _value_re.fullmatch(raw_value): + raise ValueError(f"invalid HTTP header value: {d(raw_value)}") + + name = raw_name.decode("ascii") # guaranteed to be ASCII at this point + value = raw_value.decode("ascii", "surrogateescape") + headers[name] = value + + else: + raise SecurityError("too many HTTP headers") + + return headers + + +async def read_line(stream: asyncio.StreamReader) -> bytes: + """ + Read a single line from ``stream``. + + CRLF is stripped from the return value. + + """ + # Security: this is bounded by the StreamReader's limit (default = 32Β KiB). + line = await stream.readline() + # Security: this guarantees header values are small (hard-coded = 8Β KiB) + if len(line) > MAX_LINE_LENGTH: + raise SecurityError("line too long") + # Not mandatory but safe - https://datatracker.ietf.org/doc/html/rfc7230#section-3.5 + if not line.endswith(b"\r\n"): + raise EOFError("line without CRLF") + return line[:-2] diff --git a/.venv/Lib/site-packages/websockets/legacy/protocol.py b/.venv/Lib/site-packages/websockets/legacy/protocol.py new file mode 100644 index 0000000000000000000000000000000000000000..6feddff49139b0e5127f6a0fc3f1587ff8fc5f7a --- /dev/null +++ b/.venv/Lib/site-packages/websockets/legacy/protocol.py @@ -0,0 +1,1635 @@ +from __future__ import annotations + +import asyncio +import codecs +import collections +import logging +import random +import ssl +import struct +import sys +import time +import traceback +import uuid +import warnings +from collections.abc import AsyncIterable, AsyncIterator, Awaitable, Iterable, Mapping +from typing import Any, Callable, Deque, cast + +from ..asyncio.compatibility import asyncio_timeout +from ..datastructures import Headers +from ..exceptions import ( + ConnectionClosed, + ConnectionClosedError, + ConnectionClosedOK, + InvalidState, + PayloadTooBig, + ProtocolError, +) +from ..extensions import Extension +from ..frames import ( + OK_CLOSE_CODES, + OP_BINARY, + OP_CLOSE, + OP_CONT, + OP_PING, + OP_PONG, + OP_TEXT, + Close, + CloseCode, + Opcode, +) +from ..protocol import State +from ..typing import BytesLike, Data, DataLike, LoggerLike, Subprotocol +from .framing import Frame, prepare_ctrl, prepare_data + + +__all__ = ["WebSocketCommonProtocol"] + + +# In order to ensure consistency, the code always checks the current value of +# WebSocketCommonProtocol.state before assigning a new value and never yields +# between the check and the assignment. + + +class WebSocketCommonProtocol(asyncio.Protocol): + """ + WebSocket connection. + + :class:`WebSocketCommonProtocol` provides APIs shared between WebSocket + servers and clients. You shouldn't use it directly. Instead, use + :class:`~websockets.legacy.client.WebSocketClientProtocol` or + :class:`~websockets.legacy.server.WebSocketServerProtocol`. + + This documentation focuses on low-level details that aren't covered in the + documentation of :class:`~websockets.legacy.client.WebSocketClientProtocol` + and :class:`~websockets.legacy.server.WebSocketServerProtocol` for the sake + of simplicity. + + Once the connection is open, a Ping_ frame is sent every ``ping_interval`` + seconds. This serves as a keepalive. It helps keeping the connection open, + especially in the presence of proxies with short timeouts on inactive + connections. Set ``ping_interval`` to :obj:`None` to disable this behavior. + + .. _Ping: https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.2 + + If the corresponding Pong_ frame isn't received within ``ping_timeout`` + seconds, the connection is considered unusable and is closed with code 1011. + This ensures that the remote endpoint remains responsive. Set + ``ping_timeout`` to :obj:`None` to disable this behavior. + + .. _Pong: https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.3 + + See the discussion of :doc:`keepalive <../../topics/keepalive>` for details. + + The ``close_timeout`` parameter defines a maximum wait time for completing + the closing handshake and terminating the TCP connection. For legacy + reasons, :meth:`close` completes in at most ``5 * close_timeout`` seconds + for clients and ``4 * close_timeout`` for servers. + + ``close_timeout`` is a parameter of the protocol because websockets usually + calls :meth:`close` implicitly upon exit: + + * on the client side, when using :func:`~websockets.legacy.client.connect` + as a context manager; + * on the server side, when the connection handler terminates. + + To apply a timeout to any other API, wrap it in :func:`~asyncio.timeout` or + :func:`~asyncio.wait_for`. + + The ``max_size`` parameter enforces the maximum size for incoming messages + in bytes. The default value is 1Β MiB. If a larger message is received, + :meth:`recv` will raise :exc:`~websockets.exceptions.ConnectionClosedError` + and the connection will be closed with code 1009. + + The ``max_queue`` parameter sets the maximum length of the queue that + holds incoming messages. The default value is ``32``. Messages are added + to an in-memory queue when they're received; then :meth:`recv` pops from + that queue. In order to prevent excessive memory consumption when + messages are received faster than they can be processed, the queue must + be bounded. If the queue fills up, the protocol stops processing incoming + data until :meth:`recv` is called. In this situation, various receive + buffers (at least in :mod:`asyncio` and in the OS) will fill up, then the + TCP receive window will shrink, slowing down transmission to avoid packet + loss. + + Since Python can use up to 4 bytes of memory to represent a single + character, each connection may use up to ``4 * max_size * max_queue`` + bytes of memory to store incoming messages. By default, this is 128Β MiB. + You may want to lower the limits, depending on your application's + requirements. + + The ``read_limit`` argument sets the high-water limit of the buffer for + incoming bytes. The low-water limit is half the high-water limit. The + default value is 64Β KiB, half of asyncio's default (based on the current + implementation of :class:`~asyncio.StreamReader`). + + The ``write_limit`` argument sets the high-water limit of the buffer for + outgoing bytes. The low-water limit is a quarter of the high-water limit. + The default value is 64Β KiB, equal to asyncio's default (based on the + current implementation of ``FlowControlMixin``). + + See the discussion of :doc:`memory usage <../../topics/memory>` for details. + + Args: + logger: Logger for this server. + It defaults to ``logging.getLogger("websockets.protocol")``. + See the :doc:`logging guide <../../topics/logging>` for details. + ping_interval: Interval between keepalive pings in seconds. + :obj:`None` disables keepalive. + ping_timeout: Timeout for keepalive pings in seconds. + :obj:`None` disables timeouts. + close_timeout: Timeout for closing the connection in seconds. + For legacy reasons, the actual timeout is 4 or 5 times larger. + max_size: Maximum size of incoming messages in bytes. + :obj:`None` disables the limit. + max_queue: Maximum number of incoming messages in receive buffer. + :obj:`None` disables the limit. + read_limit: High-water mark of read buffer in bytes. + write_limit: High-water mark of write buffer in bytes. + + """ + + # There are only two differences between the client-side and server-side + # behavior: masking the payload and closing the underlying TCP connection. + # Set is_client = True/False and side = "client"/"server" to pick a side. + is_client: bool + side: str = "undefined" + + def __init__( + self, + *, + logger: LoggerLike | None = None, + ping_interval: float | None = 20, + ping_timeout: float | None = 20, + close_timeout: float | None = None, + max_size: int | None = 2**20, + max_queue: int | None = 2**5, + read_limit: int = 2**16, + write_limit: int = 2**16, + # The following arguments are kept only for backwards compatibility. + host: str | None = None, + port: int | None = None, + secure: bool | None = None, + legacy_recv: bool = False, + loop: asyncio.AbstractEventLoop | None = None, + timeout: float | None = None, + ) -> None: + if legacy_recv: # pragma: no cover + warnings.warn("legacy_recv is deprecated", DeprecationWarning) + + # Backwards compatibility: close_timeout used to be called timeout. + if timeout is None: + timeout = 10 + else: + warnings.warn("rename timeout to close_timeout", DeprecationWarning) + # If both are specified, timeout is ignored. + if close_timeout is None: + close_timeout = timeout + + # Backwards compatibility: the loop parameter used to be supported. + if loop is None: + loop = asyncio.get_event_loop() + else: + warnings.warn("remove loop argument", DeprecationWarning) + + self.ping_interval = ping_interval + self.ping_timeout = ping_timeout + self.close_timeout = close_timeout + self.max_size = max_size + self.max_queue = max_queue + self.read_limit = read_limit + self.write_limit = write_limit + + # Unique identifier. For logs. + self.id: uuid.UUID = uuid.uuid4() + """Unique identifier of the connection. Useful in logs.""" + + # Logger or LoggerAdapter for this connection. + if logger is None: + logger = logging.getLogger("websockets.protocol") + self.logger: LoggerLike = logging.LoggerAdapter(logger, {"websocket": self}) + """Logger for this connection.""" + + # Track if DEBUG is enabled. Shortcut logging calls if it isn't. + self.debug = logger.isEnabledFor(logging.DEBUG) + + self.loop = loop + + self._host = host + self._port = port + self._secure = secure + self.legacy_recv = legacy_recv + + # Configure read buffer limits. The high-water limit is defined by + # ``self.read_limit``. The ``limit`` argument controls the line length + # limit and half the buffer limit of :class:`~asyncio.StreamReader`. + # That's why it must be set to half of ``self.read_limit``. + self.reader = asyncio.StreamReader(limit=read_limit // 2, loop=loop) + + # Copied from asyncio.FlowControlMixin + self._paused = False + self._drain_waiter: asyncio.Future[None] | None = None + + # This class implements the data transfer and closing handshake, which + # are shared between the client-side and the server-side. + # Subclasses implement the opening handshake and, on success, execute + # :meth:`connection_open` to change the state to OPEN. + self.state = State.CONNECTING + if self.debug: + self.logger.debug("= connection is CONNECTING") + + # HTTP protocol parameters. + self.path: str + """Path of the opening handshake request.""" + self.request_headers: Headers + """Opening handshake request headers.""" + self.response_headers: Headers + """Opening handshake response headers.""" + + # WebSocket protocol parameters. + self.extensions: list[Extension] = [] + self.subprotocol: Subprotocol | None = None + """Subprotocol, if one was negotiated.""" + + # Close code and reason, set when a close frame is sent or received. + self.close_rcvd: Close | None = None + self.close_sent: Close | None = None + self.close_rcvd_then_sent: bool | None = None + + # Completed when the connection state becomes CLOSED. Translates the + # :meth:`connection_lost` callback to a :class:`~asyncio.Future` + # that can be awaited. (Other :class:`~asyncio.Protocol` callbacks are + # translated by ``self.stream_reader``). + self.connection_lost_waiter: asyncio.Future[None] = loop.create_future() + + # Queue of received messages. + self.messages: Deque[Data] = collections.deque() + self._pop_message_waiter: asyncio.Future[None] | None = None + self._put_message_waiter: asyncio.Future[None] | None = None + + # Protect sending fragmented messages. + self._fragmented_message_waiter: asyncio.Future[None] | None = None + + # Mapping of ping IDs to pong waiters, in chronological order. + self.pings: dict[bytes, tuple[asyncio.Future[float], float]] = {} + + self.latency: float = 0 + """ + Latency of the connection, in seconds. + + Latency is defined as the round-trip time of the connection. It is + measured by sending a Ping frame and waiting for a matching Pong frame. + Before the first measurement, :attr:`latency` is ``0``. + + By default, websockets enables a :ref:`keepalive ` mechanism + that sends Ping frames automatically at regular intervals. You can also + send Ping frames and measure latency with :meth:`ping`. + """ + + # Task running the data transfer. + self.transfer_data_task: asyncio.Task[None] + + # Exception that occurred during data transfer, if any. + self.transfer_data_exc: BaseException | None = None + + # Task sending keepalive pings. + self.keepalive_ping_task: asyncio.Task[None] + + # Task closing the TCP connection. + self.close_connection_task: asyncio.Task[None] + + # Copied from asyncio.FlowControlMixin + async def _drain_helper(self) -> None: # pragma: no cover + if self.connection_lost_waiter.done(): + raise ConnectionResetError("Connection lost") + if not self._paused: + return + waiter = self._drain_waiter + assert waiter is None or waiter.cancelled() + waiter = self.loop.create_future() + self._drain_waiter = waiter + await waiter + + # Copied from asyncio.StreamWriter + async def _drain(self) -> None: # pragma: no cover + if self.reader is not None: + exc = self.reader.exception() + if exc is not None: + raise exc + if self.transport is not None: + if self.transport.is_closing(): + # Yield to the event loop so connection_lost() may be + # called. Without this, _drain_helper() would return + # immediately, and code that calls + # write(...); yield from drain() + # in a loop would never call connection_lost(), so it + # would not see an error when the socket is closed. + await asyncio.sleep(0) + await self._drain_helper() + + def connection_open(self) -> None: + """ + Callback when the WebSocket opening handshake completes. + + Enter the OPEN state and start the data transfer phase. + + """ + # 4.1. The WebSocket Connection is Established. + assert self.state is State.CONNECTING + self.state = State.OPEN + if self.debug: + self.logger.debug("= connection is OPEN") + # Start the task that receives incoming WebSocket messages. + self.transfer_data_task = self.loop.create_task(self.transfer_data()) + # Start the task that sends pings at regular intervals. + self.keepalive_ping_task = self.loop.create_task(self.keepalive_ping()) + # Start the task that eventually closes the TCP connection. + self.close_connection_task = self.loop.create_task(self.close_connection()) + + @property + def host(self) -> str | None: + alternative = "remote_address" if self.is_client else "local_address" + warnings.warn(f"use {alternative}[0] instead of host", DeprecationWarning) + return self._host + + @property + def port(self) -> int | None: + alternative = "remote_address" if self.is_client else "local_address" + warnings.warn(f"use {alternative}[1] instead of port", DeprecationWarning) + return self._port + + @property + def secure(self) -> bool | None: + warnings.warn("don't use secure", DeprecationWarning) + return self._secure + + # Public API + + @property + def local_address(self) -> Any: + """ + Local address of the connection. + + For IPv4 connections, this is a ``(host, port)`` tuple. + + The format of the address depends on the address family; + see :meth:`~socket.socket.getsockname`. + + :obj:`None` if the TCP connection isn't established yet. + + """ + try: + transport = self.transport + except AttributeError: + return None + else: + return transport.get_extra_info("sockname") + + @property + def remote_address(self) -> Any: + """ + Remote address of the connection. + + For IPv4 connections, this is a ``(host, port)`` tuple. + + The format of the address depends on the address family; + see :meth:`~socket.socket.getpeername`. + + :obj:`None` if the TCP connection isn't established yet. + + """ + try: + transport = self.transport + except AttributeError: + return None + else: + return transport.get_extra_info("peername") + + @property + def open(self) -> bool: + """ + :obj:`True` when the connection is open; :obj:`False` otherwise. + + This attribute may be used to detect disconnections. However, this + approach is discouraged per the EAFP_ principle. Instead, you should + handle :exc:`~websockets.exceptions.ConnectionClosed` exceptions. + + .. _EAFP: https://docs.python.org/3/glossary.html#term-eafp + + """ + return self.state is State.OPEN and not self.transfer_data_task.done() + + @property + def closed(self) -> bool: + """ + :obj:`True` when the connection is closed; :obj:`False` otherwise. + + Be aware that both :attr:`open` and :attr:`closed` are :obj:`False` + during the opening and closing sequences. + + """ + return self.state is State.CLOSED + + @property + def close_code(self) -> int | None: + """ + WebSocket close code, defined in `section 7.1.5 of RFC 6455`_. + + .. _section 7.1.5 of RFC 6455: + https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.5 + + :obj:`None` if the connection isn't closed yet. + + """ + if self.state is not State.CLOSED: + return None + elif self.close_rcvd is None: + return CloseCode.ABNORMAL_CLOSURE + else: + return self.close_rcvd.code + + @property + def close_reason(self) -> str | None: + """ + WebSocket close reason, defined in `section 7.1.6 of RFC 6455`_. + + .. _section 7.1.6 of RFC 6455: + https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.6 + + :obj:`None` if the connection isn't closed yet. + + """ + if self.state is not State.CLOSED: + return None + elif self.close_rcvd is None: + return "" + else: + return self.close_rcvd.reason + + async def __aiter__(self) -> AsyncIterator[Data]: + """ + Iterate on incoming messages. + + The iterator exits normally when the connection is closed with the close + code 1000 (OK) or 1001 (going away) or without a close code. + + It raises a :exc:`~websockets.exceptions.ConnectionClosedError` + exception when the connection is closed with any other code. + + """ + try: + while True: + yield await self.recv() + except ConnectionClosedOK: + return + + async def recv(self) -> Data: + """ + Receive the next message. + + When the connection is closed, :meth:`recv` raises + :exc:`~websockets.exceptions.ConnectionClosed`. Specifically, it raises + :exc:`~websockets.exceptions.ConnectionClosedOK` after a normal + connection closure and + :exc:`~websockets.exceptions.ConnectionClosedError` after a protocol + error or a network failure. This is how you detect the end of the + message stream. + + Canceling :meth:`recv` is safe. There's no risk of losing the next + message. The next invocation of :meth:`recv` will return it. + + This makes it possible to enforce a timeout by wrapping :meth:`recv` in + :func:`~asyncio.timeout` or :func:`~asyncio.wait_for`. + + Returns: + A string (:class:`str`) for a Text_ frame. A bytestring + (:class:`bytes`) for a Binary_ frame. + + .. _Text: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6 + .. _Binary: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6 + + Raises: + ConnectionClosed: When the connection is closed. + RuntimeError: If two coroutines call :meth:`recv` concurrently. + + """ + if self._pop_message_waiter is not None: + raise RuntimeError( + "cannot call recv while another coroutine " + "is already waiting for the next message" + ) + + # Don't await self.ensure_open() here: + # - messages could be available in the queue even if the connection + # is closed; + # - messages could be received before the closing frame even if the + # connection is closing. + + # Wait until there's a message in the queue (if necessary) or the + # connection is closed. + while len(self.messages) <= 0: + pop_message_waiter: asyncio.Future[None] = self.loop.create_future() + self._pop_message_waiter = pop_message_waiter + try: + # If asyncio.wait() is canceled, it doesn't cancel + # pop_message_waiter and self.transfer_data_task. + await asyncio.wait( + [pop_message_waiter, self.transfer_data_task], + return_when=asyncio.FIRST_COMPLETED, + ) + finally: + self._pop_message_waiter = None + + # If asyncio.wait(...) exited because self.transfer_data_task + # completed before receiving a new message, raise a suitable + # exception (or return None if legacy_recv is enabled). + if not pop_message_waiter.done(): + if self.legacy_recv: + return None # type: ignore + else: + # Wait until the connection is closed to raise + # ConnectionClosed with the correct code and reason. + await self.ensure_open() + + # Pop a message from the queue. + message = self.messages.popleft() + + # Notify transfer_data(). + if self._put_message_waiter is not None: + self._put_message_waiter.set_result(None) + self._put_message_waiter = None + + return message + + async def send( + self, + message: DataLike | Iterable[DataLike] | AsyncIterable[DataLike], + ) -> None: + """ + Send a message. + + A string (:class:`str`) is sent as a Text_ frame. A bytestring or + bytes-like object (:class:`bytes`, :class:`bytearray`, or + :class:`memoryview`) is sent as a Binary_ frame. + + .. _Text: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6 + .. _Binary: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6 + + :meth:`send` also accepts an iterable or an asynchronous iterable of + strings, bytestrings, or bytes-like objects to enable fragmentation_. + Each item is treated as a message fragment and sent in its own frame. + All items must be of the same type, or else :meth:`send` will raise a + :exc:`TypeError` and the connection will be closed. + + .. _fragmentation: https://datatracker.ietf.org/doc/html/rfc6455#section-5.4 + + :meth:`send` rejects dict-like objects because this is often an error. + (If you want to send the keys of a dict-like object as fragments, call + its :meth:`~dict.keys` method and pass the result to :meth:`send`.) + + Canceling :meth:`send` is discouraged. Instead, you should close the + connection with :meth:`close`. Indeed, there are only two situations + where :meth:`send` may yield control to the event loop and then get + canceled; in both cases, :meth:`close` has the same effect and is + more clear: + + 1. The write buffer is full. If you don't want to wait until enough + data is sent, your only alternative is to close the connection. + :meth:`close` will likely time out then abort the TCP connection. + 2. ``message`` is an asynchronous iterator that yields control. + Stopping in the middle of a fragmented message will cause a + protocol error and the connection will be closed. + + When the connection is closed, :meth:`send` raises + :exc:`~websockets.exceptions.ConnectionClosed`. Specifically, it + raises :exc:`~websockets.exceptions.ConnectionClosedOK` after a normal + connection closure and + :exc:`~websockets.exceptions.ConnectionClosedError` after a protocol + error or a network failure. + + Args: + message: Message to send. + + Raises: + ConnectionClosed: When the connection is closed. + TypeError: If ``message`` doesn't have a supported type. + + """ + await self.ensure_open() + + # While sending a fragmented message, prevent sending other messages + # until all fragments are sent. + while self._fragmented_message_waiter is not None: + await asyncio.shield(self._fragmented_message_waiter) + + # Unfragmented message -- this case must be handled first because + # strings and bytes-like objects are iterable. + + if isinstance(message, (str, bytes, bytearray, memoryview)): + opcode, data = prepare_data(message) + await self.write_frame(True, opcode, data) + + # Catch a common mistake -- passing a dict to send(). + + elif isinstance(message, Mapping): + raise TypeError("data is a dict-like object") + + # Fragmented message -- regular iterator. + + elif isinstance(message, Iterable): + iter_message = iter(message) + try: + fragment = next(iter_message) + except StopIteration: + return + opcode, data = prepare_data(fragment) + + self._fragmented_message_waiter = self.loop.create_future() + try: + # First fragment. + await self.write_frame(False, opcode, data) + + # Other fragments. + for fragment in iter_message: + confirm_opcode, data = prepare_data(fragment) + if confirm_opcode != opcode: + raise TypeError("data contains inconsistent types") + await self.write_frame(False, OP_CONT, data) + + # Final fragment. + await self.write_frame(True, OP_CONT, b"") + + except (Exception, asyncio.CancelledError): + # We're half-way through a fragmented message and we can't + # complete it. This makes the connection unusable. + self.fail_connection(CloseCode.INTERNAL_ERROR) + raise + + finally: + self._fragmented_message_waiter.set_result(None) + self._fragmented_message_waiter = None + + # Fragmented message -- asynchronous iterator + + elif isinstance(message, AsyncIterable): + # Implement aiter_message = aiter(message) without aiter + # Work around https://github.com/python/mypy/issues/5738 + aiter_message = cast( + Callable[[AsyncIterable[DataLike]], AsyncIterator[DataLike]], + type(message).__aiter__, + )(message) + try: + # Implement fragment = anext(aiter_message) without anext + # Work around https://github.com/python/mypy/issues/5738 + fragment = await cast( + Callable[[AsyncIterator[DataLike]], Awaitable[DataLike]], + type(aiter_message).__anext__, + )(aiter_message) + except StopAsyncIteration: + return + opcode, data = prepare_data(fragment) + + self._fragmented_message_waiter = self.loop.create_future() + try: + # First fragment. + await self.write_frame(False, opcode, data) + + # Other fragments. + async for fragment in aiter_message: + confirm_opcode, data = prepare_data(fragment) + if confirm_opcode != opcode: + raise TypeError("data contains inconsistent types") + await self.write_frame(False, OP_CONT, data) + + # Final fragment. + await self.write_frame(True, OP_CONT, b"") + + except (Exception, asyncio.CancelledError): + # We're half-way through a fragmented message and we can't + # complete it. This makes the connection unusable. + self.fail_connection(CloseCode.INTERNAL_ERROR) + raise + + finally: + self._fragmented_message_waiter.set_result(None) + self._fragmented_message_waiter = None + + else: + raise TypeError("data must be str, bytes-like, or iterable") + + async def close( + self, + code: int = CloseCode.NORMAL_CLOSURE, + reason: str = "", + ) -> None: + """ + Perform the closing handshake. + + :meth:`close` waits for the other end to complete the handshake and + for the TCP connection to terminate. As a consequence, there's no need + to await :meth:`wait_closed` after :meth:`close`. + + :meth:`close` is idempotent: it doesn't do anything once the + connection is closed. + + Wrapping :func:`close` in :func:`~asyncio.create_task` is safe, given + that errors during connection termination aren't particularly useful. + + Canceling :meth:`close` is discouraged. If it takes too long, you can + set a shorter ``close_timeout``. If you don't want to wait, let the + Python process exit, then the OS will take care of closing the TCP + connection. + + Args: + code: WebSocket close code. + reason: WebSocket close reason. + + """ + try: + async with asyncio_timeout(self.close_timeout): + await self.write_close_frame(Close(code, reason)) + except asyncio.TimeoutError: + # If the close frame cannot be sent because the send buffers + # are full, the closing handshake won't complete anyway. + # Fail the connection to shut down faster. + self.fail_connection() + + # If no close frame is received within the timeout, asyncio_timeout() + # cancels the data transfer task and raises TimeoutError. + + # If close() is called multiple times concurrently and one of these + # calls hits the timeout, the data transfer task will be canceled. + # Other calls will receive a CancelledError here. + + try: + # If close() is canceled during the wait, self.transfer_data_task + # is canceled before the timeout elapses. + async with asyncio_timeout(self.close_timeout): + await self.transfer_data_task + except (asyncio.TimeoutError, asyncio.CancelledError): + pass + + # Wait for the close connection task to close the TCP connection. + await asyncio.shield(self.close_connection_task) + + async def wait_closed(self) -> None: + """ + Wait until the connection is closed. + + This coroutine is identical to the :attr:`closed` attribute, except it + can be awaited. + + This can make it easier to detect connection termination, regardless + of its cause, in tasks that interact with the WebSocket connection. + + """ + await asyncio.shield(self.connection_lost_waiter) + + async def ping(self, data: DataLike | None = None) -> Awaitable[float]: + """ + Send a Ping_. + + .. _Ping: https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.2 + + A ping may serve as a keepalive, as a check that the remote endpoint + received all messages up to this point, or to measure :attr:`latency`. + + Canceling :meth:`ping` is discouraged. If :meth:`ping` doesn't return + immediately, it means the write buffer is full. If you don't want to + wait, you should close the connection. + + Canceling the :class:`~asyncio.Future` returned by :meth:`ping` has no + effect. + + Args: + data: Payload of the ping. A string will be encoded to UTF-8. + If ``data`` is :obj:`None`, the payload is four random bytes. + + Returns: + A future that will be completed when the corresponding pong is + received. You can ignore it if you don't intend to wait. The result + of the future is the latency of the connection in seconds. + + :: + + pong_waiter = await ws.ping() + # only if you want to wait for the corresponding pong + latency = await pong_waiter + + Raises: + ConnectionClosed: When the connection is closed. + RuntimeError: If another ping was sent with the same data and + the corresponding pong wasn't received yet. + + """ + await self.ensure_open() + + if data is not None: + data = prepare_ctrl(data) + + # Protect against duplicates if a payload is explicitly set. + if data in self.pings: + raise RuntimeError("already waiting for a pong with the same data") + + # Generate a unique random payload otherwise. + while data is None or data in self.pings: + data = struct.pack("!I", random.getrandbits(32)) + + pong_waiter = self.loop.create_future() + # Resolution of time.monotonic() may be too low on Windows. + ping_timestamp = time.perf_counter() + self.pings[data] = (pong_waiter, ping_timestamp) + + await self.write_frame(True, OP_PING, data) + + return asyncio.shield(pong_waiter) + + async def pong(self, data: DataLike = b"") -> None: + """ + Send a Pong_. + + .. _Pong: https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.3 + + An unsolicited pong may serve as a unidirectional heartbeat. + + Canceling :meth:`pong` is discouraged. If :meth:`pong` doesn't return + immediately, it means the write buffer is full. If you don't want to + wait, you should close the connection. + + Args: + data: Payload of the pong. A string will be encoded to UTF-8. + + Raises: + ConnectionClosed: When the connection is closed. + + """ + await self.ensure_open() + + data = prepare_ctrl(data) + + await self.write_frame(True, OP_PONG, data) + + # Private methods - no guarantees. + + def connection_closed_exc(self) -> ConnectionClosed: + exc: ConnectionClosed + if ( + self.close_rcvd is not None + and self.close_rcvd.code in OK_CLOSE_CODES + and self.close_sent is not None + and self.close_sent.code in OK_CLOSE_CODES + ): + exc = ConnectionClosedOK( + self.close_rcvd, + self.close_sent, + self.close_rcvd_then_sent, + ) + else: + exc = ConnectionClosedError( + self.close_rcvd, + self.close_sent, + self.close_rcvd_then_sent, + ) + # Chain to the exception that terminated data transfer, if any. + exc.__cause__ = self.transfer_data_exc + return exc + + async def ensure_open(self) -> None: + """ + Check that the WebSocket connection is open. + + Raise :exc:`~websockets.exceptions.ConnectionClosed` if it isn't. + + """ + # Handle cases from most common to least common for performance. + if self.state is State.OPEN: + # If self.transfer_data_task exited without a closing handshake, + # self.close_connection_task may be closing the connection, going + # straight from OPEN to CLOSED. + if self.transfer_data_task.done(): + await asyncio.shield(self.close_connection_task) + raise self.connection_closed_exc() + else: + return + + if self.state is State.CLOSED: + raise self.connection_closed_exc() + + if self.state is State.CLOSING: + # If we started the closing handshake, wait for its completion to + # get the proper close code and reason. self.close_connection_task + # will complete within 4 or 5 * close_timeout after close(). The + # CLOSING state also occurs when failing the connection. In that + # case self.close_connection_task will complete even faster. + await asyncio.shield(self.close_connection_task) + raise self.connection_closed_exc() + + # Control may only reach this point in buggy third-party subclasses. + assert self.state is State.CONNECTING + raise InvalidState("WebSocket connection isn't established yet") + + async def transfer_data(self) -> None: + """ + Read incoming messages and put them in a queue. + + This coroutine runs in a task until the closing handshake is started. + + """ + try: + while True: + message = await self.read_message() + + # Exit the loop when receiving a close frame. + if message is None: + break + + # Wait until there's room in the queue (if necessary). + if self.max_queue is not None: + while len(self.messages) >= self.max_queue: + self._put_message_waiter = self.loop.create_future() + try: + await asyncio.shield(self._put_message_waiter) + finally: + self._put_message_waiter = None + + # Put the message in the queue. + self.messages.append(message) + + # Notify recv(). + if self._pop_message_waiter is not None: + self._pop_message_waiter.set_result(None) + self._pop_message_waiter = None + + except asyncio.CancelledError as exc: + self.transfer_data_exc = exc + # If fail_connection() cancels this task, avoid logging the error + # twice and failing the connection again. + raise + + except ProtocolError as exc: + self.transfer_data_exc = exc + self.fail_connection(CloseCode.PROTOCOL_ERROR) + + except (ConnectionError, TimeoutError, EOFError, ssl.SSLError) as exc: + # Reading data with self.reader.readexactly may raise: + # - most subclasses of ConnectionError if the TCP connection + # breaks, is reset, or is aborted; + # - TimeoutError if the TCP connection times out; + # - IncompleteReadError, a subclass of EOFError, if fewer + # bytes are available than requested; + # - ssl.SSLError if the other side infringes the TLS protocol. + self.transfer_data_exc = exc + self.fail_connection(CloseCode.ABNORMAL_CLOSURE) + + except UnicodeDecodeError as exc: + self.transfer_data_exc = exc + self.fail_connection(CloseCode.INVALID_DATA) + + except PayloadTooBig as exc: + self.transfer_data_exc = exc + self.fail_connection(CloseCode.MESSAGE_TOO_BIG) + + except Exception as exc: + # This shouldn't happen often because exceptions expected under + # regular circumstances are handled above. If it does, consider + # catching and handling more exceptions. + self.logger.error("data transfer failed", exc_info=True) + + self.transfer_data_exc = exc + self.fail_connection(CloseCode.INTERNAL_ERROR) + + async def read_message(self) -> Data | None: + """ + Read a single message from the connection. + + Re-assemble data frames if the message is fragmented. + + Return :obj:`None` when the closing handshake is started. + + """ + frame = await self.read_data_frame(max_size=self.max_size) + + # A close frame was received. + if frame is None: + return None + + if frame.opcode == OP_TEXT: + text = True + elif frame.opcode == OP_BINARY: + text = False + else: # frame.opcode == OP_CONT + raise ProtocolError("unexpected opcode") + + # Shortcut for the common case - no fragmentation + if frame.fin: + if isinstance(frame.data, memoryview): + raise AssertionError("only compressed outgoing frames use memoryview") + return frame.data.decode() if text else bytes(frame.data) + + # 5.4. Fragmentation + fragments: list[DataLike] = [] + max_size = self.max_size + if text: + decoder_factory = codecs.getincrementaldecoder("utf-8") + decoder = decoder_factory(errors="strict") + if max_size is None: + + def append(frame: Frame) -> None: + nonlocal fragments + fragments.append(decoder.decode(frame.data, frame.fin)) + + else: + + def append(frame: Frame) -> None: + nonlocal fragments, max_size + fragments.append(decoder.decode(frame.data, frame.fin)) + assert isinstance(max_size, int) + max_size -= len(frame.data) + + else: + if max_size is None: + + def append(frame: Frame) -> None: + nonlocal fragments + fragments.append(frame.data) + + else: + + def append(frame: Frame) -> None: + nonlocal fragments, max_size + fragments.append(frame.data) + assert isinstance(max_size, int) + max_size -= len(frame.data) + + append(frame) + + while not frame.fin: + frame = await self.read_data_frame(max_size=max_size) + if frame is None: + raise ProtocolError("incomplete fragmented message") + if frame.opcode != OP_CONT: + raise ProtocolError("unexpected opcode") + append(frame) + + return ("" if text else b"").join(fragments) + + async def read_data_frame(self, max_size: int | None) -> Frame | None: + """ + Read a single data frame from the connection. + + Process control frames received before the next data frame. + + Return :obj:`None` if a close frame is encountered before any data frame. + + """ + # 6.2. Receiving Data + while True: + frame = await self.read_frame(max_size) + + # 5.5. Control Frames + if frame.opcode == OP_CLOSE: + # 7.1.5. The WebSocket Connection Close Code + # 7.1.6. The WebSocket Connection Close Reason + self.close_rcvd = Close.parse(frame.data) + if self.close_sent is not None: + self.close_rcvd_then_sent = False + try: + # Echo the original data instead of re-serializing it with + # Close.serialize() because that fails when the close frame + # is empty and Close.parse() synthesizes a 1005 close code. + await self.write_close_frame(self.close_rcvd, frame.data) + except ConnectionClosed: + # Connection closed before we could echo the close frame. + pass + return None + + elif frame.opcode == OP_PING: + # Answer pings, unless connection is CLOSING. + if self.state is State.OPEN: + try: + await self.pong(frame.data) + except ConnectionClosed: + # Connection closed while draining write buffer. + pass + + elif frame.opcode == OP_PONG: + if frame.data in self.pings: + pong_timestamp = time.perf_counter() + # Sending a pong for only the most recent ping is legal. + # Acknowledge all previous pings too in that case. + ping_id = None + ping_ids = [] + for ping_id, (pong_waiter, ping_timestamp) in self.pings.items(): + ping_ids.append(ping_id) + if not pong_waiter.done(): + pong_waiter.set_result(pong_timestamp - ping_timestamp) + if ping_id == frame.data: + self.latency = pong_timestamp - ping_timestamp + break + else: + raise AssertionError("solicited pong not found in pings") + # Remove acknowledged pings from self.pings. + for ping_id in ping_ids: + del self.pings[ping_id] + + # 5.6. Data Frames + else: + return frame + + async def read_frame(self, max_size: int | None) -> Frame: + """ + Read a single frame from the connection. + + """ + frame = await Frame.read( + self.reader.readexactly, + mask=not self.is_client, + max_size=max_size, + extensions=self.extensions, + ) + if self.debug: + self.logger.debug("< %s", frame) + return frame + + def write_frame_sync(self, fin: bool, opcode: int, data: BytesLike) -> None: + frame = Frame(fin, Opcode(opcode), data) + if self.debug: + self.logger.debug("> %s", frame) + frame.write( + self.transport.write, + mask=self.is_client, + extensions=self.extensions, + ) + + async def drain(self) -> None: + try: + # Handle flow control automatically. + await self._drain() + except ConnectionError: + # Terminate the connection if the socket died. + self.fail_connection() + # Wait until the connection is closed to raise ConnectionClosed + # with the correct code and reason. + await self.ensure_open() + + async def write_frame( + self, fin: bool, opcode: int, data: BytesLike, *, _state: int = State.OPEN + ) -> None: + # Defensive assertion for protocol compliance. + if self.state is not _state: # pragma: no cover + raise InvalidState( + f"Cannot write to a WebSocket in the {self.state.name} state" + ) + self.write_frame_sync(fin, opcode, data) + await self.drain() + + async def write_close_frame( + self, close: Close, data: BytesLike | None = None + ) -> None: + """ + Write a close frame if and only if the connection state is OPEN. + + This dedicated coroutine must be used for writing close frames to + ensure that at most one close frame is sent on a given connection. + + """ + # Test and set the connection state before sending the close frame to + # avoid sending two frames in case of concurrent calls. + if self.state is State.OPEN: + # 7.1.3. The WebSocket Closing Handshake is Started + self.state = State.CLOSING + if self.debug: + self.logger.debug("= connection is CLOSING") + + self.close_sent = close + if self.close_rcvd is not None: + self.close_rcvd_then_sent = True + if data is None: + data = close.serialize() + + # 7.1.2. Start the WebSocket Closing Handshake + await self.write_frame(True, OP_CLOSE, data, _state=State.CLOSING) + + async def keepalive_ping(self) -> None: + """ + Send a Ping frame and wait for a Pong frame at regular intervals. + + This coroutine exits when the connection terminates and one of the + following happens: + + - :meth:`ping` raises :exc:`ConnectionClosed`, or + - :meth:`close_connection` cancels :attr:`keepalive_ping_task`. + + """ + if self.ping_interval is None: + return + + try: + while True: + await asyncio.sleep(self.ping_interval) + + if self.debug: + self.logger.debug("% sending keepalive ping") + pong_waiter = await self.ping() + + if self.ping_timeout is not None: + try: + async with asyncio_timeout(self.ping_timeout): + # Raises CancelledError if the connection is closed, + # when close_connection() cancels keepalive_ping(). + # Raises ConnectionClosed if the connection is lost, + # when connection_lost() calls abort_pings(). + await pong_waiter + if self.debug: + self.logger.debug("% received keepalive pong") + except asyncio.TimeoutError: + if self.debug: + self.logger.debug("- timed out waiting for keepalive pong") + self.fail_connection( + CloseCode.INTERNAL_ERROR, + "keepalive ping timeout", + ) + break + + except ConnectionClosed: + pass + + except Exception: + self.logger.error("keepalive ping failed", exc_info=True) + + async def close_connection(self) -> None: + """ + 7.1.1. Close the WebSocket Connection + + When the opening handshake succeeds, :meth:`connection_open` starts + this coroutine in a task. It waits for the data transfer phase to + complete then it closes the TCP connection cleanly. + + When the opening handshake fails, :meth:`fail_connection` does the + same. There's no data transfer phase in that case. + + """ + try: + # Wait for the data transfer phase to complete. + if hasattr(self, "transfer_data_task"): + try: + await self.transfer_data_task + except asyncio.CancelledError: + pass + + # Cancel the keepalive ping task. + if hasattr(self, "keepalive_ping_task"): + self.keepalive_ping_task.cancel() + + # A client should wait for a TCP close from the server. + if self.is_client and hasattr(self, "transfer_data_task"): + if await self.wait_for_connection_lost(): + return + if self.debug: + self.logger.debug("- timed out waiting for TCP close") + + # Half-close the TCP connection if possible (when there's no TLS). + if self.transport.can_write_eof(): + if self.debug: + self.logger.debug("x half-closing TCP connection") + # write_eof() doesn't document which exceptions it raises. + # "[Errno 107] Transport endpoint is not connected" happens + # but it isn't completely clear under which circumstances. + # uvloop can raise RuntimeError here. + try: + self.transport.write_eof() + except (OSError, RuntimeError): # pragma: no cover + pass + + if await self.wait_for_connection_lost(): + return + if self.debug: + self.logger.debug("- timed out waiting for TCP close") + + finally: + # The try/finally ensures that the transport never remains open, + # even if this coroutine is canceled (for example). + await self.close_transport() + + async def close_transport(self) -> None: + """ + Close the TCP connection. + + """ + # If connection_lost() was called, the TCP connection is closed. + # However, if TLS is enabled, the transport still needs closing. + # Else asyncio complains: ResourceWarning: unclosed transport. + if self.connection_lost_waiter.done() and self.transport.is_closing(): + return + + # Close the TCP connection. Buffers are flushed asynchronously. + if self.debug: + self.logger.debug("x closing TCP connection") + self.transport.close() + + if await self.wait_for_connection_lost(): + return + if self.debug: + self.logger.debug("- timed out waiting for TCP close") + + # Abort the TCP connection. Buffers are discarded. + if self.debug: + self.logger.debug("x aborting TCP connection") + self.transport.abort() + + # connection_lost() is called quickly after aborting. + await self.wait_for_connection_lost() + + async def wait_for_connection_lost(self) -> bool: + """ + Wait until the TCP connection is closed or ``self.close_timeout`` elapses. + + Return :obj:`True` if the connection is closed and :obj:`False` + otherwise. + + """ + if not self.connection_lost_waiter.done(): + try: + async with asyncio_timeout(self.close_timeout): + await asyncio.shield(self.connection_lost_waiter) + except asyncio.TimeoutError: + pass + # Re-check self.connection_lost_waiter.done() synchronously because + # connection_lost() could run between the moment the timeout occurs + # and the moment this coroutine resumes running. + return self.connection_lost_waiter.done() + + def fail_connection( + self, + code: int = CloseCode.ABNORMAL_CLOSURE, + reason: str = "", + ) -> None: + """ + 7.1.7. Fail the WebSocket Connection + + This requires: + + 1. Stopping all processing of incoming data, which means canceling + :attr:`transfer_data_task`. The close code will be 1006 unless a + close frame was received earlier. + + 2. Sending a close frame with an appropriate code if the opening + handshake succeeded and the other side is likely to process it. + + 3. Closing the connection. :meth:`close_connection` takes care of + this once :attr:`transfer_data_task` exits after being canceled. + + (The specification describes these steps in the opposite order.) + + """ + if self.debug: + self.logger.debug("! failing connection with code %d", code) + + # Cancel transfer_data_task if the opening handshake succeeded. + # cancel() is idempotent and ignored if the task is done already. + if hasattr(self, "transfer_data_task"): + self.transfer_data_task.cancel() + + # Send a close frame when the state is OPEN (a close frame was already + # sent if it's CLOSING), except when failing the connection because of + # an error reading from or writing to the network. + # Don't send a close frame if the connection is broken. + if code != CloseCode.ABNORMAL_CLOSURE and self.state is State.OPEN: + close = Close(code, reason) + + # Write the close frame without draining the write buffer. + + # Keeping fail_connection() synchronous guarantees it can't + # get stuck and simplifies the implementation of the callers. + # Not drainig the write buffer is acceptable in this context. + + # This duplicates a few lines of code from write_close_frame(). + + self.state = State.CLOSING + if self.debug: + self.logger.debug("= connection is CLOSING") + + # If self.close_rcvd was set, the connection state would be + # CLOSING. Therefore self.close_rcvd isn't set and we don't + # have to set self.close_rcvd_then_sent. + assert self.close_rcvd is None + self.close_sent = close + + self.write_frame_sync(True, OP_CLOSE, close.serialize()) + + # Start close_connection_task if the opening handshake didn't succeed. + if not hasattr(self, "close_connection_task"): + self.close_connection_task = self.loop.create_task(self.close_connection()) + + def abort_pings(self) -> None: + """ + Raise ConnectionClosed in pending keepalive pings. + + They'll never receive a pong once the connection is closed. + + """ + assert self.state is State.CLOSED + exc = self.connection_closed_exc() + + for pong_waiter, _ping_timestamp in self.pings.values(): + pong_waiter.set_exception(exc) + # If the exception is never retrieved, it will be logged when ping + # is garbage-collected. This is confusing for users. + # Given that ping is done (with an exception), canceling it does + # nothing, but it prevents logging the exception. + pong_waiter.cancel() + + # asyncio.Protocol methods + + def connection_made(self, transport: asyncio.BaseTransport) -> None: + """ + Configure write buffer limits. + + The high-water limit is defined by ``self.write_limit``. + + The low-water limit currently defaults to ``self.write_limit // 4`` in + :meth:`~asyncio.WriteTransport.set_write_buffer_limits`, which should + be all right for reasonable use cases of this library. + + This is the earliest point where we can get hold of the transport, + which means it's the best point for configuring it. + + """ + transport = cast(asyncio.Transport, transport) + transport.set_write_buffer_limits(self.write_limit) + self.transport = transport + + # Copied from asyncio.StreamReaderProtocol + self.reader.set_transport(transport) + + def connection_lost(self, exc: Exception | None) -> None: + """ + 7.1.4. The WebSocket Connection is Closed. + + """ + self.state = State.CLOSED + if self.debug: + self.logger.debug("= connection is CLOSED") + + self.abort_pings() + + # If self.connection_lost_waiter isn't pending, that's a bug, because: + # - it's set only here in connection_lost() which is called only once; + # - it must never be canceled. + self.connection_lost_waiter.set_result(None) + + if True: # pragma: no cover + # Copied from asyncio.StreamReaderProtocol + if self.reader is not None: + if exc is None: + self.reader.feed_eof() + else: + self.reader.set_exception(exc) + + # Copied from asyncio.FlowControlMixin + # Wake up the writer if currently paused. + if not self._paused: + return + waiter = self._drain_waiter + if waiter is None: + return + self._drain_waiter = None + if waiter.done(): + return + if exc is None: + waiter.set_result(None) + else: + waiter.set_exception(exc) + + def pause_writing(self) -> None: # pragma: no cover + assert not self._paused + self._paused = True + + def resume_writing(self) -> None: # pragma: no cover + assert self._paused + self._paused = False + + waiter = self._drain_waiter + if waiter is not None: + self._drain_waiter = None + if not waiter.done(): + waiter.set_result(None) + + def data_received(self, data: bytes) -> None: + self.reader.feed_data(data) + + def eof_received(self) -> None: + """ + Close the transport after receiving EOF. + + The WebSocket protocol has its own closing handshake: endpoints close + the TCP or TLS connection after sending and receiving a close frame. + + As a consequence, they never need to write after receiving EOF, so + there's no reason to keep the transport open by returning :obj:`True`. + + Besides, that doesn't work on TLS connections. + + """ + self.reader.feed_eof() + + +# broadcast() is defined in the protocol module even though it's primarily +# used by servers and documented in the server module because it works with +# client connections too and because it's easier to test together with the +# WebSocketCommonProtocol class. + + +def broadcast( + websockets: Iterable[WebSocketCommonProtocol], + message: DataLike, + raise_exceptions: bool = False, +) -> None: + """ + Broadcast a message to several WebSocket connections. + + A string (:class:`str`) is sent as a Text_ frame. A bytestring or bytes-like + object (:class:`bytes`, :class:`bytearray`, or :class:`memoryview`) is sent + as a Binary_ frame. + + .. _Text: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6 + .. _Binary: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6 + + :func:`broadcast` pushes the message synchronously to all connections even + if their write buffers are overflowing. There's no backpressure. + + If you broadcast messages faster than a connection can handle them, messages + will pile up in its write buffer until the connection times out. Keep + ``ping_interval`` and ``ping_timeout`` low to prevent excessive memory usage + from slow connections. + + Unlike :meth:`~websockets.legacy.protocol.WebSocketCommonProtocol.send`, + :func:`broadcast` doesn't support sending fragmented messages. Indeed, + fragmentation is useful for sending large messages without buffering them in + memory, while :func:`broadcast` buffers one copy per connection as fast as + possible. + + :func:`broadcast` skips connections that aren't open in order to avoid + errors on connections where the closing handshake is in progress. + + :func:`broadcast` ignores failures to write the message on some connections. + It continues writing to other connections. On Python 3.11 and above, you may + set ``raise_exceptions`` to :obj:`True` to record failures and raise all + exceptions in a :pep:`654` :exc:`ExceptionGroup`. + + While :func:`broadcast` makes more sense for servers, it works identically + with clients, if you have a use case for opening connections to many servers + and broadcasting a message to them. + + Args: + websockets: WebSocket connections to which the message will be sent. + message: Message to send. + raise_exceptions: Whether to raise an exception in case of failures. + + Raises: + TypeError: If ``message`` doesn't have a supported type. + + """ + if not isinstance(message, (str, bytes, bytearray, memoryview)): + raise TypeError("data must be str or bytes-like") + + if raise_exceptions: + if sys.version_info[:2] < (3, 11): # pragma: no cover + raise ValueError("raise_exceptions requires at least Python 3.11") + exceptions = [] + + opcode, data = prepare_data(message) + + for websocket in websockets: + if websocket.state is not State.OPEN: + continue + + if websocket._fragmented_message_waiter is not None: + if raise_exceptions: + exception = RuntimeError("sending a fragmented message") + exceptions.append(exception) + else: + websocket.logger.warning( + "skipped broadcast: sending a fragmented message", + ) + continue + + try: + websocket.write_frame_sync(True, opcode, data) + except Exception as write_exception: + if raise_exceptions: + exception = RuntimeError("failed to write message") + exception.__cause__ = write_exception + exceptions.append(exception) + else: + websocket.logger.warning( + "skipped broadcast: failed to write message: %s", + traceback.format_exception_only(write_exception)[0].strip(), + ) + + if raise_exceptions and exceptions: + raise ExceptionGroup("skipped broadcast", exceptions) + + +# Pretend that broadcast is actually defined in the server module. +broadcast.__module__ = "websockets.legacy.server" diff --git a/.venv/Lib/site-packages/websockets/legacy/server.py b/.venv/Lib/site-packages/websockets/legacy/server.py new file mode 100644 index 0000000000000000000000000000000000000000..9f5feaca8514b84432d9b05e064012ac0ebee357 --- /dev/null +++ b/.venv/Lib/site-packages/websockets/legacy/server.py @@ -0,0 +1,1191 @@ +from __future__ import annotations + +import asyncio +import email.utils +import functools +import http +import inspect +import logging +import socket +import warnings +from collections.abc import Awaitable, Generator, Iterable, Sequence +from types import TracebackType +from typing import Any, Callable, cast + +from ..asyncio.compatibility import asyncio_timeout +from ..datastructures import Headers, HeadersLike, MultipleValuesError +from ..exceptions import ( + InvalidHandshake, + InvalidHeader, + InvalidMessage, + InvalidOrigin, + InvalidUpgrade, + NegotiationError, +) +from ..extensions import Extension, ServerExtensionFactory +from ..extensions.permessage_deflate import enable_server_permessage_deflate +from ..headers import ( + build_extension, + parse_extension, + parse_subprotocol, + validate_subprotocols, +) +from ..http11 import SERVER +from ..protocol import State +from ..typing import ExtensionHeader, LoggerLike, Origin, StatusLike, Subprotocol +from .exceptions import AbortHandshake +from .handshake import build_response, check_request +from .http import read_request +from .protocol import WebSocketCommonProtocol, broadcast + + +__all__ = [ + "broadcast", + "serve", + "unix_serve", + "WebSocketServerProtocol", + "WebSocketServer", +] + + +HeadersLikeOrCallable = HeadersLike | Callable[[str, Headers], HeadersLike] + +HTTPResponse = tuple[StatusLike, HeadersLike, bytes] + + +class WebSocketServerProtocol(WebSocketCommonProtocol): + """ + WebSocket server connection. + + :class:`WebSocketServerProtocol` provides :meth:`recv` and :meth:`send` + coroutines for receiving and sending messages. + + It supports asynchronous iteration to receive messages:: + + async for message in websocket: + await process(message) + + The iterator exits normally when the connection is closed with close code + 1000 (OK) or 1001 (going away) or without a close code. It raises + a :exc:`~websockets.exceptions.ConnectionClosedError` when the connection + is closed with any other code. + + You may customize the opening handshake in a subclass by + overriding :meth:`process_request` or :meth:`select_subprotocol`. + + Args: + ws_server: WebSocket server that created this connection. + + See :func:`serve` for the documentation of ``ws_handler``, ``logger``, ``origins``, + ``extensions``, ``subprotocols``, ``extra_headers``, and ``server_header``. + + See :class:`~websockets.legacy.protocol.WebSocketCommonProtocol` for the + documentation of ``ping_interval``, ``ping_timeout``, ``close_timeout``, + ``max_size``, ``max_queue``, ``read_limit``, and ``write_limit``. + + """ + + is_client = False + side = "server" + + def __init__( + self, + # The version that accepts the path in the second argument is deprecated. + ws_handler: ( + Callable[[WebSocketServerProtocol], Awaitable[Any]] + | Callable[[WebSocketServerProtocol, str], Awaitable[Any]] + ), + ws_server: WebSocketServer, + *, + logger: LoggerLike | None = None, + origins: Sequence[Origin | None] | None = None, + extensions: Sequence[ServerExtensionFactory] | None = None, + subprotocols: Sequence[Subprotocol] | None = None, + extra_headers: HeadersLikeOrCallable | None = None, + server_header: str | None = SERVER, + process_request: ( + Callable[[str, Headers], Awaitable[HTTPResponse | None]] | None + ) = None, + select_subprotocol: ( + Callable[[Sequence[Subprotocol], Sequence[Subprotocol]], Subprotocol] | None + ) = None, + open_timeout: float | None = 10, + **kwargs: Any, + ) -> None: + if logger is None: + logger = logging.getLogger("websockets.server") + super().__init__(logger=logger, **kwargs) + # For backwards compatibility with 6.0 or earlier. + if origins is not None and "" in origins: + warnings.warn("use None instead of '' in origins", DeprecationWarning) + origins = [None if origin == "" else origin for origin in origins] + # For backwards compatibility with 10.0 or earlier. Done here in + # addition to serve to trigger the deprecation warning on direct + # use of WebSocketServerProtocol. + self.ws_handler = remove_path_argument(ws_handler) + self.ws_server = ws_server + self.origins = origins + self.available_extensions = extensions + self.available_subprotocols = subprotocols + self.extra_headers = extra_headers + self.server_header = server_header + self._process_request = process_request + self._select_subprotocol = select_subprotocol + self.open_timeout = open_timeout + + def connection_made(self, transport: asyncio.BaseTransport) -> None: + """ + Register connection and initialize a task to handle it. + + """ + super().connection_made(transport) + # Register the connection with the server before creating the handler + # task. Registering at the beginning of the handler coroutine would + # create a race condition between the creation of the task, which + # schedules its execution, and the moment the handler starts running. + self.ws_server.register(self) + self.handler_task = self.loop.create_task(self.handler()) + + async def handler(self) -> None: + """ + Handle the lifecycle of a WebSocket connection. + + Since this method doesn't have a caller able to handle exceptions, it + attempts to log relevant ones and guarantees that the TCP connection is + closed before exiting. + + """ + try: + try: + async with asyncio_timeout(self.open_timeout): + await self.handshake( + origins=self.origins, + available_extensions=self.available_extensions, + available_subprotocols=self.available_subprotocols, + extra_headers=self.extra_headers, + ) + except asyncio.TimeoutError: # pragma: no cover + raise + except ConnectionError: + raise + except Exception as exc: + if isinstance(exc, AbortHandshake): + status, headers, body = exc.status, exc.headers, exc.body + elif isinstance(exc, InvalidOrigin): + if self.debug: + self.logger.debug("! invalid origin", exc_info=True) + status, headers, body = ( + http.HTTPStatus.FORBIDDEN, + Headers(), + f"Failed to open a WebSocket connection: {exc}.\n".encode(), + ) + elif isinstance(exc, InvalidUpgrade): + if self.debug: + self.logger.debug("! invalid upgrade", exc_info=True) + status, headers, body = ( + http.HTTPStatus.UPGRADE_REQUIRED, + Headers([("Upgrade", "websocket")]), + ( + f"Failed to open a WebSocket connection: {exc}.\n" + f"\n" + f"You cannot access a WebSocket server directly " + f"with a browser. You need a WebSocket client.\n" + ).encode(), + ) + elif isinstance(exc, InvalidHandshake): + if self.debug: + self.logger.debug("! invalid handshake", exc_info=True) + exc_chain = cast(BaseException, exc) + exc_str = f"{exc_chain}" + while exc_chain.__cause__ is not None: + exc_chain = exc_chain.__cause__ + exc_str += f"; {exc_chain}" + status, headers, body = ( + http.HTTPStatus.BAD_REQUEST, + Headers(), + f"Failed to open a WebSocket connection: {exc_str}.\n".encode(), + ) + else: + self.logger.error("opening handshake failed", exc_info=True) + status, headers, body = ( + http.HTTPStatus.INTERNAL_SERVER_ERROR, + Headers(), + ( + b"Failed to open a WebSocket connection.\n" + b"See server log for more information.\n" + ), + ) + + headers.setdefault("Date", email.utils.formatdate(usegmt=True)) + if self.server_header: + headers.setdefault("Server", self.server_header) + + headers.setdefault("Content-Length", str(len(body))) + headers.setdefault("Content-Type", "text/plain") + headers.setdefault("Connection", "close") + + self.write_http_response(status, headers, body) + self.logger.info( + "connection rejected (%d %s)", status.value, status.phrase + ) + await self.close_transport() + return + + try: + await self.ws_handler(self) + except Exception: + self.logger.error("connection handler failed", exc_info=True) + if not self.closed: + self.fail_connection(1011) + raise + + try: + await self.close() + except ConnectionError: + raise + except Exception: + self.logger.error("closing handshake failed", exc_info=True) + raise + + except Exception: + # Last-ditch attempt to avoid leaking connections on errors. + try: + self.transport.close() + except Exception: # pragma: no cover + pass + + finally: + # Unregister the connection with the server when the handler task + # terminates. Registration is tied to the lifecycle of the handler + # task because the server waits for tasks attached to registered + # connections before terminating. + self.ws_server.unregister(self) + self.logger.info("connection closed") + + async def read_http_request(self) -> tuple[str, Headers]: + """ + Read request line and headers from the HTTP request. + + If the request contains a body, it may be read from ``self.reader`` + after this coroutine returns. + + Raises: + InvalidMessage: If the HTTP message is malformed or isn't an + HTTP/1.1 GET request. + + """ + try: + path, headers = await read_request(self.reader) + except asyncio.CancelledError: # pragma: no cover + raise + except Exception as exc: + raise InvalidMessage("did not receive a valid HTTP request") from exc + + if self.debug: + self.logger.debug("< GET %s HTTP/1.1", path) + for key, value in headers.raw_items(): + self.logger.debug("< %s: %s", key, value) + + self.path = path + self.request_headers = headers + + return path, headers + + def write_http_response( + self, status: http.HTTPStatus, headers: Headers, body: bytes | None = None + ) -> None: + """ + Write status line and headers to the HTTP response. + + This coroutine is also able to write a response body. + + """ + self.response_headers = headers + + if self.debug: + self.logger.debug("> HTTP/1.1 %d %s", status.value, status.phrase) + for key, value in headers.raw_items(): + self.logger.debug("> %s: %s", key, value) + if body is not None: + self.logger.debug("> [body] (%d bytes)", len(body)) + + # Since the status line and headers only contain ASCII characters, + # we can keep this simple. + response = f"HTTP/1.1 {status.value} {status.phrase}\r\n" + response += str(headers) + + self.transport.write(response.encode()) + + if body is not None: + self.transport.write(body) + + async def process_request( + self, path: str, request_headers: Headers + ) -> HTTPResponse | None: + """ + Intercept the HTTP request and return an HTTP response if appropriate. + + You may override this method in a :class:`WebSocketServerProtocol` + subclass, for example: + + * to return an HTTP 200 OK response on a given path; then a load + balancer can use this path for a health check; + * to authenticate the request and return an HTTP 401 Unauthorized or an + HTTP 403 Forbidden when authentication fails. + + You may also override this method with the ``process_request`` + argument of :func:`serve` and :class:`WebSocketServerProtocol`. This + is equivalent, except ``process_request`` won't have access to the + protocol instance, so it can't store information for later use. + + :meth:`process_request` is expected to complete quickly. If it may run + for a long time, then it should await :meth:`wait_closed` and exit if + :meth:`wait_closed` completes, or else it could prevent the server + from shutting down. + + Args: + path: Request path, including optional query string. + request_headers: Request headers. + + Returns: + tuple[StatusLike, HeadersLike, bytes] | None: :obj:`None` to + continue the WebSocket handshake normally. + + An HTTP response, represented by a 3-uple of the response status, + headers, and body, to abort the WebSocket handshake and return + that HTTP response instead. + + """ + if self._process_request is not None: + response = self._process_request(path, request_headers) + if isinstance(response, Awaitable): + return await response + else: + # For backwards compatibility with 7.0. + warnings.warn( + "declare process_request as a coroutine", DeprecationWarning + ) + return response + return None + + @staticmethod + def process_origin( + headers: Headers, origins: Sequence[Origin | None] | None = None + ) -> Origin | None: + """ + Handle the Origin HTTP request header. + + Args: + headers: Request headers. + origins: Optional list of acceptable origins. + + Raises: + InvalidOrigin: If the origin isn't acceptable. + + """ + # "The user agent MUST NOT include more than one Origin header field" + # per https://datatracker.ietf.org/doc/html/rfc6454#section-7.3. + try: + origin = headers.get("Origin") + except MultipleValuesError as exc: + raise InvalidHeader("Origin", "multiple values") from exc + if origin is not None: + origin = cast(Origin, origin) + if origins is not None: + if origin not in origins: + raise InvalidOrigin(origin) + return origin + + @staticmethod + def process_extensions( + headers: Headers, + available_extensions: Sequence[ServerExtensionFactory] | None, + ) -> tuple[str | None, list[Extension]]: + """ + Handle the Sec-WebSocket-Extensions HTTP request header. + + Accept or reject each extension proposed in the client request. + Negotiate parameters for accepted extensions. + + Return the Sec-WebSocket-Extensions HTTP response header and the list + of accepted extensions. + + :rfc:`6455` leaves the rules up to the specification of each + :extension. + + To provide this level of flexibility, for each extension proposed by + the client, we check for a match with each extension available in the + server configuration. If no match is found, the extension is ignored. + + If several variants of the same extension are proposed by the client, + it may be accepted several times, which won't make sense in general. + Extensions must implement their own requirements. For this purpose, + the list of previously accepted extensions is provided. + + This process doesn't allow the server to reorder extensions. It can + only select a subset of the extensions proposed by the client. + + Other requirements, for example related to mandatory extensions or the + order of extensions, may be implemented by overriding this method. + + Args: + headers: Request headers. + extensions: Optional list of supported extensions. + + Raises: + InvalidHandshake: To abort the handshake with an HTTP 400 error. + + """ + response_header_value: str | None = None + + extension_headers: list[ExtensionHeader] = [] + accepted_extensions: list[Extension] = [] + + header_values = headers.get_all("Sec-WebSocket-Extensions") + + if header_values and available_extensions: + parsed_header_values: list[ExtensionHeader] = sum( + [parse_extension(header_value) for header_value in header_values], [] + ) + + for name, request_params in parsed_header_values: + for ext_factory in available_extensions: + # Skip non-matching extensions based on their name. + if ext_factory.name != name: + continue + + # Skip non-matching extensions based on their params. + try: + response_params, extension = ext_factory.process_request_params( + request_params, accepted_extensions + ) + except NegotiationError: + continue + + # Add matching extension to the final list. + extension_headers.append((name, response_params)) + accepted_extensions.append(extension) + + # Break out of the loop once we have a match. + break + + # If we didn't break from the loop, no extension in our list + # matched what the client sent. The extension is declined. + + # Serialize extension header. + if extension_headers: + response_header_value = build_extension(extension_headers) + + return response_header_value, accepted_extensions + + # Not @staticmethod because it calls self.select_subprotocol() + def process_subprotocol( + self, headers: Headers, available_subprotocols: Sequence[Subprotocol] | None + ) -> Subprotocol | None: + """ + Handle the Sec-WebSocket-Protocol HTTP request header. + + Return Sec-WebSocket-Protocol HTTP response header, which is the same + as the selected subprotocol. + + Args: + headers: Request headers. + available_subprotocols: Optional list of supported subprotocols. + + Raises: + InvalidHandshake: To abort the handshake with an HTTP 400 error. + + """ + subprotocol: Subprotocol | None = None + + header_values = headers.get_all("Sec-WebSocket-Protocol") + + if header_values and available_subprotocols: + parsed_header_values: list[Subprotocol] = sum( + [parse_subprotocol(header_value) for header_value in header_values], [] + ) + + subprotocol = self.select_subprotocol( + parsed_header_values, available_subprotocols + ) + + return subprotocol + + def select_subprotocol( + self, + client_subprotocols: Sequence[Subprotocol], + server_subprotocols: Sequence[Subprotocol], + ) -> Subprotocol | None: + """ + Pick a subprotocol among those supported by the client and the server. + + If several subprotocols are available, select the preferred subprotocol + by giving equal weight to the preferences of the client and the server. + + If no subprotocol is available, proceed without a subprotocol. + + You may provide a ``select_subprotocol`` argument to :func:`serve` or + :class:`WebSocketServerProtocol` to override this logic. For example, + you could reject the handshake if the client doesn't support a + particular subprotocol, rather than accept the handshake without that + subprotocol. + + Args: + client_subprotocols: List of subprotocols offered by the client. + server_subprotocols: List of subprotocols available on the server. + + Returns: + Selected subprotocol, if a common subprotocol was found. + + :obj:`None` to continue without a subprotocol. + + """ + if self._select_subprotocol is not None: + return self._select_subprotocol(client_subprotocols, server_subprotocols) + + subprotocols = set(client_subprotocols) & set(server_subprotocols) + if not subprotocols: + return None + return sorted( + subprotocols, + key=lambda p: client_subprotocols.index(p) + server_subprotocols.index(p), + )[0] + + async def handshake( + self, + origins: Sequence[Origin | None] | None = None, + available_extensions: Sequence[ServerExtensionFactory] | None = None, + available_subprotocols: Sequence[Subprotocol] | None = None, + extra_headers: HeadersLikeOrCallable | None = None, + ) -> str: + """ + Perform the server side of the opening handshake. + + Args: + origins: List of acceptable values of the Origin HTTP header; + include :obj:`None` if the lack of an origin is acceptable. + extensions: List of supported extensions, in order in which they + should be tried. + subprotocols: List of supported subprotocols, in order of + decreasing preference. + extra_headers: Arbitrary HTTP headers to add to the response when + the handshake succeeds. + + Returns: + path of the URI of the request. + + Raises: + InvalidHandshake: If the handshake fails. + + """ + path, request_headers = await self.read_http_request() + + # Hook for customizing request handling, for example checking + # authentication or treating some paths as plain HTTP endpoints. + early_response_awaitable = self.process_request(path, request_headers) + if isinstance(early_response_awaitable, Awaitable): + early_response = await early_response_awaitable + else: + # For backwards compatibility with 7.0. + warnings.warn("declare process_request as a coroutine", DeprecationWarning) + early_response = early_response_awaitable + + # The connection may drop while process_request is running. + if self.state is State.CLOSED: + # This subclass of ConnectionError is silently ignored in handler(). + raise BrokenPipeError("connection closed during opening handshake") + + # Change the response to a 503 error if the server is shutting down. + if not self.ws_server.is_serving(): + early_response = ( + http.HTTPStatus.SERVICE_UNAVAILABLE, + [], + b"Server is shutting down.\n", + ) + + if early_response is not None: + raise AbortHandshake(*early_response) + + key = check_request(request_headers) + + self.origin = self.process_origin(request_headers, origins) + + extensions_header, self.extensions = self.process_extensions( + request_headers, available_extensions + ) + + protocol_header = self.subprotocol = self.process_subprotocol( + request_headers, available_subprotocols + ) + + response_headers = Headers() + + build_response(response_headers, key) + + if extensions_header is not None: + response_headers["Sec-WebSocket-Extensions"] = extensions_header + + if protocol_header is not None: + response_headers["Sec-WebSocket-Protocol"] = protocol_header + + if callable(extra_headers): + extra_headers = extra_headers(path, self.request_headers) + if extra_headers is not None: + response_headers.update(extra_headers) + + response_headers.setdefault("Date", email.utils.formatdate(usegmt=True)) + if self.server_header is not None: + response_headers.setdefault("Server", self.server_header) + + self.write_http_response(http.HTTPStatus.SWITCHING_PROTOCOLS, response_headers) + + self.logger.info("connection open") + + self.connection_open() + + return path + + +class WebSocketServer: + """ + WebSocket server returned by :func:`serve`. + + This class mirrors the API of :class:`~asyncio.Server`. + + It keeps track of WebSocket connections in order to close them properly + when shutting down. + + Args: + logger: Logger for this server. + It defaults to ``logging.getLogger("websockets.server")``. + See the :doc:`logging guide <../../topics/logging>` for details. + + """ + + def __init__(self, logger: LoggerLike | None = None) -> None: + if logger is None: + logger = logging.getLogger("websockets.server") + self.logger = logger + + # Keep track of active connections. + self.websockets: set[WebSocketServerProtocol] = set() + + # Task responsible for closing the server and terminating connections. + self.close_task: asyncio.Task[None] | None = None + + # Completed when the server is closed and connections are terminated. + self.closed_waiter: asyncio.Future[None] + + def wrap(self, server: asyncio.base_events.Server) -> None: + """ + Attach to a given :class:`~asyncio.Server`. + + Since :meth:`~asyncio.loop.create_server` doesn't support injecting a + custom ``Server`` class, the easiest solution that doesn't rely on + private :mod:`asyncio` APIs is to: + + - instantiate a :class:`WebSocketServer` + - give the protocol factory a reference to that instance + - call :meth:`~asyncio.loop.create_server` with the factory + - attach the resulting :class:`~asyncio.Server` with this method + + """ + self.server = server + for sock in server.sockets: + if sock.family == socket.AF_INET: + name = "%s:%d" % sock.getsockname() + elif sock.family == socket.AF_INET6: + name = "[%s]:%d" % sock.getsockname()[:2] + elif sock.family == socket.AF_UNIX: + name = sock.getsockname() + # In the unlikely event that someone runs websockets over a + # protocol other than IP or Unix sockets, avoid crashing. + else: # pragma: no cover + name = str(sock.getsockname()) + self.logger.info("server listening on %s", name) + + # Initialized here because we need a reference to the event loop. + # This could be moved back to __init__ now that Python < 3.10 isn't + # supported anymore, but I'm not taking that risk in legacy code. + self.closed_waiter = server.get_loop().create_future() + + def register(self, protocol: WebSocketServerProtocol) -> None: + """ + Register a connection with this server. + + """ + self.websockets.add(protocol) + + def unregister(self, protocol: WebSocketServerProtocol) -> None: + """ + Unregister a connection with this server. + + """ + self.websockets.remove(protocol) + + def close(self, close_connections: bool = True) -> None: + """ + Close the server. + + * Close the underlying :class:`~asyncio.Server`. + * When ``close_connections`` is :obj:`True`, which is the default, + close existing connections. Specifically: + + * Reject opening WebSocket connections with an HTTP 503 (service + unavailable) error. This happens when the server accepted the TCP + connection but didn't complete the opening handshake before closing. + * Close open WebSocket connections with close code 1001 (going away). + + * Wait until all connection handlers terminate. + + :meth:`close` is idempotent. + + """ + if self.close_task is None: + self.close_task = self.get_loop().create_task( + self._close(close_connections) + ) + + async def _close(self, close_connections: bool) -> None: + """ + Implementation of :meth:`close`. + + This calls :meth:`~asyncio.Server.close` on the underlying + :class:`~asyncio.Server` object to stop accepting new connections and + then closes open connections with close code 1001. + + """ + self.logger.info("server closing") + + # Stop accepting new connections. + self.server.close() + + # Wait until all accepted connections reach connection_made() and call + # register(). See https://github.com/python/cpython/issues/79033 for + # details. This workaround can be removed when dropping Python < 3.11. + await asyncio.sleep(0) + + if close_connections: + # Close OPEN connections with close code 1001. After server.close(), + # handshake() closes OPENING connections with an HTTP 503 error. + close_tasks = [ + asyncio.create_task(websocket.close(1001)) + for websocket in self.websockets + if websocket.state is not State.CONNECTING + ] + # asyncio.wait doesn't accept an empty first argument. + if close_tasks: + await asyncio.wait(close_tasks) + + # Wait until all TCP connections are closed. + await self.server.wait_closed() + + # Wait until all connection handlers terminate. + # asyncio.wait doesn't accept an empty first argument. + if self.websockets: + await asyncio.wait( + [websocket.handler_task for websocket in self.websockets] + ) + + # Tell wait_closed() to return. + self.closed_waiter.set_result(None) + + self.logger.info("server closed") + + async def wait_closed(self) -> None: + """ + Wait until the server is closed. + + When :meth:`wait_closed` returns, all TCP connections are closed and + all connection handlers have returned. + + To ensure a fast shutdown, a connection handler should always be + awaiting at least one of: + + * :meth:`~WebSocketServerProtocol.recv`: when the connection is closed, + it raises :exc:`~websockets.exceptions.ConnectionClosedOK`; + * :meth:`~WebSocketServerProtocol.wait_closed`: when the connection is + closed, it returns. + + Then the connection handler is immediately notified of the shutdown; + it can clean up and exit. + + """ + await asyncio.shield(self.closed_waiter) + + def get_loop(self) -> asyncio.AbstractEventLoop: + """ + See :meth:`asyncio.Server.get_loop`. + + """ + return self.server.get_loop() + + def is_serving(self) -> bool: + """ + See :meth:`asyncio.Server.is_serving`. + + """ + return self.server.is_serving() + + async def start_serving(self) -> None: # pragma: no cover + """ + See :meth:`asyncio.Server.start_serving`. + + Typical use:: + + server = await serve(..., start_serving=False) + # perform additional setup here... + # ... then start the server + await server.start_serving() + + """ + await self.server.start_serving() + + async def serve_forever(self) -> None: # pragma: no cover + """ + See :meth:`asyncio.Server.serve_forever`. + + Typical use:: + + server = await serve(...) + # this coroutine doesn't return + # canceling it stops the server + await server.serve_forever() + + This is an alternative to using :func:`serve` as an asynchronous context + manager. Shutdown is triggered by canceling :meth:`serve_forever` + instead of exiting a :func:`serve` context. + + """ + await self.server.serve_forever() + + @property + def sockets(self) -> Iterable[socket.socket]: + """ + See :attr:`asyncio.Server.sockets`. + + """ + return self.server.sockets + + async def __aenter__(self) -> WebSocketServer: # pragma: no cover + return self + + async def __aexit__( + self, + exc_type: type[BaseException] | None, + exc_value: BaseException | None, + traceback: TracebackType | None, + ) -> None: # pragma: no cover + self.close() + await self.wait_closed() + + +class Serve: + """ + Start a WebSocket server listening on ``host`` and ``port``. + + Whenever a client connects, the server creates a + :class:`WebSocketServerProtocol`, performs the opening handshake, and + delegates to the connection handler, ``ws_handler``. + + The handler receives the :class:`WebSocketServerProtocol` and uses it to + send and receive messages. + + Once the handler completes, either normally or with an exception, the + server performs the closing handshake and closes the connection. + + Awaiting :func:`serve` yields a :class:`WebSocketServer`. This object + provides a :meth:`~WebSocketServer.close` method to shut down the server:: + + # set this future to exit the server + stop = asyncio.get_running_loop().create_future() + + server = await serve(...) + await stop + server.close() + await server.wait_closed() + + :func:`serve` can be used as an asynchronous context manager. Then, the + server is shut down automatically when exiting the context:: + + # set this future to exit the server + stop = asyncio.get_running_loop().create_future() + + async with serve(...): + await stop + + Args: + ws_handler: Connection handler. It receives the WebSocket connection, + which is a :class:`WebSocketServerProtocol`, in argument. + host: Network interfaces the server binds to. + See :meth:`~asyncio.loop.create_server` for details. + port: TCP port the server listens on. + See :meth:`~asyncio.loop.create_server` for details. + create_protocol: Factory for the :class:`asyncio.Protocol` managing + the connection. It defaults to :class:`WebSocketServerProtocol`. + Set it to a wrapper or a subclass to customize connection handling. + logger: Logger for this server. + It defaults to ``logging.getLogger("websockets.server")``. + See the :doc:`logging guide <../../topics/logging>` for details. + compression: The "permessage-deflate" extension is enabled by default. + Set ``compression`` to :obj:`None` to disable it. See the + :doc:`compression guide <../../topics/compression>` for details. + origins: Acceptable values of the ``Origin`` header, for defending + against Cross-Site WebSocket Hijacking attacks. Include :obj:`None` + in the list if the lack of an origin is acceptable. + extensions: List of supported extensions, in order in which they + should be negotiated and run. + subprotocols: List of supported subprotocols, in order of decreasing + preference. + extra_headers (HeadersLike | Callable[[str, Headers] | HeadersLike]): + Arbitrary HTTP headers to add to the response. This can be + a :data:`~websockets.datastructures.HeadersLike` or a callable + taking the request path and headers in arguments and returning + a :data:`~websockets.datastructures.HeadersLike`. + server_header: Value of the ``Server`` response header. + It defaults to ``"Python/x.y.z websockets/X.Y"``. + Setting it to :obj:`None` removes the header. + process_request (Callable[[str, Headers], \ + Awaitable[tuple[StatusLike, HeadersLike, bytes] | None]] | None): + Intercept HTTP request before the opening handshake. + See :meth:`~WebSocketServerProtocol.process_request` for details. + select_subprotocol: Select a subprotocol supported by the client. + See :meth:`~WebSocketServerProtocol.select_subprotocol` for details. + open_timeout: Timeout for opening connections in seconds. + :obj:`None` disables the timeout. + + See :class:`~websockets.legacy.protocol.WebSocketCommonProtocol` for the + documentation of ``ping_interval``, ``ping_timeout``, ``close_timeout``, + ``max_size``, ``max_queue``, ``read_limit``, and ``write_limit``. + + Any other keyword arguments are passed the event loop's + :meth:`~asyncio.loop.create_server` method. + + For example: + + * You can set ``ssl`` to a :class:`~ssl.SSLContext` to enable TLS. + + * You can set ``sock`` to a :obj:`~socket.socket` that you created + outside of websockets. + + Returns: + WebSocket server. + + """ + + def __init__( + self, + # The version that accepts the path in the second argument is deprecated. + ws_handler: ( + Callable[[WebSocketServerProtocol], Awaitable[Any]] + | Callable[[WebSocketServerProtocol, str], Awaitable[Any]] + ), + host: str | Sequence[str] | None = None, + port: int | None = None, + *, + create_protocol: Callable[..., WebSocketServerProtocol] | None = None, + logger: LoggerLike | None = None, + compression: str | None = "deflate", + origins: Sequence[Origin | None] | None = None, + extensions: Sequence[ServerExtensionFactory] | None = None, + subprotocols: Sequence[Subprotocol] | None = None, + extra_headers: HeadersLikeOrCallable | None = None, + server_header: str | None = SERVER, + process_request: ( + Callable[[str, Headers], Awaitable[HTTPResponse | None]] | None + ) = None, + select_subprotocol: ( + Callable[[Sequence[Subprotocol], Sequence[Subprotocol]], Subprotocol] | None + ) = None, + open_timeout: float | None = 10, + ping_interval: float | None = 20, + ping_timeout: float | None = 20, + close_timeout: float | None = None, + max_size: int | None = 2**20, + max_queue: int | None = 2**5, + read_limit: int = 2**16, + write_limit: int = 2**16, + **kwargs: Any, + ) -> None: + # Backwards compatibility: close_timeout used to be called timeout. + timeout: float | None = kwargs.pop("timeout", None) + if timeout is None: + timeout = 10 + else: + warnings.warn("rename timeout to close_timeout", DeprecationWarning) + # If both are specified, timeout is ignored. + if close_timeout is None: + close_timeout = timeout + + # Backwards compatibility: create_protocol used to be called klass. + klass: type[WebSocketServerProtocol] | None = kwargs.pop("klass", None) + if klass is None: + klass = WebSocketServerProtocol + else: + warnings.warn("rename klass to create_protocol", DeprecationWarning) + # If both are specified, klass is ignored. + if create_protocol is None: + create_protocol = klass + + # Backwards compatibility: recv() used to return None on closed connections + legacy_recv: bool = kwargs.pop("legacy_recv", False) + + # Backwards compatibility: the loop parameter used to be supported. + _loop: asyncio.AbstractEventLoop | None = kwargs.pop("loop", None) + if _loop is None: + loop = asyncio.get_event_loop() + else: + loop = _loop + warnings.warn("remove loop argument", DeprecationWarning) + + ws_server = WebSocketServer(logger=logger) + + secure = kwargs.get("ssl") is not None + + if compression == "deflate": + extensions = enable_server_permessage_deflate(extensions) + elif compression is not None: + raise ValueError(f"unsupported compression: {compression}") + + if subprotocols is not None: + validate_subprotocols(subprotocols) + + # Help mypy and avoid this error: "type[WebSocketServerProtocol] | + # Callable[..., WebSocketServerProtocol]" not callable [misc] + create_protocol = cast(Callable[..., WebSocketServerProtocol], create_protocol) + factory = functools.partial( + create_protocol, + # For backwards compatibility with 10.0 or earlier. Done here in + # addition to WebSocketServerProtocol to trigger the deprecation + # warning once per serve() call rather than once per connection. + remove_path_argument(ws_handler), + ws_server, + host=host, + port=port, + secure=secure, + open_timeout=open_timeout, + ping_interval=ping_interval, + ping_timeout=ping_timeout, + close_timeout=close_timeout, + max_size=max_size, + max_queue=max_queue, + read_limit=read_limit, + write_limit=write_limit, + loop=_loop, + legacy_recv=legacy_recv, + origins=origins, + extensions=extensions, + subprotocols=subprotocols, + extra_headers=extra_headers, + server_header=server_header, + process_request=process_request, + select_subprotocol=select_subprotocol, + logger=logger, + ) + + if kwargs.pop("unix", False): + path: str | None = kwargs.pop("path", None) + # unix_serve(path) must not specify host and port parameters. + assert host is None and port is None + create_server = functools.partial( + loop.create_unix_server, factory, path, **kwargs + ) + else: + create_server = functools.partial( + loop.create_server, factory, host, port, **kwargs + ) + + # This is a coroutine function. + self._create_server = create_server + self.ws_server = ws_server + + # async with serve(...) + + async def __aenter__(self) -> WebSocketServer: + return await self + + async def __aexit__( + self, + exc_type: type[BaseException] | None, + exc_value: BaseException | None, + traceback: TracebackType | None, + ) -> None: + self.ws_server.close() + await self.ws_server.wait_closed() + + # await serve(...) + + def __await__(self) -> Generator[Any, None, WebSocketServer]: + # Create a suitable iterator by calling __await__ on a coroutine. + return self.__await_impl__().__await__() + + async def __await_impl__(self) -> WebSocketServer: + server = await self._create_server() + self.ws_server.wrap(server) + return self.ws_server + + # yield from serve(...) - remove when dropping Python < 3.11 + + __iter__ = __await__ + + +serve = Serve + + +def unix_serve( + # The version that accepts the path in the second argument is deprecated. + ws_handler: ( + Callable[[WebSocketServerProtocol], Awaitable[Any]] + | Callable[[WebSocketServerProtocol, str], Awaitable[Any]] + ), + path: str | None = None, + **kwargs: Any, +) -> Serve: + """ + Start a WebSocket server listening on a Unix socket. + + This function is identical to :func:`serve`, except the ``host`` and + ``port`` arguments are replaced by ``path``. It is only available on Unix. + + Unrecognized keyword arguments are passed the event loop's + :meth:`~asyncio.loop.create_unix_server` method. + + It's useful for deploying a server behind a reverse proxy such as nginx. + + Args: + path: File system path to the Unix socket. + + """ + return serve(ws_handler, path=path, unix=True, **kwargs) + + +def remove_path_argument( + ws_handler: ( + Callable[[WebSocketServerProtocol], Awaitable[Any]] + | Callable[[WebSocketServerProtocol, str], Awaitable[Any]] + ), +) -> Callable[[WebSocketServerProtocol], Awaitable[Any]]: + try: + inspect.signature(ws_handler).bind(None) + except TypeError: + try: + inspect.signature(ws_handler).bind(None, "") + except TypeError: # pragma: no cover + # ws_handler accepts neither one nor two arguments; leave it alone. + pass + else: + # ws_handler accepts two arguments; activate backwards compatibility. + warnings.warn("remove second argument of ws_handler", DeprecationWarning) + + async def _ws_handler(websocket: WebSocketServerProtocol) -> Any: + return await cast( + Callable[[WebSocketServerProtocol, str], Awaitable[Any]], + ws_handler, + )(websocket, websocket.path) + + return _ws_handler + + return cast( + Callable[[WebSocketServerProtocol], Awaitable[Any]], + ws_handler, + ) diff --git a/.venv/Lib/site-packages/websockets/protocol.py b/.venv/Lib/site-packages/websockets/protocol.py new file mode 100644 index 0000000000000000000000000000000000000000..ed47272c8d5c4635664ba49d344ce07cdb8d0096 --- /dev/null +++ b/.venv/Lib/site-packages/websockets/protocol.py @@ -0,0 +1,768 @@ +from __future__ import annotations + +import enum +import logging +import uuid +from collections.abc import Generator + +from .exceptions import ( + ConnectionClosed, + ConnectionClosedError, + ConnectionClosedOK, + InvalidState, + PayloadTooBig, + ProtocolError, +) +from .extensions import Extension +from .frames import ( + OK_CLOSE_CODES, + OP_BINARY, + OP_CLOSE, + OP_CONT, + OP_PING, + OP_PONG, + OP_TEXT, + Close, + CloseCode, + Frame, +) +from .http11 import Request, Response +from .streams import StreamReader +from .typing import BytesLike, LoggerLike, Origin, Subprotocol + + +__all__ = [ + "Protocol", + "Side", + "State", + "SEND_EOF", +] + +Event = Request | Response | Frame +"""Events that :meth:`~Protocol.events_received` may return.""" + + +class Side(enum.IntEnum): + """A WebSocket connection is either a server or a client.""" + + SERVER, CLIENT = range(2) + + +SERVER = Side.SERVER +CLIENT = Side.CLIENT + + +class State(enum.IntEnum): + """A WebSocket connection is in one of these four states.""" + + CONNECTING, OPEN, CLOSING, CLOSED = range(4) + + +CONNECTING = State.CONNECTING +OPEN = State.OPEN +CLOSING = State.CLOSING +CLOSED = State.CLOSED + + +SEND_EOF = b"" +"""Sentinel signaling that the TCP connection must be half-closed.""" + + +class Protocol: + """ + Sans-I/O implementation of a WebSocket connection. + + Args: + side: :attr:`~Side.CLIENT` or :attr:`~Side.SERVER`. + state: Initial state of the WebSocket connection. + max_size: Maximum size of incoming messages in bytes. + :obj:`None` disables the limit. You may pass a ``(max_message_size, + max_fragment_size)`` tuple to set different limits for messages and + fragments when you expect long messages sent in short fragments. + logger: Logger for this connection; depending on ``side``, + defaults to ``logging.getLogger("websockets.client")`` + or ``logging.getLogger("websockets.server")``; + see the :doc:`logging guide <../../topics/logging>` for details. + + """ + + def __init__( + self, + side: Side, + *, + state: State = OPEN, + max_size: tuple[int | None, int | None] | int | None = 2**20, + logger: LoggerLike | None = None, + ) -> None: + # Unique identifier. For logs. + self.id: uuid.UUID = uuid.uuid4() + """Unique identifier of the connection. Useful in logs.""" + + # Logger or LoggerAdapter for this connection. + if logger is None: + logger = logging.getLogger(f"websockets.{side.name.lower()}") + self.logger: LoggerLike = logger + """Logger for this connection.""" + + # Track if DEBUG is enabled. Shortcut logging calls if it isn't. + self.debug = logger.isEnabledFor(logging.DEBUG) + + # Connection side. CLIENT or SERVER. + self.side = side + + # Connection state. Initially OPEN because subclasses handle CONNECTING. + self.state = state + + # Maximum size of incoming messages in bytes. + if isinstance(max_size, int) or max_size is None: + self.max_message_size, self.max_fragment_size = max_size, None + else: + self.max_message_size, self.max_fragment_size = max_size + + # Current size of incoming message in bytes. Only set while reading a + # fragmented message i.e. a data frames with the FIN bit not set. + self.current_size: int | None = None + + # True while sending a fragmented message i.e. a data frames with the + # FIN bit not set. + self.expect_continuation_frame = False + + # WebSocket protocol parameters. + self.origin: Origin | None = None + self.extensions: list[Extension] = [] + self.subprotocol: Subprotocol | None = None + + # Close code and reason, set when a close frame is sent or received. + self.close_rcvd: Close | None = None + self.close_sent: Close | None = None + self.close_rcvd_then_sent: bool | None = None + + # Track if an exception happened during the handshake. + self.handshake_exc: Exception | None = None + """ + Exception to raise if the opening handshake failed. + + :obj:`None` if the opening handshake succeeded. + + """ + + # Track if send_eof() was called. + self.eof_sent = False + + # Parser state. + self.reader = StreamReader() + self.events: list[Event] = [] + self.writes: list[bytes] = [] + self.parser = self.parse() + next(self.parser) # start coroutine + self.parser_exc: Exception | None = None + + @property + def state(self) -> State: + """ + State of the WebSocket connection. + + Defined in 4.1_, 4.2_, 7.1.3_, and 7.1.4_ of :rfc:`6455`. + + .. _4.1: https://datatracker.ietf.org/doc/html/rfc6455#section-4.1 + .. _4.2: https://datatracker.ietf.org/doc/html/rfc6455#section-4.2 + .. _7.1.3: https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.3 + .. _7.1.4: https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.4 + + """ + return self._state + + @state.setter + def state(self, state: State) -> None: + if self.debug: + self.logger.debug("= connection is %s", state.name) + self._state = state + + @property + def close_code(self) -> int | None: + """ + WebSocket close code received from the remote endpoint. + + Defined in 7.1.5_ of :rfc:`6455`. + + .. _7.1.5: https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.5 + + :obj:`None` if the connection isn't closed yet. + + """ + if self.state is not CLOSED: + return None + elif self.close_rcvd is None: + return CloseCode.ABNORMAL_CLOSURE + else: + return self.close_rcvd.code + + @property + def close_reason(self) -> str | None: + """ + WebSocket close reason received from the remote endpoint. + + Defined in 7.1.6_ of :rfc:`6455`. + + .. _7.1.6: https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.6 + + :obj:`None` if the connection isn't closed yet. + + """ + if self.state is not CLOSED: + return None + elif self.close_rcvd is None: + return "" + else: + return self.close_rcvd.reason + + @property + def close_exc(self) -> ConnectionClosed: + """ + Exception to raise when trying to interact with a closed connection. + + Don't raise this exception while the connection :attr:`state` + is :attr:`~websockets.protocol.State.CLOSING`; wait until + it's :attr:`~websockets.protocol.State.CLOSED`. + + Indeed, the exception includes the close code and reason, which are + known only once the connection is closed. + + Raises: + AssertionError: If the connection isn't closed yet. + + """ + assert self.state is CLOSED, "connection isn't closed yet" + exc_type: type[ConnectionClosed] + if ( + self.close_rcvd is not None + and self.close_sent is not None + and self.close_rcvd.code in OK_CLOSE_CODES + and self.close_sent.code in OK_CLOSE_CODES + ): + exc_type = ConnectionClosedOK + else: + exc_type = ConnectionClosedError + exc: ConnectionClosed = exc_type( + self.close_rcvd, + self.close_sent, + self.close_rcvd_then_sent, + ) + # Chain to the exception raised in the parser, if any. + exc.__cause__ = self.parser_exc + return exc + + # Public methods for receiving data. + + def receive_data(self, data: bytes | bytearray) -> None: + """ + Receive data from the network. + + After calling this method: + + - You must call :meth:`data_to_send` and send this data to the network. + - You should call :meth:`events_received` and process resulting events. + + Raises: + EOFError: If :meth:`receive_eof` was called earlier. + + """ + self.reader.feed_data(data) + next(self.parser) + + def receive_eof(self) -> None: + """ + Receive the end of the data stream from the network. + + After calling this method: + + - You must call :meth:`data_to_send` and send this data to the network; + it will return ``[b""]``, signaling the end of the stream, or ``[]``. + - You aren't expected to call :meth:`events_received`; it won't return + any new events. + + :meth:`receive_eof` is idempotent. + + """ + if self.reader.eof: + return + self.reader.feed_eof() + next(self.parser) + + # Public methods for sending events. + + def send_continuation(self, data: BytesLike, fin: bool) -> None: + """ + Send a `Continuation frame`_. + + .. _Continuation frame: + https://datatracker.ietf.org/doc/html/rfc6455#section-5.6 + + Parameters: + data: payload containing the same kind of data + as the initial frame. + fin: FIN bit; set it to :obj:`True` if this is the last frame + of a fragmented message and to :obj:`False` otherwise. + + Raises: + ProtocolError: If a fragmented message isn't in progress. + + """ + if not self.expect_continuation_frame: + raise ProtocolError("unexpected continuation frame") + if self._state is not OPEN: + raise InvalidState(f"connection is {self.state.name.lower()}") + self.expect_continuation_frame = not fin + self.send_frame(Frame(OP_CONT, data, fin)) + + def send_text(self, data: BytesLike, fin: bool = True) -> None: + """ + Send a `Text frame`_. + + .. _Text frame: + https://datatracker.ietf.org/doc/html/rfc6455#section-5.6 + + Parameters: + data: payload containing text encoded with UTF-8. + fin: FIN bit; set it to :obj:`False` if this is the first frame of + a fragmented message. + + Raises: + ProtocolError: If a fragmented message is in progress. + + """ + if self.expect_continuation_frame: + raise ProtocolError("expected a continuation frame") + if self._state is not OPEN: + raise InvalidState(f"connection is {self.state.name.lower()}") + self.expect_continuation_frame = not fin + self.send_frame(Frame(OP_TEXT, data, fin)) + + def send_binary(self, data: BytesLike, fin: bool = True) -> None: + """ + Send a `Binary frame`_. + + .. _Binary frame: + https://datatracker.ietf.org/doc/html/rfc6455#section-5.6 + + Parameters: + data: payload containing arbitrary binary data. + fin: FIN bit; set it to :obj:`False` if this is the first frame of + a fragmented message. + + Raises: + ProtocolError: If a fragmented message is in progress. + + """ + if self.expect_continuation_frame: + raise ProtocolError("expected a continuation frame") + if self._state is not OPEN: + raise InvalidState(f"connection is {self.state.name.lower()}") + self.expect_continuation_frame = not fin + self.send_frame(Frame(OP_BINARY, data, fin)) + + def send_close(self, code: CloseCode | int | None = None, reason: str = "") -> None: + """ + Send a `Close frame`_. + + .. _Close frame: + https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.1 + + Parameters: + code: close code. + reason: close reason. + + Raises: + ProtocolError: If the code isn't valid or if a reason is provided + without a code. + + """ + # While RFC 6455 doesn't rule out sending more than one close Frame, + # websockets is conservative in what it sends and doesn't allow that. + if self._state is not OPEN: + raise InvalidState(f"connection is {self.state.name.lower()}") + if code is None: + if reason != "": + raise ProtocolError("cannot send a reason without a code") + close = Close(CloseCode.NO_STATUS_RCVD, "") + data = b"" + else: + close = Close(code, reason) + data = close.serialize() + # 7.1.3. The WebSocket Closing Handshake is Started + self.send_frame(Frame(OP_CLOSE, data)) + # Since the state is OPEN, no close frame was received yet. + # As a consequence, self.close_rcvd_then_sent remains None. + assert self.close_rcvd is None + self.close_sent = close + self.state = CLOSING + + def send_ping(self, data: BytesLike) -> None: + """ + Send a `Ping frame`_. + + .. _Ping frame: + https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.2 + + Parameters: + data: payload containing arbitrary binary data. + + """ + # RFC 6455 allows control frames after starting the closing handshake. + if self._state is not OPEN and self._state is not CLOSING: + raise InvalidState(f"connection is {self.state.name.lower()}") + self.send_frame(Frame(OP_PING, data)) + + def send_pong(self, data: BytesLike) -> None: + """ + Send a `Pong frame`_. + + .. _Pong frame: + https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.3 + + Parameters: + data: payload containing arbitrary binary data. + + """ + # RFC 6455 allows control frames after starting the closing handshake. + if self._state is not OPEN and self._state is not CLOSING: + raise InvalidState(f"connection is {self.state.name.lower()}") + self.send_frame(Frame(OP_PONG, data)) + + def fail(self, code: CloseCode | int, reason: str = "") -> None: + """ + `Fail the WebSocket connection`_. + + .. _Fail the WebSocket connection: + https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.7 + + Parameters: + code: close code + reason: close reason + + Raises: + ProtocolError: If the code isn't valid. + """ + # 7.1.7. Fail the WebSocket Connection + + # Send a close frame when the state is OPEN (a close frame was already + # sent if it's CLOSING), except when failing the connection because + # of an error reading from or writing to the network. + if self.state is OPEN: + if code != CloseCode.ABNORMAL_CLOSURE: + close = Close(code, reason) + data = close.serialize() + self.send_frame(Frame(OP_CLOSE, data)) + self.close_sent = close + # If recv_messages() raised an exception upon receiving a close + # frame but before echoing it, then close_rcvd is not None even + # though the state is OPEN. This happens when the connection is + # closed while receiving a fragmented message. + if self.close_rcvd is not None: + self.close_rcvd_then_sent = True + self.state = CLOSING + + # When failing the connection, a server closes the TCP connection + # without waiting for the client to complete the handshake, while a + # client waits for the server to close the TCP connection, possibly + # after sending a close frame that the client will ignore. + if self.side is SERVER and not self.eof_sent: + self.send_eof() + + # 7.1.7. Fail the WebSocket Connection "An endpoint MUST NOT continue + # to attempt to process data(including a responding Close frame) from + # the remote endpoint after being instructed to _Fail the WebSocket + # Connection_." + self.parser = self.discard() + next(self.parser) # start coroutine + + # Public method for getting incoming events after receiving data. + + def events_received(self) -> list[Event]: + """ + Fetch events generated from data received from the network. + + Call this method immediately after any of the ``receive_*()`` methods. + + Process resulting events, likely by passing them to the application. + + Returns: + Events read from the connection. + """ + events, self.events = self.events, [] + return events + + # Public method for getting outgoing data after receiving data or sending events. + + def data_to_send(self) -> list[bytes]: + """ + Obtain data to send to the network. + + Call this method immediately after any of the ``receive_*()``, + ``send_*()``, or :meth:`fail` methods. + + Write resulting data to the connection. + + The empty bytestring :data:`~websockets.protocol.SEND_EOF` signals + the end of the data stream. When you receive it, half-close the TCP + connection. + + Returns: + Data to write to the connection. + + """ + writes, self.writes = self.writes, [] + return writes + + def close_expected(self) -> bool: + """ + Tell if the TCP connection is expected to close soon. + + Call this method immediately after any of the ``receive_*()``, + ``send_close()``, or :meth:`fail` methods. + + If it returns :obj:`True`, schedule closing the TCP connection after a + short timeout if the other side hasn't already closed it. + + Returns: + Whether the TCP connection is expected to close soon. + + """ + # During the opening handshake, when our state is CONNECTING, we expect + # a TCP close if and only if the hansdake fails. When it does, we start + # the TCP closing handshake by sending EOF with send_eof(). + + # Once the opening handshake completes successfully, we expect a TCP + # close if and only if we sent a close frame, meaning that our state + # progressed to CLOSING: + + # * Normal closure: once we send a close frame, we expect a TCP close: + # server waits for client to complete the TCP closing handshake; + # client waits for server to initiate the TCP closing handshake. + + # * Abnormal closure: we always send a close frame and the same logic + # applies, except on EOFError where we don't send a close frame + # because we already received the TCP close, so we don't expect it. + + # If our state is CLOSED, we already received a TCP close so we don't + # expect it anymore. + + # Micro-optimization: put the most common case first + if self.state is OPEN: + return False + if self.state is CLOSING: + return True + if self.state is CLOSED: + return False + assert self.state is CONNECTING + return self.eof_sent + + # Private methods for receiving data. + + def parse(self) -> Generator[None]: + """ + Parse incoming data into frames. + + :meth:`receive_data` and :meth:`receive_eof` run this generator + coroutine until it needs more data or reaches EOF. + + :meth:`parse` never raises an exception. Instead, it sets the + :attr:`parser_exc` and yields control. + + """ + try: + while True: + if (yield from self.reader.at_eof()): + if self.debug: + self.logger.debug("< EOF") + # If the WebSocket connection is closed cleanly, with a + # closing handhshake, recv_frame() substitutes parse() + # with discard(). This branch is reached only when the + # connection isn't closed cleanly. + raise EOFError("unexpected end of stream") + + max_size = None + + if self.max_message_size is not None: + if self.current_size is None: + max_size = self.max_message_size + else: + max_size = self.max_message_size - self.current_size + + if self.max_fragment_size is not None: + if max_size is None: + max_size = self.max_fragment_size + else: + max_size = min(max_size, self.max_fragment_size) + + # During a normal closure, execution ends here on the next + # iteration of the loop after receiving a close frame. At + # this point, recv_frame() replaced parse() by discard(). + frame = yield from Frame.parse( + self.reader.read_exact, + mask=self.side is SERVER, + max_size=max_size, + extensions=self.extensions, + ) + + if self.debug: + self.logger.debug("< %s", frame) + + self.recv_frame(frame) + + except ProtocolError as exc: + self.fail(CloseCode.PROTOCOL_ERROR, str(exc)) + self.parser_exc = exc + + except EOFError as exc: + self.fail(CloseCode.ABNORMAL_CLOSURE, str(exc)) + self.parser_exc = exc + + except UnicodeDecodeError as exc: + self.fail(CloseCode.INVALID_DATA, f"{exc.reason} at position {exc.start}") + self.parser_exc = exc + + except PayloadTooBig as exc: + exc.set_current_size(self.current_size) + self.fail(CloseCode.MESSAGE_TOO_BIG, str(exc)) + self.parser_exc = exc + + except Exception as exc: + self.logger.error("parser failed", exc_info=True) + # Don't include exception details, which may be security-sensitive. + self.fail(CloseCode.INTERNAL_ERROR) + self.parser_exc = exc + + # During an abnormal closure, execution ends here after catching an + # exception. At this point, fail() replaced parse() by discard(). + yield + raise AssertionError("parse() shouldn't step after error") + + def discard(self) -> Generator[None]: + """ + Discard incoming data. + + This coroutine replaces :meth:`parse`: + + - after receiving a close frame, during a normal closure (1.4); + - after sending a close frame, during an abnormal closure (7.1.7). + + """ + # After the opening handshake completes, the server closes the TCP + # connection in the same circumstances where discard() replaces parse(). + # The client closes it when it receives EOF from the server or times + # out. (The latter case cannot be handled in this Sans-I/O layer.) + assert (self.side is SERVER or self.state is CONNECTING) == (self.eof_sent) + while not (yield from self.reader.at_eof()): + self.reader.discard() + if self.debug: + self.logger.debug("< EOF") + # A server closes the TCP connection immediately, while a client + # waits for the server to close the TCP connection. + if self.side is CLIENT and self.state is not CONNECTING: + self.send_eof() + self.state = CLOSED + # If discard() completes normally, execution ends here. + yield + # Once the reader reaches EOF, its feed_data/eof() methods raise an + # error, so our receive_data/eof() methods don't step the generator. + raise AssertionError("discard() shouldn't step after EOF") + + def recv_frame(self, frame: Frame) -> None: + """ + Process an incoming frame. + + """ + if frame.opcode is OP_TEXT or frame.opcode is OP_BINARY: + if self.current_size is not None: + raise ProtocolError("expected a continuation frame") + if not frame.fin: + self.current_size = len(frame.data) + + elif frame.opcode is OP_CONT: + if self.current_size is None: + raise ProtocolError("unexpected continuation frame") + if frame.fin: + self.current_size = None + else: + self.current_size += len(frame.data) + + elif frame.opcode is OP_PING: + # 5.5.2. Ping: "Upon receipt of a Ping frame, an endpoint MUST + # send a Pong frame in response" + pong_frame = Frame(OP_PONG, frame.data) + self.send_frame(pong_frame) + + elif frame.opcode is OP_PONG: + # 5.5.3 Pong: "A response to an unsolicited Pong frame is not + # expected." + pass + + elif frame.opcode is OP_CLOSE: + # 7.1.5. The WebSocket Connection Close Code + # 7.1.6. The WebSocket Connection Close Reason + self.close_rcvd = Close.parse(frame.data) + if self.state is CLOSING: + assert self.close_sent is not None + self.close_rcvd_then_sent = False + + if self.current_size is not None: + raise ProtocolError("incomplete fragmented message") + + # 5.5.1 Close: "If an endpoint receives a Close frame and did + # not previously send a Close frame, the endpoint MUST send a + # Close frame in response. (When sending a Close frame in + # response, the endpoint typically echos the status code it + # received.)" + + if self.state is OPEN: + # Echo the original data instead of re-serializing it with + # Close.serialize() because that fails when the close frame + # is empty and Close.parse() synthesizes a 1005 close code. + # The rest is identical to send_close(). + self.send_frame(Frame(OP_CLOSE, frame.data)) + self.close_sent = self.close_rcvd + self.close_rcvd_then_sent = True + self.state = CLOSING + + # 7.1.2. Start the WebSocket Closing Handshake: "Once an + # endpoint has both sent and received a Close control frame, + # that endpoint SHOULD _Close the WebSocket Connection_" + + # A server closes the TCP connection immediately, while a client + # waits for the server to close the TCP connection. + if self.side is SERVER: + self.send_eof() + + # 1.4. Closing Handshake: "after receiving a control frame + # indicating the connection should be closed, a peer discards + # any further data received." + # RFC 6455 allows reading Ping and Pong frames after a Close frame. + # However, that doesn't seem useful; websockets doesn't support it. + self.parser = self.discard() + next(self.parser) # start coroutine + + else: + # This can't happen because Frame.parse() validates opcodes. + raise AssertionError(f"unexpected opcode: {frame.opcode:02x}") + + self.events.append(frame) + + # Private methods for sending events. + + def send_frame(self, frame: Frame) -> None: + if self.debug: + self.logger.debug("> %s", frame) + self.writes.append( + frame.serialize( + mask=self.side is CLIENT, + extensions=self.extensions, + ) + ) + + def send_eof(self) -> None: + assert not self.eof_sent + self.eof_sent = True + if self.debug: + self.logger.debug("> EOF") + self.writes.append(SEND_EOF) diff --git a/.venv/Lib/site-packages/websockets/proxy.py b/.venv/Lib/site-packages/websockets/proxy.py new file mode 100644 index 0000000000000000000000000000000000000000..c3a735d50cff52574abc5dd0ae3d77ad3936ff11 --- /dev/null +++ b/.venv/Lib/site-packages/websockets/proxy.py @@ -0,0 +1,150 @@ +from __future__ import annotations + +import dataclasses +import urllib.parse +import urllib.request + +from .datastructures import Headers +from .exceptions import InvalidProxy +from .headers import build_authorization_basic, build_host +from .http11 import USER_AGENT +from .uri import DELIMS, WebSocketURI + + +__all__ = ["get_proxy", "parse_proxy", "Proxy"] + + +@dataclasses.dataclass +class Proxy: + """ + Proxy address. + + Attributes: + scheme: ``"socks5h"``, ``"socks5"``, ``"socks4a"``, ``"socks4"``, + ``"https"``, or ``"http"``. + host: Normalized to lower case. + port: Always set even if it's the default. + username: Available when the proxy address contains `User Information`_. + password: Available when the proxy address contains `User Information`_. + + .. _User Information: https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1 + + """ + + scheme: str + host: str + port: int + username: str | None = None + password: str | None = None + + @property + def user_info(self) -> tuple[str, str] | None: + if self.username is None: + return None + assert self.password is not None + return (self.username, self.password) + + +def parse_proxy(proxy: str) -> Proxy: + """ + Parse and validate a proxy. + + Args: + proxy: proxy. + + Returns: + Parsed proxy. + + Raises: + InvalidProxy: If ``proxy`` isn't a valid proxy. + + """ + parsed = urllib.parse.urlparse(proxy) + if parsed.scheme not in ["socks5h", "socks5", "socks4a", "socks4", "https", "http"]: + raise InvalidProxy(proxy, f"scheme {parsed.scheme} isn't supported") + if parsed.hostname is None: + raise InvalidProxy(proxy, "hostname isn't provided") + if parsed.path not in ["", "/"]: + raise InvalidProxy(proxy, "path is meaningless") + if parsed.query != "": + raise InvalidProxy(proxy, "query is meaningless") + if parsed.fragment != "": + raise InvalidProxy(proxy, "fragment is meaningless") + + scheme = parsed.scheme + host = parsed.hostname + port = parsed.port or (443 if parsed.scheme == "https" else 80) + username = parsed.username + password = parsed.password + # urllib.parse.urlparse accepts URLs with a username but without a + # password. This doesn't make sense for HTTP Basic Auth credentials. + if username is not None and password is None: + raise InvalidProxy(proxy, "username provided without password") + + try: + proxy.encode("ascii") + except UnicodeEncodeError: + # Input contains non-ASCII characters. + # It must be an IRI. Convert it to a URI. + host = host.encode("idna").decode() + if username is not None: + assert password is not None + username = urllib.parse.quote(username, safe=DELIMS) + password = urllib.parse.quote(password, safe=DELIMS) + + return Proxy(scheme, host, port, username, password) + + +def get_proxy(uri: WebSocketURI) -> str | None: + """ + Return the proxy to use for connecting to the given WebSocket URI, if any. + + """ + if urllib.request.proxy_bypass(f"{uri.host}:{uri.port}"): + return None + + # According to the _Proxy Usage_ section of RFC 6455, use a SOCKS5 proxy if + # available, else favor the proxy for HTTPS connections over the proxy for + # HTTP connections. + + # The priority of a proxy for WebSocket connections is unspecified. We give + # it the highest priority. This makes it easy to configure a specific proxy + # for websockets. + + # getproxies() may return SOCKS proxies as {"socks": "http://host:port"} or + # as {"https": "socks5h://host:port"} depending on whether they're declared + # in the operating system or in environment variables. + + proxies = urllib.request.getproxies() + if uri.secure: + schemes = ["wss", "socks", "https"] + else: + schemes = ["ws", "socks", "https", "http"] + + for scheme in schemes: + proxy = proxies.get(scheme) + if proxy is not None: + if scheme == "socks" and proxy.startswith("http://"): + proxy = "socks5h://" + proxy[7:] + return proxy + else: + return None + + +def prepare_connect_request( + proxy: Proxy, + ws_uri: WebSocketURI, + user_agent_header: str | None = USER_AGENT, +) -> bytes: + host = build_host(ws_uri.host, ws_uri.port, ws_uri.secure, always_include_port=True) + headers = Headers() + headers["Host"] = build_host(ws_uri.host, ws_uri.port, ws_uri.secure) + if user_agent_header is not None: + headers["User-Agent"] = user_agent_header + if proxy.username is not None: + assert proxy.password is not None # enforced by parse_proxy() + headers["Proxy-Authorization"] = build_authorization_basic( + proxy.username, proxy.password + ) + # We cannot use the Request class because it supports only GET requests. + return f"CONNECT {host} HTTP/1.1\r\n".encode() + headers.serialize() diff --git a/.venv/Lib/site-packages/websockets/py.typed b/.venv/Lib/site-packages/websockets/py.typed new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/.venv/Lib/site-packages/websockets/server.py b/.venv/Lib/site-packages/websockets/server.py new file mode 100644 index 0000000000000000000000000000000000000000..c4ff6cf70008ab2a01b9a6cbb739b799d414582c --- /dev/null +++ b/.venv/Lib/site-packages/websockets/server.py @@ -0,0 +1,589 @@ +from __future__ import annotations + +import base64 +import binascii +import email.utils +import http +import re +import warnings +from collections.abc import Generator, Sequence +from typing import Any, Callable, cast + +from .datastructures import Headers, MultipleValuesError +from .exceptions import ( + InvalidHandshake, + InvalidHeader, + InvalidHeaderValue, + InvalidMessage, + InvalidOrigin, + InvalidUpgrade, + NegotiationError, +) +from .extensions import Extension, ServerExtensionFactory +from .headers import ( + build_extension, + parse_connection, + parse_extension, + parse_subprotocol, + parse_upgrade, +) +from .http11 import Request, Response +from .imports import lazy_import +from .protocol import CONNECTING, OPEN, SERVER, Protocol, State +from .typing import ( + ConnectionOption, + ExtensionHeader, + LoggerLike, + Origin, + StatusLike, + Subprotocol, + UpgradeProtocol, +) +from .utils import accept_key + + +__all__ = ["ServerProtocol"] + + +class ServerProtocol(Protocol): + """ + Sans-I/O implementation of a WebSocket server connection. + + Args: + origins: Acceptable values of the ``Origin`` header. Values can be + :class:`str` to test for an exact match or regular expressions + compiled by :func:`re.compile` to test against a pattern. Include + :obj:`None` in the list if the lack of an origin is acceptable. + This is useful for defending against Cross-Site WebSocket + Hijacking attacks. + extensions: List of supported extensions, in order in which they + should be tried. + subprotocols: List of supported subprotocols, in order of decreasing + preference. + select_subprotocol: Callback for selecting a subprotocol among + those supported by the client and the server. It has the same + signature as the :meth:`select_subprotocol` method, including a + :class:`ServerProtocol` instance as first argument. + state: Initial state of the WebSocket connection. + max_size: Maximum size of incoming messages in bytes. + :obj:`None` disables the limit. You may pass a ``(max_message_size, + max_fragment_size)`` tuple to set different limits for messages and + fragments when you expect long messages sent in short fragments. + logger: Logger for this connection; + defaults to ``logging.getLogger("websockets.server")``; + see the :doc:`logging guide <../../topics/logging>` for details. + + """ + + def __init__( + self, + *, + origins: Sequence[Origin | re.Pattern[str] | None] | None = None, + extensions: Sequence[ServerExtensionFactory] | None = None, + subprotocols: Sequence[Subprotocol] | None = None, + select_subprotocol: ( + Callable[ + [ServerProtocol, Sequence[Subprotocol]], + Subprotocol | None, + ] + | None + ) = None, + state: State = CONNECTING, + max_size: int | None | tuple[int | None, int | None] = 2**20, + logger: LoggerLike | None = None, + ) -> None: + super().__init__( + side=SERVER, + state=state, + max_size=max_size, + logger=logger, + ) + self.origins = origins + self.available_extensions = extensions + self.available_subprotocols = subprotocols + if select_subprotocol is not None: + # Bind select_subprotocol then shadow self.select_subprotocol. + # Use setattr to work around https://github.com/python/mypy/issues/2427. + setattr( + self, + "select_subprotocol", + select_subprotocol.__get__(self, self.__class__), + ) + + def accept(self, request: Request) -> Response: + """ + Create a handshake response to accept the connection. + + If the handshake request is valid and the handshake successful, + :meth:`accept` returns an HTTP response with status code 101. + + Else, it returns an HTTP response with another status code. This rejects + the connection, like :meth:`reject` would. + + You must send the handshake response with :meth:`send_response`. + + You may modify the response before sending it, typically by adding HTTP + headers. + + Args: + request: WebSocket handshake request received from the client. + + Returns: + WebSocket handshake response or HTTP response to send to the client. + + """ + try: + ( + accept_header, + extensions_header, + protocol_header, + ) = self.process_request(request) + except InvalidOrigin as exc: + request._exception = exc + self.handshake_exc = exc + if self.debug: + self.logger.debug("! invalid origin", exc_info=True) + return self.reject( + http.HTTPStatus.FORBIDDEN, + f"Failed to open a WebSocket connection: {exc}.\n", + ) + except InvalidUpgrade as exc: + request._exception = exc + self.handshake_exc = exc + if self.debug: + self.logger.debug("! invalid upgrade", exc_info=True) + response = self.reject( + http.HTTPStatus.UPGRADE_REQUIRED, + ( + f"Failed to open a WebSocket connection: {exc}.\n" + f"\n" + f"You cannot access a WebSocket server directly " + f"with a browser. You need a WebSocket client.\n" + ), + ) + response.headers["Upgrade"] = "websocket" + return response + except InvalidHandshake as exc: + request._exception = exc + self.handshake_exc = exc + if self.debug: + self.logger.debug("! invalid handshake", exc_info=True) + exc_chain = cast(BaseException, exc) + exc_str = f"{exc_chain}" + while exc_chain.__cause__ is not None: + exc_chain = exc_chain.__cause__ + exc_str += f"; {exc_chain}" + return self.reject( + http.HTTPStatus.BAD_REQUEST, + f"Failed to open a WebSocket connection: {exc_str}.\n", + ) + except Exception as exc: + # Handle exceptions raised by user-provided select_subprotocol and + # unexpected errors. + request._exception = exc + self.handshake_exc = exc + self.logger.error("opening handshake failed", exc_info=True) + return self.reject( + http.HTTPStatus.INTERNAL_SERVER_ERROR, + ( + "Failed to open a WebSocket connection.\n" + "See server log for more information.\n" + ), + ) + + headers = Headers() + headers["Date"] = email.utils.formatdate(usegmt=True) + headers["Upgrade"] = "websocket" + headers["Connection"] = "Upgrade" + headers["Sec-WebSocket-Accept"] = accept_header + if extensions_header is not None: + headers["Sec-WebSocket-Extensions"] = extensions_header + if protocol_header is not None: + headers["Sec-WebSocket-Protocol"] = protocol_header + return Response(101, "Switching Protocols", headers) + + def process_request( + self, + request: Request, + ) -> tuple[str, str | None, str | None]: + """ + Check a handshake request and negotiate extensions and subprotocol. + + This function doesn't verify that the request is an HTTP/1.1 or higher + GET request and doesn't check the ``Host`` header. These controls are + usually performed earlier in the HTTP request handling code. They're + the responsibility of the caller. + + Args: + request: WebSocket handshake request received from the client. + + Returns: + ``Sec-WebSocket-Accept``, ``Sec-WebSocket-Extensions``, and + ``Sec-WebSocket-Protocol`` headers for the handshake response. + + Raises: + InvalidHandshake: If the handshake request is invalid; + then the server must return 400 Bad Request error. + + """ + headers = request.headers + + connection: list[ConnectionOption] = sum( + [parse_connection(value) for value in headers.get_all("Connection")], [] + ) + if not any(value.lower() == "upgrade" for value in connection): + raise InvalidUpgrade( + "Connection", ", ".join(connection) if connection else None + ) + + upgrade: list[UpgradeProtocol] = sum( + [parse_upgrade(value) for value in headers.get_all("Upgrade")], [] + ) + # For compatibility with non-strict implementations, ignore case when + # checking the Upgrade header. The RFC always uses "websocket", except + # in section 11.2. (IANA registration) where it uses "WebSocket". + if not (len(upgrade) == 1 and upgrade[0].lower() == "websocket"): + raise InvalidUpgrade("Upgrade", ", ".join(upgrade) if upgrade else None) + + try: + key = headers["Sec-WebSocket-Key"] + except KeyError: + raise InvalidHeader("Sec-WebSocket-Key") from None + except MultipleValuesError: + raise InvalidHeader("Sec-WebSocket-Key", "multiple values") from None + try: + raw_key = base64.b64decode(key.encode(), validate=True) + except binascii.Error as exc: + raise InvalidHeaderValue("Sec-WebSocket-Key", key) from exc + if len(raw_key) != 16: + raise InvalidHeaderValue("Sec-WebSocket-Key", key) + accept_header = accept_key(key) + + try: + version = headers["Sec-WebSocket-Version"] + except KeyError: + raise InvalidHeader("Sec-WebSocket-Version") from None + except MultipleValuesError: + raise InvalidHeader("Sec-WebSocket-Version", "multiple values") from None + if version != "13": + raise InvalidHeaderValue("Sec-WebSocket-Version", version) + + self.origin = self.process_origin(headers) + extensions_header, self.extensions = self.process_extensions(headers) + protocol_header = self.subprotocol = self.process_subprotocol(headers) + + return (accept_header, extensions_header, protocol_header) + + def process_origin(self, headers: Headers) -> Origin | None: + """ + Handle the Origin HTTP request header. + + Args: + headers: WebSocket handshake request headers. + + Returns: + origin, if it is acceptable. + + Raises: + InvalidHandshake: If the Origin header is invalid. + InvalidOrigin: If the origin isn't acceptable. + + """ + # "The user agent MUST NOT include more than one Origin header field" + # per https://datatracker.ietf.org/doc/html/rfc6454#section-7.3. + try: + origin = headers.get("Origin") + except MultipleValuesError: + raise InvalidHeader("Origin", "multiple values") from None + if origin is not None: + origin = cast(Origin, origin) + if self.origins is not None: + for origin_or_regex in self.origins: + if origin_or_regex == origin or ( + isinstance(origin_or_regex, re.Pattern) + and origin is not None + and origin_or_regex.fullmatch(origin) is not None + ): + break + else: + raise InvalidOrigin(origin) + return origin + + def process_extensions( + self, + headers: Headers, + ) -> tuple[str | None, list[Extension]]: + """ + Handle the Sec-WebSocket-Extensions HTTP request header. + + Accept or reject each extension proposed in the client request. + Negotiate parameters for accepted extensions. + + Per :rfc:`6455`, negotiation rules are defined by the specification of + each extension. + + To provide this level of flexibility, for each extension proposed by + the client, we check for a match with each extension available in the + server configuration. If no match is found, the extension is ignored. + + If several variants of the same extension are proposed by the client, + it may be accepted several times, which won't make sense in general. + Extensions must implement their own requirements. For this purpose, + the list of previously accepted extensions is provided. + + This process doesn't allow the server to reorder extensions. It can + only select a subset of the extensions proposed by the client. + + Other requirements, for example related to mandatory extensions or the + order of extensions, may be implemented by overriding this method. + + Args: + headers: WebSocket handshake request headers. + + Returns: + ``Sec-WebSocket-Extensions`` HTTP response header and list of + accepted extensions. + + Raises: + InvalidHandshake: If the Sec-WebSocket-Extensions header is invalid. + + """ + response_header_value: str | None = None + + extension_headers: list[ExtensionHeader] = [] + accepted_extensions: list[Extension] = [] + + header_values = headers.get_all("Sec-WebSocket-Extensions") + + if header_values and self.available_extensions: + parsed_header_values: list[ExtensionHeader] = sum( + [parse_extension(header_value) for header_value in header_values], [] + ) + + for name, request_params in parsed_header_values: + for ext_factory in self.available_extensions: + # Skip non-matching extensions based on their name. + if ext_factory.name != name: + continue + + # Skip non-matching extensions based on their params. + try: + response_params, extension = ext_factory.process_request_params( + request_params, accepted_extensions + ) + except NegotiationError: + continue + + # Add matching extension to the final list. + extension_headers.append((name, response_params)) + accepted_extensions.append(extension) + + # Break out of the loop once we have a match. + break + + # If we didn't break from the loop, no extension in our list + # matched what the client sent. The extension is declined. + + # Serialize extension header. + if extension_headers: + response_header_value = build_extension(extension_headers) + + return response_header_value, accepted_extensions + + def process_subprotocol(self, headers: Headers) -> Subprotocol | None: + """ + Handle the Sec-WebSocket-Protocol HTTP request header. + + Args: + headers: WebSocket handshake request headers. + + Returns: + Subprotocol, if one was selected; this is also the value of the + ``Sec-WebSocket-Protocol`` response header. + + Raises: + InvalidHandshake: If the Sec-WebSocket-Subprotocol header is invalid. + + """ + subprotocols: Sequence[Subprotocol] = sum( + [ + parse_subprotocol(header_value) + for header_value in headers.get_all("Sec-WebSocket-Protocol") + ], + [], + ) + return self.select_subprotocol(subprotocols) + + def select_subprotocol( + self, + subprotocols: Sequence[Subprotocol], + ) -> Subprotocol | None: + """ + Pick a subprotocol among those offered by the client. + + If several subprotocols are supported by both the client and the server, + pick the first one in the list declared the server. + + If the server doesn't support any subprotocols, continue without a + subprotocol, regardless of what the client offers. + + If the server supports at least one subprotocol and the client doesn't + offer any, abort the handshake with an HTTP 400 error. + + You provide a ``select_subprotocol`` argument to :class:`ServerProtocol` + to override this logic. For example, you could accept the connection + even if client doesn't offer a subprotocol, rather than reject it. + + Here's how to negotiate the ``chat`` subprotocol if the client supports + it and continue without a subprotocol otherwise:: + + def select_subprotocol(protocol, subprotocols): + if "chat" in subprotocols: + return "chat" + + Args: + subprotocols: List of subprotocols offered by the client. + + Returns: + Selected subprotocol, if a common subprotocol was found. + + :obj:`None` to continue without a subprotocol. + + Raises: + NegotiationError: Custom implementations may raise this exception + to abort the handshake with an HTTP 400 error. + + """ + # Server doesn't offer any subprotocols. + if not self.available_subprotocols: # None or empty list + return None + + # Server offers at least one subprotocol but client doesn't offer any. + if not subprotocols: + raise NegotiationError("missing subprotocol") + + # Server and client both offer subprotocols. Look for a shared one. + proposed_subprotocols = set(subprotocols) + for subprotocol in self.available_subprotocols: + if subprotocol in proposed_subprotocols: + return subprotocol + + # No common subprotocol was found. + raise NegotiationError( + "invalid subprotocol; expected one of " + + ", ".join(self.available_subprotocols) + ) + + def reject(self, status: StatusLike, text: str) -> Response: + """ + Create a handshake response to reject the connection. + + A short plain text response is the best fallback when failing to + establish a WebSocket connection. + + You must send the handshake response with :meth:`send_response`. + + You may modify the response before sending it, for example by changing + HTTP headers. + + Args: + status: HTTP status code. + text: HTTP response body; it will be encoded to UTF-8. + + Returns: + HTTP response to send to the client. + + """ + # If status is an int instead of an HTTPStatus, fix it automatically. + status = http.HTTPStatus(status) + body = text.encode() + headers = Headers( + [ + ("Date", email.utils.formatdate(usegmt=True)), + ("Connection", "close"), + ("Content-Length", str(len(body))), + ("Content-Type", "text/plain; charset=utf-8"), + ] + ) + return Response(status.value, status.phrase, headers, body) + + def send_response(self, response: Response) -> None: + """ + Send a handshake response to the client. + + Args: + response: WebSocket handshake response event to send. + + """ + if self.debug: + code, phrase = response.status_code, response.reason_phrase + self.logger.debug("> HTTP/1.1 %d %s", code, phrase) + for key, value in response.headers.raw_items(): + self.logger.debug("> %s: %s", key, value) + if response.body: + self.logger.debug("> [body] (%d bytes)", len(response.body)) + + self.writes.append(response.serialize()) + + if response.status_code == 101: + assert self.state is CONNECTING + self.state = OPEN + self.logger.info("connection open") + + else: + self.logger.info( + "connection rejected (%d %s)", + response.status_code, + response.reason_phrase, + ) + + self.send_eof() + self.parser = self.discard() + next(self.parser) # start coroutine + + def parse(self) -> Generator[None]: + if self.state is CONNECTING: + try: + request = yield from Request.parse( + self.reader.read_line, + ) + except Exception as exc: + self.handshake_exc = InvalidMessage( + "did not receive a valid HTTP request" + ) + self.handshake_exc.__cause__ = exc + self.send_eof() + self.parser = self.discard() + next(self.parser) # start coroutine + yield + + if self.debug: + self.logger.debug("< GET %s HTTP/1.1", request.path) + for key, value in request.headers.raw_items(): + self.logger.debug("< %s: %s", key, value) + + self.events.append(request) + + yield from super().parse() + + +class ServerConnection(ServerProtocol): + def __init__(self, *args: Any, **kwargs: Any) -> None: + warnings.warn( # deprecated in 11.0 - 2023-04-02 + "ServerConnection was renamed to ServerProtocol", + DeprecationWarning, + ) + super().__init__(*args, **kwargs) + + +lazy_import( + globals(), + deprecated_aliases={ + # deprecated in 14.0 - 2024-11-09 + "WebSocketServer": ".legacy.server", + "WebSocketServerProtocol": ".legacy.server", + "broadcast": ".legacy.server", + "serve": ".legacy.server", + "unix_serve": ".legacy.server", + }, +) diff --git a/.venv/Lib/site-packages/websockets/speedups.c b/.venv/Lib/site-packages/websockets/speedups.c new file mode 100644 index 0000000000000000000000000000000000000000..5c0235abef1ebb0ccbb0e26d9d5d7100e4f16031 --- /dev/null +++ b/.venv/Lib/site-packages/websockets/speedups.c @@ -0,0 +1,229 @@ +/* C implementation of performance sensitive functions. */ + +#define PY_SSIZE_T_CLEAN +#include +#include /* uint8_t, uint32_t, uint64_t */ + +#if __ARM_NEON +#include +#elif __SSE2__ +#include +#endif + +static const Py_ssize_t MASK_LEN = 4; + +/* Similar to PyBytes_AsStringAndSize, but accepts more types */ + +static int +_PyBytesLike_AsStringAndSize(PyObject *obj, PyObject **tmp, char **buffer, Py_ssize_t *length) +{ + // This supports bytes, bytearrays, and memoryview objects, + // which are common data structures for handling byte streams. + // If *tmp isn't NULL, the caller gets a new reference. + if (PyBytes_Check(obj)) + { + *tmp = NULL; + *buffer = PyBytes_AS_STRING(obj); + *length = PyBytes_GET_SIZE(obj); + } + else if (PyByteArray_Check(obj)) + { + *tmp = NULL; + *buffer = PyByteArray_AS_STRING(obj); + *length = PyByteArray_GET_SIZE(obj); + } + else if (PyMemoryView_Check(obj)) + { + *tmp = PyMemoryView_GetContiguous(obj, PyBUF_READ, 'C'); + if (*tmp == NULL) + { + return -1; + } + Py_buffer *mv_buf; + mv_buf = PyMemoryView_GET_BUFFER(*tmp); + *buffer = mv_buf->buf; + *length = mv_buf->len; + } + else + { + PyErr_Format( + PyExc_TypeError, + "expected a bytes-like object, %.200s found", + Py_TYPE(obj)->tp_name); + return -1; + } + + return 0; +} + +/* C implementation of websockets.utils.apply_mask */ + +static PyObject * +apply_mask(PyObject *self, PyObject *args, PyObject *kwds) +{ + + // In order to support various bytes-like types, accept any Python object. + + static char *kwlist[] = {"data", "mask", NULL}; + PyObject *input_obj; + PyObject *mask_obj; + + // A pointer to a char * + length will be extracted from the data and mask + // arguments, possibly via a Py_buffer. + + PyObject *input_tmp = NULL; + char *input; + Py_ssize_t input_len; + PyObject *mask_tmp = NULL; + char *mask; + Py_ssize_t mask_len; + + // Initialize a PyBytesObject then get a pointer to the underlying char * + // in order to avoid an extra memory copy in PyBytes_FromStringAndSize. + + PyObject *result = NULL; + char *output; + + // Other variables. + + Py_ssize_t i = 0; + + // Parse inputs. + + if (!PyArg_ParseTupleAndKeywords( + args, kwds, "OO", kwlist, &input_obj, &mask_obj)) + { + goto exit; + } + + if (_PyBytesLike_AsStringAndSize(input_obj, &input_tmp, &input, &input_len) == -1) + { + goto exit; + } + + if (_PyBytesLike_AsStringAndSize(mask_obj, &mask_tmp, &mask, &mask_len) == -1) + { + goto exit; + } + + if (mask_len != MASK_LEN) + { + PyErr_SetString(PyExc_ValueError, "mask must contain 4 bytes"); + goto exit; + } + + // Create output. + + result = PyBytes_FromStringAndSize(NULL, input_len); + if (result == NULL) + { + goto exit; + } + + // Since we just created result, we don't need error checks. + output = PyBytes_AS_STRING(result); + + // Perform the masking operation. + + // Apparently GCC cannot figure out the following optimizations by itself. + + // We need a new scope for MSVC 2010 (non C99 friendly) + { +#if __ARM_NEON + + // With NEON support, XOR by blocks of 16 bytes = 128 bits. + + Py_ssize_t input_len_128 = input_len & ~15; + uint8x16_t mask_128 = vreinterpretq_u8_u32(vdupq_n_u32(*(uint32_t *)mask)); + + for (; i < input_len_128; i += 16) + { + uint8x16_t in_128 = vld1q_u8((uint8_t *)(input + i)); + uint8x16_t out_128 = veorq_u8(in_128, mask_128); + vst1q_u8((uint8_t *)(output + i), out_128); + } + +#elif __SSE2__ + + // With SSE2 support, XOR by blocks of 16 bytes = 128 bits. + + // Since we cannot control the 16-bytes alignment of input and output + // buffers, we rely on loadu/storeu rather than load/store. + + Py_ssize_t input_len_128 = input_len & ~15; + __m128i mask_128 = _mm_set1_epi32(*(uint32_t *)mask); + + for (; i < input_len_128; i += 16) + { + __m128i in_128 = _mm_loadu_si128((__m128i *)(input + i)); + __m128i out_128 = _mm_xor_si128(in_128, mask_128); + _mm_storeu_si128((__m128i *)(output + i), out_128); + } + +#else + + // Without SSE2 support, XOR by blocks of 8 bytes = 64 bits. + + // We assume the memory allocator aligns everything on 8 bytes boundaries. + + Py_ssize_t input_len_64 = input_len & ~7; + uint32_t mask_32 = *(uint32_t *)mask; + uint64_t mask_64 = ((uint64_t)mask_32 << 32) | (uint64_t)mask_32; + + for (; i < input_len_64; i += 8) + { + *(uint64_t *)(output + i) = *(uint64_t *)(input + i) ^ mask_64; + } + +#endif + } + + // XOR the remainder of the input byte by byte. + + for (; i < input_len; i++) + { + output[i] = input[i] ^ mask[i & (MASK_LEN - 1)]; + } + +exit: + Py_XDECREF(input_tmp); + Py_XDECREF(mask_tmp); + return result; + +} + +static PyMethodDef speedups_methods[] = { + { + "apply_mask", + (PyCFunction)apply_mask, + METH_VARARGS | METH_KEYWORDS, + "Apply masking to the data of a WebSocket message.", + }, + {NULL, NULL, 0, NULL}, /* Sentinel */ +}; + +static struct PyModuleDef speedups_module = { + PyModuleDef_HEAD_INIT, + "websocket.speedups", /* m_name */ + "C implementation of performance sensitive functions.", + /* m_doc */ + -1, /* m_size */ + speedups_methods, /* m_methods */ + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit_speedups(void) +{ + PyObject *m = PyModule_Create(&speedups_module); + if (m == NULL) { + return NULL; + } +#ifdef Py_GIL_DISABLED + PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED); +#endif + return m; +} diff --git a/.venv/Lib/site-packages/websockets/speedups.pyi b/.venv/Lib/site-packages/websockets/speedups.pyi new file mode 100644 index 0000000000000000000000000000000000000000..2aa58e8e92c4cc66c30d423051e6dc55b0b86d0b --- /dev/null +++ b/.venv/Lib/site-packages/websockets/speedups.pyi @@ -0,0 +1,3 @@ +from .typing import BytesLike + +def apply_mask(data: BytesLike, mask: bytes | bytearray) -> bytes: ... diff --git a/.venv/Lib/site-packages/websockets/streams.py b/.venv/Lib/site-packages/websockets/streams.py new file mode 100644 index 0000000000000000000000000000000000000000..35634fc5b47b702322d73aabfe083c6817203674 --- /dev/null +++ b/.venv/Lib/site-packages/websockets/streams.py @@ -0,0 +1,151 @@ +from __future__ import annotations + +from collections.abc import Generator + + +class StreamReader: + """ + Generator-based stream reader. + + This class doesn't support concurrent calls to :meth:`read_line`, + :meth:`read_exact`, or :meth:`read_to_eof`. Make sure calls are + serialized. + + """ + + def __init__(self) -> None: + self.buffer = bytearray() + self.eof = False + + def read_line(self, m: int) -> Generator[None, None, bytearray]: + """ + Read a LF-terminated line from the stream. + + This is a generator-based coroutine. + + The return value includes the LF character. + + Args: + m: Maximum number bytes to read; this is a security limit. + + Raises: + EOFError: If the stream ends without a LF. + RuntimeError: If the stream ends in more than ``m`` bytes. + + """ + n = 0 # number of bytes to read + p = 0 # number of bytes without a newline + while True: + n = self.buffer.find(b"\n", p) + 1 + if n > 0: + break + p = len(self.buffer) + if p > m: + raise RuntimeError(f"read {p} bytes, expected no more than {m} bytes") + if self.eof: + raise EOFError(f"stream ends after {p} bytes, before end of line") + yield + if n > m: + raise RuntimeError(f"read {n} bytes, expected no more than {m} bytes") + r = self.buffer[:n] + del self.buffer[:n] + return r + + def read_exact(self, n: int) -> Generator[None, None, bytearray]: + """ + Read a given number of bytes from the stream. + + This is a generator-based coroutine. + + Args: + n: How many bytes to read. + + Raises: + EOFError: If the stream ends in less than ``n`` bytes. + + """ + assert n >= 0 + while len(self.buffer) < n: + if self.eof: + p = len(self.buffer) + raise EOFError(f"stream ends after {p} bytes, expected {n} bytes") + yield + r = self.buffer[:n] + del self.buffer[:n] + return r + + def read_to_eof(self, m: int) -> Generator[None, None, bytearray]: + """ + Read all bytes from the stream. + + This is a generator-based coroutine. + + Args: + m: Maximum number bytes to read; this is a security limit. + + Raises: + RuntimeError: If the stream ends in more than ``m`` bytes. + + """ + while not self.eof: + p = len(self.buffer) + if p > m: + raise RuntimeError(f"read {p} bytes, expected no more than {m} bytes") + yield + r = self.buffer[:] + del self.buffer[:] + return r + + def at_eof(self) -> Generator[None, None, bool]: + """ + Tell whether the stream has ended and all data was read. + + This is a generator-based coroutine. + + """ + while True: + if self.buffer: + return False + if self.eof: + return True + # When all data was read but the stream hasn't ended, we can't + # tell if until either feed_data() or feed_eof() is called. + yield + + def feed_data(self, data: bytes | bytearray) -> None: + """ + Write data to the stream. + + :meth:`feed_data` cannot be called after :meth:`feed_eof`. + + Args: + data: Data to write. + + Raises: + EOFError: If the stream has ended. + + """ + if self.eof: + raise EOFError("stream ended") + self.buffer += data + + def feed_eof(self) -> None: + """ + End the stream. + + :meth:`feed_eof` cannot be called more than once. + + Raises: + EOFError: If the stream has ended. + + """ + if self.eof: + raise EOFError("stream ended") + self.eof = True + + def discard(self) -> None: + """ + Discard all buffered data, but don't end the stream. + + """ + del self.buffer[:] diff --git a/.venv/Lib/site-packages/websockets/sync/__init__.py b/.venv/Lib/site-packages/websockets/sync/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/.venv/Lib/site-packages/websockets/sync/client.py b/.venv/Lib/site-packages/websockets/sync/client.py new file mode 100644 index 0000000000000000000000000000000000000000..6e3ea12877842f2679fa036ad5648c4550c28340 --- /dev/null +++ b/.venv/Lib/site-packages/websockets/sync/client.py @@ -0,0 +1,633 @@ +from __future__ import annotations + +import socket +import ssl as ssl_module +import threading +import warnings +from collections.abc import Sequence +from typing import Any, Callable, Literal, TypeVar, cast + +from ..client import ClientProtocol +from ..datastructures import HeadersLike +from ..exceptions import InvalidProxyMessage, InvalidProxyStatus, ProxyError +from ..extensions.base import ClientExtensionFactory +from ..extensions.permessage_deflate import enable_client_permessage_deflate +from ..headers import validate_subprotocols +from ..http11 import USER_AGENT, Response +from ..protocol import CONNECTING, Event +from ..proxy import Proxy, get_proxy, parse_proxy, prepare_connect_request +from ..streams import StreamReader +from ..typing import BytesLike, LoggerLike, Origin, Subprotocol +from ..uri import WebSocketURI, parse_uri +from .connection import Connection +from .utils import Deadline + + +__all__ = ["connect", "unix_connect", "ClientConnection"] + + +class ClientConnection(Connection): + """ + :mod:`threading` implementation of a WebSocket client connection. + + :class:`ClientConnection` provides :meth:`recv` and :meth:`send` methods for + receiving and sending messages. + + It supports iteration to receive messages:: + + for message in websocket: + process(message) + + The iterator exits normally when the connection is closed with code + 1000 (OK) or 1001 (going away) or without a close code. It raises a + :exc:`~websockets.exceptions.ConnectionClosedError` when the connection is + closed with any other code. + + The ``ping_interval``, ``ping_timeout``, ``close_timeout``, and + ``max_queue`` arguments have the same meaning as in :func:`connect`. + + Args: + socket: Socket connected to a WebSocket server. + protocol: Sans-I/O connection. + + """ + + def __init__( + self, + socket: socket.socket, + protocol: ClientProtocol, + *, + ping_interval: float | None = 20, + ping_timeout: float | None = 20, + close_timeout: float | None = 10, + max_queue: int | None | tuple[int | None, int | None] = 16, + ) -> None: + self.protocol: ClientProtocol + self.response_rcvd = threading.Event() + super().__init__( + socket, + protocol, + ping_interval=ping_interval, + ping_timeout=ping_timeout, + close_timeout=close_timeout, + max_queue=max_queue, + ) + + def handshake( + self, + additional_headers: HeadersLike | None = None, + user_agent_header: str | None = USER_AGENT, + timeout: float | None = None, + ) -> None: + """ + Perform the opening handshake. + + """ + with self.send_context(expected_state=CONNECTING): + self.request = self.protocol.connect() + if additional_headers is not None: + self.request.headers.update(additional_headers) + if user_agent_header is not None: + self.request.headers.setdefault("User-Agent", user_agent_header) + self.protocol.send_request(self.request) + + if not self.response_rcvd.wait(timeout): + raise TimeoutError("timed out while waiting for handshake response") + + # self.protocol.handshake_exc is set when the connection is lost before + # receiving a response, when the response cannot be parsed, or when the + # response fails the handshake. + + if self.protocol.handshake_exc is not None: + raise self.protocol.handshake_exc + + def process_event(self, event: Event) -> None: + """ + Process one incoming event. + + """ + # First event - handshake response. + if self.response is None: + assert isinstance(event, Response) + self.response = event + self.response_rcvd.set() + # Later events - frames. + else: + super().process_event(event) + + def recv_events(self) -> None: + """ + Read incoming data from the socket and process events. + + """ + try: + super().recv_events() + finally: + # If the connection is closed during the handshake, unblock it. + self.response_rcvd.set() + + +def connect( + uri: str, + *, + # TCP/TLS + sock: socket.socket | None = None, + ssl: ssl_module.SSLContext | None = None, + server_hostname: str | None = None, + # WebSocket + origin: Origin | None = None, + extensions: Sequence[ClientExtensionFactory] | None = None, + subprotocols: Sequence[Subprotocol] | None = None, + compression: str | None = "deflate", + # HTTP + additional_headers: HeadersLike | None = None, + user_agent_header: str | None = USER_AGENT, + proxy: str | Literal[True] | None = True, + proxy_ssl: ssl_module.SSLContext | None = None, + proxy_server_hostname: str | None = None, + # Timeouts + open_timeout: float | None = 10, + ping_interval: float | None = 20, + ping_timeout: float | None = 20, + close_timeout: float | None = 10, + # Limits + max_size: int | None | tuple[int | None, int | None] = 2**20, + max_queue: int | None | tuple[int | None, int | None] = 16, + # Logging + logger: LoggerLike | None = None, + # Escape hatch for advanced customization + create_connection: type[ClientConnection] | None = None, + **kwargs: Any, +) -> ClientConnection: + """ + Connect to the WebSocket server at ``uri``. + + This function returns a :class:`ClientConnection` instance, which you can + use to send and receive messages. + + :func:`connect` may be used as a context manager:: + + from websockets.sync.client import connect + + with connect(...) as websocket: + ... + + The connection is closed automatically when exiting the context. + + Args: + uri: URI of the WebSocket server. + sock: Preexisting TCP socket. ``sock`` overrides the host and port + from ``uri``. You may call :func:`socket.create_connection` to + create a suitable TCP socket. + ssl: Configuration for enabling TLS on the connection. + server_hostname: Host name for the TLS handshake. ``server_hostname`` + overrides the host name from ``uri``. + origin: Value of the ``Origin`` header, for servers that require it. + extensions: List of supported extensions, in order in which they + should be negotiated and run. + subprotocols: List of supported subprotocols, in order of decreasing + preference. + compression: The "permessage-deflate" extension is enabled by default. + Set ``compression`` to :obj:`None` to disable it. See the + :doc:`compression guide <../../topics/compression>` for details. + additional_headers (HeadersLike | None): Arbitrary HTTP headers to add + to the handshake request. + user_agent_header: Value of the ``User-Agent`` request header. + It defaults to ``"Python/x.y.z websockets/X.Y"``. + Setting it to :obj:`None` removes the header. + proxy: If a proxy is configured, it is used by default. Set ``proxy`` + to :obj:`None` to disable the proxy or to the address of a proxy + to override the system configuration. See the :doc:`proxy docs + <../../topics/proxies>` for details. + proxy_ssl: Configuration for enabling TLS on the proxy connection. + proxy_server_hostname: Host name for the TLS handshake with the proxy. + ``proxy_server_hostname`` overrides the host name from ``proxy``. + open_timeout: Timeout for opening the connection in seconds. + :obj:`None` disables the timeout. + ping_interval: Interval between keepalive pings in seconds. + :obj:`None` disables keepalive. + ping_timeout: Timeout for keepalive pings in seconds. + :obj:`None` disables timeouts. + close_timeout: Timeout for closing the connection in seconds. + :obj:`None` disables the timeout. + max_size: Maximum size of incoming messages in bytes. + :obj:`None` disables the limit. You may pass a ``(max_message_size, + max_fragment_size)`` tuple to set different limits for messages and + fragments when you expect long messages sent in short fragments. + max_queue: High-water mark of the buffer where frames are received. + It defaults to 16 frames. The low-water mark defaults to ``max_queue + // 4``. You may pass a ``(high, low)`` tuple to set the high-water + and low-water marks. If you want to disable flow control entirely, + you may set it to ``None``, although that's a bad idea. + logger: Logger for this client. + It defaults to ``logging.getLogger("websockets.client")``. + See the :doc:`logging guide <../../topics/logging>` for details. + create_connection: Factory for the :class:`ClientConnection` managing + the connection. Set it to a wrapper or a subclass to customize + connection handling. + + Any other keyword arguments are passed to :func:`~socket.create_connection`. + + Raises: + InvalidURI: If ``uri`` isn't a valid WebSocket URI. + OSError: If the TCP connection fails. + InvalidHandshake: If the opening handshake fails. + TimeoutError: If the opening handshake times out. + + """ + + # Process parameters + + # Backwards compatibility: ssl used to be called ssl_context. + if ssl is None and "ssl_context" in kwargs: + ssl = kwargs.pop("ssl_context") + warnings.warn( # deprecated in 13.0 - 2024-08-20 + "ssl_context was renamed to ssl", + DeprecationWarning, + ) + + ws_uri = parse_uri(uri) + if not ws_uri.secure and ssl is not None: + raise ValueError("ssl argument is incompatible with a ws:// URI") + + # Private APIs for unix_connect() + unix: bool = kwargs.pop("unix", False) + path: str | None = kwargs.pop("path", None) + + if unix: + if path is None and sock is None: + raise ValueError("missing path argument") + elif path is not None and sock is not None: + raise ValueError("path and sock arguments are incompatible") + + if subprotocols is not None: + validate_subprotocols(subprotocols) + + if compression == "deflate": + extensions = enable_client_permessage_deflate(extensions) + elif compression is not None: + raise ValueError(f"unsupported compression: {compression}") + + if unix: + proxy = None + if sock is not None: + proxy = None + if proxy is True: + proxy = get_proxy(ws_uri) + + # Calculate timeouts on the TCP, TLS, and WebSocket handshakes. + # The TCP and TLS timeouts must be set on the socket, then removed + # to avoid conflicting with the WebSocket timeout in handshake(). + deadline = Deadline(open_timeout) + + if create_connection is None: + create_connection = ClientConnection + + try: + # Connect socket + + if sock is None: + if unix: + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + sock.settimeout(deadline.timeout()) + assert path is not None # mypy cannot figure this out + sock.connect(path) + elif proxy is not None: + proxy_parsed = parse_proxy(proxy) + if proxy_parsed.scheme[:5] == "socks": + # Connect to the server through the proxy. + sock = connect_socks_proxy( + proxy_parsed, + ws_uri, + deadline, + # websockets is consistent with the socket module while + # python_socks is consistent across implementations. + local_addr=kwargs.pop("source_address", None), + ) + elif proxy_parsed.scheme[:4] == "http": + # Validate the proxy_ssl argument. + if proxy_parsed.scheme != "https" and proxy_ssl is not None: + raise ValueError( + "proxy_ssl argument is incompatible with an http:// proxy" + ) + # Connect to the server through the proxy. + sock = connect_http_proxy( + proxy_parsed, + ws_uri, + deadline, + user_agent_header=user_agent_header, + ssl=proxy_ssl, + server_hostname=proxy_server_hostname, + **kwargs, + ) + else: + raise AssertionError("unsupported proxy") + else: + kwargs.setdefault("timeout", deadline.timeout()) + sock = socket.create_connection( + (ws_uri.host, ws_uri.port), + **kwargs, + ) + sock.settimeout(None) + + # Disable Nagle algorithm + + if not unix: + sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, True) + + # Initialize TLS wrapper and perform TLS handshake + + if ws_uri.secure: + if ssl is None: + ssl = ssl_module.create_default_context() + if server_hostname is None: + server_hostname = ws_uri.host + sock.settimeout(deadline.timeout()) + if proxy_ssl is None: + sock = ssl.wrap_socket(sock, server_hostname=server_hostname) + else: + sock_2 = SSLSSLSocket(sock, ssl, server_hostname=server_hostname) + # Let's pretend that sock is a socket, even though it isn't. + sock = cast(socket.socket, sock_2) + sock.settimeout(None) + + # Initialize WebSocket protocol + + protocol = ClientProtocol( + ws_uri, + origin=origin, + extensions=extensions, + subprotocols=subprotocols, + max_size=max_size, + logger=logger, + ) + + # Initialize WebSocket connection + + connection = create_connection( + sock, + protocol, + ping_interval=ping_interval, + ping_timeout=ping_timeout, + close_timeout=close_timeout, + max_queue=max_queue, + ) + except Exception: + if sock is not None: + sock.close() + raise + + try: + connection.handshake( + additional_headers, + user_agent_header, + deadline.timeout(), + ) + except Exception: + connection.close_socket() + connection.recv_events_thread.join() + raise + + connection.start_keepalive() + return connection + + +def unix_connect( + path: str | None = None, + uri: str | None = None, + **kwargs: Any, +) -> ClientConnection: + """ + Connect to a WebSocket server listening on a Unix socket. + + This function accepts the same keyword arguments as :func:`connect`. + + It's only available on Unix. + + It's mainly useful for debugging servers listening on Unix sockets. + + Args: + path: File system path to the Unix socket. + uri: URI of the WebSocket server. ``uri`` defaults to + ``ws://localhost/`` or, when a ``ssl`` is provided, to + ``wss://localhost/``. + + """ + if uri is None: + # Backwards compatibility: ssl used to be called ssl_context. + if kwargs.get("ssl") is None and kwargs.get("ssl_context") is None: + uri = "ws://localhost/" + else: + uri = "wss://localhost/" + return connect(uri=uri, unix=True, path=path, **kwargs) + + +try: + from python_socks import ProxyType + from python_socks.sync import Proxy as SocksProxy + +except ImportError: + + def connect_socks_proxy( + proxy: Proxy, + ws_uri: WebSocketURI, + deadline: Deadline, + **kwargs: Any, + ) -> socket.socket: + raise ImportError("connecting through a SOCKS proxy requires python-socks") + +else: + SOCKS_PROXY_TYPES = { + "socks5h": ProxyType.SOCKS5, + "socks5": ProxyType.SOCKS5, + "socks4a": ProxyType.SOCKS4, + "socks4": ProxyType.SOCKS4, + } + + SOCKS_PROXY_RDNS = { + "socks5h": True, + "socks5": False, + "socks4a": True, + "socks4": False, + } + + def connect_socks_proxy( + proxy: Proxy, + ws_uri: WebSocketURI, + deadline: Deadline, + **kwargs: Any, + ) -> socket.socket: + """Connect via a SOCKS proxy and return the socket.""" + socks_proxy = SocksProxy( + SOCKS_PROXY_TYPES[proxy.scheme], + proxy.host, + proxy.port, + proxy.username, + proxy.password, + SOCKS_PROXY_RDNS[proxy.scheme], + ) + kwargs.setdefault("timeout", deadline.timeout()) + # connect() is documented to raise OSError and TimeoutError. + # Wrap other exceptions in ProxyError, a subclass of InvalidHandshake. + try: + return socks_proxy.connect(ws_uri.host, ws_uri.port, **kwargs) + except (OSError, TimeoutError, socket.timeout): + raise + except Exception as exc: + raise ProxyError("failed to connect to SOCKS proxy") from exc + + +def read_connect_response(sock: socket.socket, deadline: Deadline) -> Response: + reader = StreamReader() + parser = Response.parse( + reader.read_line, + reader.read_exact, + reader.read_to_eof, + proxy=True, + ) + try: + while True: + sock.settimeout(deadline.timeout()) + data = sock.recv(4096) + if data: + reader.feed_data(data) + else: + reader.feed_eof() + next(parser) + except StopIteration as exc: + assert isinstance(exc.value, Response) # help mypy + response = exc.value + if 200 <= response.status_code < 300: + return response + else: + raise InvalidProxyStatus(response) + except socket.timeout: + raise TimeoutError("timed out while connecting to HTTP proxy") + except Exception as exc: + raise InvalidProxyMessage( + "did not receive a valid HTTP response from proxy" + ) from exc + finally: + sock.settimeout(None) + + +def connect_http_proxy( + proxy: Proxy, + ws_uri: WebSocketURI, + deadline: Deadline, + *, + user_agent_header: str | None = None, + ssl: ssl_module.SSLContext | None = None, + server_hostname: str | None = None, + **kwargs: Any, +) -> socket.socket: + # Connect socket + + kwargs.setdefault("timeout", deadline.timeout()) + sock = socket.create_connection((proxy.host, proxy.port), **kwargs) + + # Initialize TLS wrapper and perform TLS handshake + + if proxy.scheme == "https": + if ssl is None: + ssl = ssl_module.create_default_context() + if server_hostname is None: + server_hostname = proxy.host + sock.settimeout(deadline.timeout()) + sock = ssl.wrap_socket(sock, server_hostname=server_hostname) + sock.settimeout(None) + + # Send CONNECT request to the proxy and read response. + + sock.sendall(prepare_connect_request(proxy, ws_uri, user_agent_header)) + try: + read_connect_response(sock, deadline) + except Exception: + sock.close() + raise + + return sock + + +T = TypeVar("T") +F = TypeVar("F", bound=Callable[..., T]) + + +class SSLSSLSocket: + """ + Socket-like object providing TLS-in-TLS. + + Only methods that are used by websockets are implemented. + + """ + + recv_bufsize = 65536 + + def __init__( + self, + sock: socket.socket, + ssl_context: ssl_module.SSLContext, + server_hostname: str | None = None, + ) -> None: + self.incoming = ssl_module.MemoryBIO() + self.outgoing = ssl_module.MemoryBIO() + self.ssl_socket = sock + self.ssl_object = ssl_context.wrap_bio( + self.incoming, + self.outgoing, + server_hostname=server_hostname, + ) + self.run_io(self.ssl_object.do_handshake) + + def run_io(self, func: Callable[..., T], *args: Any) -> T: + while True: + want_read = False + want_write = False + try: + result = func(*args) + except ssl_module.SSLWantReadError: + want_read = True + except ssl_module.SSLWantWriteError: # pragma: no cover + want_write = True + + # Write outgoing data in all cases. + data = self.outgoing.read() + if data: + self.ssl_socket.sendall(data) + + # Read incoming data and retry on SSLWantReadError. + if want_read: + data = self.ssl_socket.recv(self.recv_bufsize) + if data: + self.incoming.write(data) + else: + self.incoming.write_eof() + continue + # Retry after writing outgoing data on SSLWantWriteError. + if want_write: # pragma: no cover + continue + # Return result if no error happened. + return result + + def recv(self, buflen: int) -> bytes: + try: + return self.run_io(self.ssl_object.read, buflen) + except ssl_module.SSLEOFError: + return b"" # always ignore ragged EOFs + + def send(self, data: BytesLike) -> int: + return self.run_io(self.ssl_object.write, data) + + def sendall(self, data: BytesLike) -> None: + # adapted from ssl_module.SSLSocket.sendall() + count = 0 + with memoryview(data) as view, view.cast("B") as byte_view: + amount = len(byte_view) + while count < amount: + count += self.send(byte_view[count:]) + + # recv_into(), recvfrom(), recvfrom_into(), sendto(), unwrap(), and the + # flags argument aren't implemented because websockets doesn't need them. + + def __getattr__(self, name: str) -> Any: + return getattr(self.ssl_socket, name) diff --git a/.venv/Lib/site-packages/websockets/sync/connection.py b/.venv/Lib/site-packages/websockets/sync/connection.py new file mode 100644 index 0000000000000000000000000000000000000000..32ba963bf59cbe2df43c842786c0421b5d081ec3 --- /dev/null +++ b/.venv/Lib/site-packages/websockets/sync/connection.py @@ -0,0 +1,1079 @@ +from __future__ import annotations + +import contextlib +import logging +import random +import socket +import struct +import threading +import time +import uuid +from collections.abc import Iterable, Iterator, Mapping +from types import TracebackType +from typing import Any, Literal, overload + +from ..exceptions import ( + ConcurrencyError, + ConnectionClosed, + ConnectionClosedOK, + ProtocolError, +) +from ..frames import DATA_OPCODES, CloseCode, Frame, Opcode +from ..http11 import Request, Response +from ..protocol import CLOSED, OPEN, Event, Protocol, State +from ..typing import BytesLike, Data, DataLike, LoggerLike, Subprotocol +from .messages import Assembler +from .utils import Deadline + + +__all__ = ["Connection"] + + +class Connection: + """ + :mod:`threading` implementation of a WebSocket connection. + + :class:`Connection` provides APIs shared between WebSocket servers and + clients. + + You shouldn't use it directly. Instead, use + :class:`~websockets.sync.client.ClientConnection` or + :class:`~websockets.sync.server.ServerConnection`. + + """ + + recv_bufsize = 65536 + + def __init__( + self, + socket: socket.socket, + protocol: Protocol, + *, + ping_interval: float | None = 20, + ping_timeout: float | None = 20, + close_timeout: float | None = 10, + max_queue: int | None | tuple[int | None, int | None] = 16, + ) -> None: + self.socket = socket + self.protocol = protocol + self.ping_interval = ping_interval + self.ping_timeout = ping_timeout + self.close_timeout = close_timeout + if isinstance(max_queue, int) or max_queue is None: + max_queue_high, max_queue_low = max_queue, None + else: + max_queue_high, max_queue_low = max_queue + + # Inject reference to this instance in the protocol's logger. + self.protocol.logger = logging.LoggerAdapter( + self.protocol.logger, + {"websocket": self}, + ) + + # Copy attributes from the protocol for convenience. + self.id: uuid.UUID = self.protocol.id + """Unique identifier of the connection. Useful in logs.""" + self.logger: LoggerLike = self.protocol.logger + """Logger for this connection.""" + self.debug = self.protocol.debug + + # HTTP handshake request and response. + self.request: Request | None = None + """Opening handshake request.""" + self.response: Response | None = None + """Opening handshake response.""" + + # Mutex serializing interactions with the protocol. + self.protocol_mutex = threading.Lock() + + # Lock stopping reads when the assembler buffer is full. + self.recv_flow_control = threading.Lock() + + # Assembler turning frames into messages and serializing reads. + self.recv_messages = Assembler( + max_queue_high, + max_queue_low, + pause=self.recv_flow_control.acquire, + resume=self.recv_flow_control.release, + ) + + # Deadline for the closing handshake. + self.close_deadline: Deadline | None = None + + # Whether we are busy sending a fragmented message. + self.send_in_progress = False + + # Mapping of ping IDs to pong waiters, in chronological order. + self.pending_pings: dict[bytes, tuple[threading.Event, float, bool]] = {} + + self.latency: float = 0.0 + """ + Latency of the connection, in seconds. + + Latency is defined as the round-trip time of the connection. It is + measured by sending a Ping frame and waiting for a matching Pong frame. + Before the first measurement, :attr:`latency` is ``0.0``. + + By default, websockets enables a :ref:`keepalive ` mechanism + that sends Ping frames automatically at regular intervals. You can also + send Ping frames and measure latency with :meth:`ping`. + """ + + # Thread that sends keepalive pings. None when ping_interval is None. + self.keepalive_thread: threading.Thread | None = None + + # Exception raised while reading from the connection, to be chained to + # ConnectionClosed in order to show why the TCP connection dropped. + self.recv_exc: BaseException | None = None + + # Receiving events from the socket. This thread is marked as daemon to + # allow creating a connection in a non-daemon thread and using it in a + # daemon thread. This mustn't prevent the interpreter from exiting. + self.recv_events_thread = threading.Thread( + target=self.recv_events, + daemon=True, + ) + + # Start recv_events only after all attributes are initialized. + self.recv_events_thread.start() + + # Public attributes + + @property + def local_address(self) -> Any: + """ + Local address of the connection. + + For IPv4 connections, this is a ``(host, port)`` tuple. + + The format of the address depends on the address family. + See :meth:`~socket.socket.getsockname`. + + """ + return self.socket.getsockname() + + @property + def remote_address(self) -> Any: + """ + Remote address of the connection. + + For IPv4 connections, this is a ``(host, port)`` tuple. + + The format of the address depends on the address family. + See :meth:`~socket.socket.getpeername`. + + """ + return self.socket.getpeername() + + @property + def state(self) -> State: + """ + State of the WebSocket connection, defined in :rfc:`6455`. + + This attribute is provided for completeness. Typical applications + shouldn't check its value. Instead, they should call :meth:`~recv` or + :meth:`send` and handle :exc:`~websockets.exceptions.ConnectionClosed` + exceptions. + + """ + return self.protocol.state + + @property + def subprotocol(self) -> Subprotocol | None: + """ + Subprotocol negotiated during the opening handshake. + + :obj:`None` if no subprotocol was negotiated. + + """ + return self.protocol.subprotocol + + @property + def close_code(self) -> int | None: + """ + State of the WebSocket connection, defined in :rfc:`6455`. + + This attribute is provided for completeness. Typical applications + shouldn't check its value. Instead, they should inspect attributes + of :exc:`~websockets.exceptions.ConnectionClosed` exceptions. + + """ + return self.protocol.close_code + + @property + def close_reason(self) -> str | None: + """ + State of the WebSocket connection, defined in :rfc:`6455`. + + This attribute is provided for completeness. Typical applications + shouldn't check its value. Instead, they should inspect attributes + of :exc:`~websockets.exceptions.ConnectionClosed` exceptions. + + """ + return self.protocol.close_reason + + # Public methods + + def __enter__(self) -> Connection: + return self + + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_value: BaseException | None, + traceback: TracebackType | None, + ) -> None: + if exc_type is None: + self.close() + else: + self.close(CloseCode.INTERNAL_ERROR) + + def __iter__(self) -> Iterator[Data]: + """ + Iterate on incoming messages. + + The iterator calls :meth:`recv` and yields messages in an infinite loop. + + It exits when the connection is closed normally. It raises a + :exc:`~websockets.exceptions.ConnectionClosedError` exception after a + protocol error or a network failure. + + """ + try: + while True: + yield self.recv() + except ConnectionClosedOK: + return + + # This overload structure is required to avoid the error: + # "parameter without a default follows parameter with a default" + + @overload + def recv(self, timeout: float | None, decode: Literal[True]) -> str: ... + + @overload + def recv(self, timeout: float | None, decode: Literal[False]) -> bytes: ... + + @overload + def recv(self, timeout: float | None = None, *, decode: Literal[True]) -> str: ... + + @overload + def recv( + self, timeout: float | None = None, *, decode: Literal[False] + ) -> bytes: ... + + @overload + def recv( + self, timeout: float | None = None, decode: bool | None = None + ) -> Data: ... + + def recv(self, timeout: float | None = None, decode: bool | None = None) -> Data: + """ + Receive the next message. + + When the connection is closed, :meth:`recv` raises + :exc:`~websockets.exceptions.ConnectionClosed`. Specifically, it raises + :exc:`~websockets.exceptions.ConnectionClosedOK` after a normal closure + and :exc:`~websockets.exceptions.ConnectionClosedError` after a protocol + error or a network failure. This is how you detect the end of the + message stream. + + If ``timeout`` is :obj:`None`, block until a message is received. If + ``timeout`` is set, wait up to ``timeout`` seconds for a message to be + received and return it, else raise :exc:`TimeoutError`. If ``timeout`` + is ``0`` or negative, check if a message has been received already and + return it, else raise :exc:`TimeoutError`. + + When the message is fragmented, :meth:`recv` waits until all fragments + are received, reassembles them, and returns the whole message. + + Args: + timeout: Timeout for receiving a message in seconds. + decode: Set this flag to override the default behavior of returning + :class:`str` or :class:`bytes`. See below for details. + + Returns: + A string (:class:`str`) for a Text_ frame or a bytestring + (:class:`bytes`) for a Binary_ frame. + + .. _Text: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6 + .. _Binary: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6 + + You may override this behavior with the ``decode`` argument: + + * Set ``decode=False`` to disable UTF-8 decoding of Text_ frames and + return a bytestring (:class:`bytes`). This improves performance + when decoding isn't needed, for example if the message contains + JSON and you're using a JSON library that expects a bytestring. + * Set ``decode=True`` to force UTF-8 decoding of Binary_ frames and + return strings (:class:`str`). This may be useful for servers that + send binary frames instead of text frames. + + Raises: + ConnectionClosed: When the connection is closed. + ConcurrencyError: If two threads call :meth:`recv` or + :meth:`recv_streaming` concurrently. + + """ + try: + return self.recv_messages.get(timeout, decode) + except EOFError: + pass + # fallthrough + except ConcurrencyError: + raise ConcurrencyError( + "cannot call recv while another thread " + "is already running recv or recv_streaming" + ) from None + except UnicodeDecodeError as exc: + with self.send_context(): + self.protocol.fail( + CloseCode.INVALID_DATA, + f"{exc.reason} at position {exc.start}", + ) + # fallthrough + + # Wait for the protocol state to be CLOSED before accessing close_exc. + self.recv_events_thread.join() + raise self.protocol.close_exc from self.recv_exc + + @overload + def recv_streaming(self, decode: Literal[True]) -> Iterator[str]: ... + + @overload + def recv_streaming(self, decode: Literal[False]) -> Iterator[bytes]: ... + + @overload + def recv_streaming(self, decode: bool | None = None) -> Iterator[Data]: ... + + def recv_streaming(self, decode: bool | None = None) -> Iterator[Data]: + """ + Receive the next message frame by frame. + + This method is designed for receiving fragmented messages. It returns an + iterator that yields each fragment as it is received. This iterator must + be fully consumed. Else, future calls to :meth:`recv` or + :meth:`recv_streaming` will raise + :exc:`~websockets.exceptions.ConcurrencyError`, making the connection + unusable. + + :meth:`recv_streaming` raises the same exceptions as :meth:`recv`. + + Args: + decode: Set this flag to override the default behavior of returning + :class:`str` or :class:`bytes`. See below for details. + + Returns: + An iterator of strings (:class:`str`) for a Text_ frame or + bytestrings (:class:`bytes`) for a Binary_ frame. + + .. _Text: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6 + .. _Binary: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6 + + You may override this behavior with the ``decode`` argument: + + * Set ``decode=False`` to disable UTF-8 decoding of Text_ frames and + yield bytestrings (:class:`bytes`). This improves performance + when decoding isn't needed. + * Set ``decode=True`` to force UTF-8 decoding of Binary_ frames and + yield strings (:class:`str`). This may be useful for servers that + send binary frames instead of text frames. + + Raises: + ConnectionClosed: When the connection is closed. + ConcurrencyError: If two threads call :meth:`recv` or + :meth:`recv_streaming` concurrently. + + """ + try: + yield from self.recv_messages.get_iter(decode) + return + except EOFError: + pass + # fallthrough + except ConcurrencyError: + raise ConcurrencyError( + "cannot call recv_streaming while another thread " + "is already running recv or recv_streaming" + ) from None + except UnicodeDecodeError as exc: + with self.send_context(): + self.protocol.fail( + CloseCode.INVALID_DATA, + f"{exc.reason} at position {exc.start}", + ) + # fallthrough + + # Wait for the protocol state to be CLOSED before accessing close_exc. + self.recv_events_thread.join() + raise self.protocol.close_exc from self.recv_exc + + def send( + self, + message: DataLike | Iterable[DataLike], + text: bool | None = None, + ) -> None: + """ + Send a message. + + A string (:class:`str`) is sent as a Text_ frame. A bytestring or + bytes-like object (:class:`bytes`, :class:`bytearray`, or + :class:`memoryview`) is sent as a Binary_ frame. + + .. _Text: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6 + .. _Binary: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6 + + You may override this behavior with the ``text`` argument: + + * Set ``text=True`` to send an UTF-8 bytestring or bytes-like object + (:class:`bytes`, :class:`bytearray`, or :class:`memoryview`) in a + Text_ frame. This improves performance when the message is already + UTF-8 encoded, for example if the message contains JSON and you're + using a JSON library that produces a bytestring. + * Set ``text=False`` to send a string (:class:`str`) in a Binary_ + frame. This may be useful for servers that expect binary frames + instead of text frames. + + :meth:`send` also accepts an iterable of strings, bytestrings, or + bytes-like objects to enable fragmentation_. Each item is treated as a + message fragment and sent in its own frame. All items must be of the + same type, or else :meth:`send` will raise a :exc:`TypeError` and the + connection will be closed. + + .. _fragmentation: https://datatracker.ietf.org/doc/html/rfc6455#section-5.4 + + :meth:`send` rejects dict-like objects because this is often an error. + (If you really want to send the keys of a dict-like object as fragments, + call its :meth:`~dict.keys` method and pass the result to :meth:`send`.) + + When the connection is closed, :meth:`send` raises + :exc:`~websockets.exceptions.ConnectionClosed`. Specifically, it + raises :exc:`~websockets.exceptions.ConnectionClosedOK` after a normal + connection closure and + :exc:`~websockets.exceptions.ConnectionClosedError` after a protocol + error or a network failure. + + Args: + message: Message to send. + text: Force sending in a Text_ or Binary_ frame. + + Raises: + ConnectionClosed: When the connection is closed. + ConcurrencyError: If the connection is sending a fragmented message. + TypeError: If ``message`` doesn't have a supported type. + + """ + # Unfragmented message -- this case must be handled first because + # strings and bytes-like objects are iterable. + + if isinstance(message, str): + with self.send_context(): + if self.send_in_progress: + raise ConcurrencyError( + "cannot call send while another thread is already running send" + ) + if text is False: + self.protocol.send_binary(message.encode()) + else: + self.protocol.send_text(message.encode()) + + elif isinstance(message, BytesLike): + with self.send_context(): + if self.send_in_progress: + raise ConcurrencyError( + "cannot call send while another thread is already running send" + ) + if text is True: + self.protocol.send_text(message) + else: + self.protocol.send_binary(message) + + # Catch a common mistake -- passing a dict to send(). + + elif isinstance(message, Mapping): + raise TypeError("data is a dict-like object") + + # Fragmented message -- regular iterator. + + elif isinstance(message, Iterable): + chunks = iter(message) + try: + chunk = next(chunks) + except StopIteration: + return + + try: + # First fragment. + if isinstance(chunk, str): + with self.send_context(): + if self.send_in_progress: + raise ConcurrencyError( + "cannot call send while another thread " + "is already running send" + ) + self.send_in_progress = True + if text is False: + self.protocol.send_binary(chunk.encode(), fin=False) + else: + self.protocol.send_text(chunk.encode(), fin=False) + encode = True + elif isinstance(chunk, BytesLike): + with self.send_context(): + if self.send_in_progress: + raise ConcurrencyError( + "cannot call send while another thread " + "is already running send" + ) + self.send_in_progress = True + if text is True: + self.protocol.send_text(chunk, fin=False) + else: + self.protocol.send_binary(chunk, fin=False) + encode = False + else: + raise TypeError("iterable must contain bytes or str") + + # Other fragments + for chunk in chunks: + if isinstance(chunk, str) and encode: + with self.send_context(): + assert self.send_in_progress + self.protocol.send_continuation(chunk.encode(), fin=False) + elif isinstance(chunk, BytesLike) and not encode: + with self.send_context(): + assert self.send_in_progress + self.protocol.send_continuation(chunk, fin=False) + else: + raise TypeError("iterable must contain uniform types") + + # Final fragment. + with self.send_context(): + self.protocol.send_continuation(b"", fin=True) + self.send_in_progress = False + + except ConcurrencyError: + # We didn't start sending a fragmented message. + # The connection is still usable. + raise + + except Exception: + # We're half-way through a fragmented message and we can't + # complete it. This makes the connection unusable. + with self.send_context(): + self.protocol.fail( + CloseCode.INTERNAL_ERROR, + "error in fragmented message", + ) + raise + + else: + raise TypeError("data must be str, bytes, or iterable") + + def close( + self, + code: CloseCode | int = CloseCode.NORMAL_CLOSURE, + reason: str = "", + ) -> None: + """ + Perform the closing handshake. + + :meth:`close` waits for the other end to complete the handshake and + for the TCP connection to terminate. + + :meth:`close` is idempotent: it doesn't do anything once the + connection is closed. + + Args: + code: WebSocket close code. + reason: WebSocket close reason. + + """ + try: + # The context manager takes care of waiting for the TCP connection + # to terminate after calling a method that sends a close frame. + with self.send_context(): + if self.send_in_progress: + self.protocol.fail( + CloseCode.INTERNAL_ERROR, + "close during fragmented message", + ) + else: + self.protocol.send_close(code, reason) + except ConnectionClosed: + # Ignore ConnectionClosed exceptions raised from send_context(). + # They mean that the connection is closed, which was the goal. + pass + + def ping( + self, + data: DataLike | None = None, + ack_on_close: bool = False, + ) -> threading.Event: + """ + Send a Ping_. + + .. _Ping: https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.2 + + A ping may serve as a keepalive or as a check that the remote endpoint + received all messages up to this point + + Args: + data: Payload of the ping. A :class:`str` will be encoded to UTF-8. + If ``data`` is :obj:`None`, the payload is four random bytes. + ack_on_close: when this option is :obj:`True`, the event will also + be set when the connection is closed. While this avoids getting + stuck waiting for a pong that will never arrive, it requires + checking that the state of the connection is still ``OPEN`` to + confirm that a pong was received, rather than the connection + being closed. + + Returns: + An event that will be set when the corresponding pong is received. + You can ignore it if you don't intend to wait. + + :: + + pong_received = ws.ping() + # only if you want to wait for the corresponding pong + pong_received.wait() + + Raises: + ConnectionClosed: When the connection is closed. + ConcurrencyError: If another ping was sent with the same data and + the corresponding pong wasn't received yet. + + """ + if isinstance(data, BytesLike): + data = bytes(data) + elif isinstance(data, str): + data = data.encode() + elif data is not None: + raise TypeError("data must be str or bytes-like") + + with self.send_context(): + # Protect against duplicates if a payload is explicitly set. + if data in self.pending_pings: + raise ConcurrencyError("already waiting for a pong with the same data") + + # Generate a unique random payload otherwise. + while data is None or data in self.pending_pings: + data = struct.pack("!I", random.getrandbits(32)) + + pong_received = threading.Event() + ping_timestamp = time.monotonic() + self.pending_pings[data] = (pong_received, ping_timestamp, ack_on_close) + self.protocol.send_ping(data) + return pong_received + + def pong(self, data: DataLike = b"") -> None: + """ + Send a Pong_. + + .. _Pong: https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.3 + + An unsolicited pong may serve as a unidirectional heartbeat. + + Args: + data: Payload of the pong. A :class:`str` will be encoded to UTF-8. + + Raises: + ConnectionClosed: When the connection is closed. + + """ + if isinstance(data, BytesLike): + data = bytes(data) + elif isinstance(data, str): + data = data.encode() + else: + raise TypeError("data must be str or bytes-like") + + with self.send_context(): + self.protocol.send_pong(data) + + # Private methods + + def process_event(self, event: Event) -> None: + """ + Process one incoming event. + + This method is overridden in subclasses to handle the handshake. + + """ + assert isinstance(event, Frame) + if event.opcode in DATA_OPCODES: + self.recv_messages.put(event) + + if event.opcode is Opcode.PONG: + self.acknowledge_pings(bytes(event.data)) + + def acknowledge_pings(self, data: bytes) -> None: + """ + Acknowledge pings when receiving a pong. + + """ + with self.protocol_mutex: + # Ignore unsolicited pong. + if data not in self.pending_pings: + return + + pong_timestamp = time.monotonic() + + # Sending a pong for only the most recent ping is legal. + # Acknowledge all previous pings too in that case. + ping_id = None + ping_ids = [] + for ping_id, ( + pong_received, + ping_timestamp, + _ack_on_close, + ) in self.pending_pings.items(): + ping_ids.append(ping_id) + pong_received.set() + if ping_id == data: + self.latency = pong_timestamp - ping_timestamp + break + else: + raise AssertionError("solicited pong not found in pings") + + # Remove acknowledged pings from self.pending_pings. + for ping_id in ping_ids: + del self.pending_pings[ping_id] + + def terminate_pending_pings(self) -> None: + """ + Acknowledge pending pings when the connection is closed. + + """ + assert self.protocol_mutex.locked() + assert self.protocol.state is CLOSED + + for pong_received, _ping_timestamp, ack_on_close in self.pending_pings.values(): + if ack_on_close: + pong_received.set() + + self.pending_pings.clear() + + def keepalive(self) -> None: + """ + Send a Ping frame and wait for a Pong frame at regular intervals. + + """ + assert self.ping_interval is not None + try: + while True: + # If self.ping_timeout > self.latency > self.ping_interval, + # pings will be sent immediately after receiving pongs. + # The period will be longer than self.ping_interval. + self.recv_events_thread.join(self.ping_interval - self.latency) + if not self.recv_events_thread.is_alive(): + break + + try: + pong_received = self.ping(ack_on_close=True) + except ConnectionClosed: + break + if self.debug: + self.logger.debug("% sent keepalive ping") + + if self.ping_timeout is not None: + if pong_received.wait(self.ping_timeout): + if self.debug: + self.logger.debug("% received keepalive pong") + else: + if self.debug: + self.logger.debug("- timed out waiting for keepalive pong") + with self.send_context(): + self.protocol.fail( + CloseCode.INTERNAL_ERROR, + "keepalive ping timeout", + ) + break + except Exception: + self.logger.error("keepalive ping failed", exc_info=True) + + def start_keepalive(self) -> None: + """ + Run :meth:`keepalive` in a thread, unless keepalive is disabled. + + """ + if self.ping_interval is not None: + # This thread is marked as daemon like self.recv_events_thread. + self.keepalive_thread = threading.Thread( + target=self.keepalive, + daemon=True, + ) + self.keepalive_thread.start() + + def recv_events(self) -> None: + """ + Read incoming data from the socket and process events. + + Run this method in a thread as long as the connection is alive. + + ``recv_events()`` exits immediately when ``self.socket`` is closed. + + """ + try: + while True: + try: + # If the assembler buffer is full, block until it drains. + with self.recv_flow_control: + pass + if self.close_deadline is not None: + self.socket.settimeout(self.close_deadline.timeout()) + data = self.socket.recv(self.recv_bufsize) + except Exception as exc: + if self.debug: + self.logger.debug( + "! error while receiving data", + exc_info=True, + ) + # When the closing handshake is initiated by our side, + # recv() may block until send_context() closes the socket. + # In that case, send_context() already set recv_exc. + # Calling set_recv_exc() avoids overwriting it. + with self.protocol_mutex: + self.set_recv_exc(exc) + break + + if data == b"": + break + + # Acquire the connection lock. + with self.protocol_mutex: + # Feed incoming data to the protocol. + self.protocol.receive_data(data) + + # This isn't expected to raise an exception. + events = self.protocol.events_received() + + # Write outgoing data to the socket. + try: + self.send_data() + except Exception as exc: + if self.debug: + self.logger.debug( + "! error while sending data", + exc_info=True, + ) + # Similarly to the above, avoid overriding an exception + # set by send_context(), in case of a race condition + # i.e. send_context() closes the socket after recv() + # returns above but before send_data() calls send(). + self.set_recv_exc(exc) + break + + # If needed, set the close deadline based on the close timeout. + if self.protocol.close_expected(): + if self.close_deadline is None: + self.close_deadline = Deadline(self.close_timeout) + + # Unlock conn_mutex before processing events. Else, the + # application can't send messages in response to events. + + # If self.send_data raised an exception, then events are lost. + # Given that automatic responses write small amounts of data, + # this should be uncommon, so we don't handle the edge case. + + for event in events: + # This isn't expected to raise an exception. + self.process_event(event) + + # Breaking out of the while True: ... loop means that we believe + # that the socket doesn't work anymore. + + with self.protocol_mutex: + # Feed the end of the data stream to the protocol. + self.protocol.receive_eof() + + # This isn't expected to raise an exception. + events = self.protocol.events_received() + + # There is no error handling because send_data() can only write + # the end of the data stream and it handles errors by itself. + self.send_data() + + # This code path is triggered when receiving an HTTP response + # without a Content-Length header. This is the only case where + # reading until EOF generates an event; all other events have + # a known length. Ignore for coverage measurement because tests + # are in test_client.py rather than test_connection.py. + for event in events: # pragma: no cover + # This isn't expected to raise an exception. + self.process_event(event) + + except Exception as exc: + # This branch should never run. It's a safety net in case of bugs. + self.logger.error("unexpected internal error", exc_info=True) + with self.protocol_mutex: + self.set_recv_exc(exc) + finally: + # This isn't expected to raise an exception. + self.close_socket() + + @contextlib.contextmanager + def send_context( + self, + *, + expected_state: State = OPEN, # CONNECTING during the opening handshake + ) -> Iterator[None]: + """ + Create a context for writing to the connection from user code. + + On entry, :meth:`send_context` acquires the connection lock and checks + that the connection is open; on exit, it writes outgoing data to the + socket and releases the connection lock:: + + with self.send_context(): + self.protocol.send_text(message.encode()) + + When the connection isn't open on entry, when the connection is expected + to close on exit, or when an unexpected error happens, terminating the + connection, :meth:`send_context` waits until the connection is closed + then raises :exc:`~websockets.exceptions.ConnectionClosed`. + + """ + # Should we wait until the connection is closed? + wait_for_close = False + # Should we close the socket and raise ConnectionClosed? + raise_close_exc = False + # What exception should we chain ConnectionClosed to? + original_exc: BaseException | None = None + + # Acquire the protocol lock. + with self.protocol_mutex: + if self.protocol.state is expected_state: + # Let the caller interact with the protocol. + try: + yield + except (ProtocolError, ConcurrencyError): + # The protocol state wasn't changed. Exit immediately. + raise + except Exception as exc: + self.logger.error("unexpected internal error", exc_info=True) + # This branch should never run. It's a safety net in case of + # bugs. Since we don't know what happened, we will close the + # connection and raise the exception to the caller. + wait_for_close = False + raise_close_exc = True + original_exc = exc + else: + # Check if the connection is expected to close soon. + if self.protocol.close_expected(): + wait_for_close = True + # Set the close deadline based on the close timeout. + # Since we tested earlier that protocol.state is OPEN + # (or CONNECTING) and we didn't release protocol_mutex, + # self.close_deadline is still None. + assert self.close_deadline is None + self.close_deadline = Deadline(self.close_timeout) + # Write outgoing data to the socket. + try: + self.send_data() + except Exception as exc: + if self.debug: + self.logger.debug( + "! error while sending data", + exc_info=True, + ) + # While the only expected exception here is OSError, + # other exceptions would be treated identically. + wait_for_close = False + raise_close_exc = True + original_exc = exc + + else: # self.protocol.state is not expected_state + # Minor layering violation: we assume that the connection + # will be closing soon if it isn't in the expected state. + wait_for_close = True + # Calculate close_deadline if it wasn't set yet. + if self.close_deadline is None: + self.close_deadline = Deadline(self.close_timeout) + raise_close_exc = True + + # To avoid a deadlock, release the connection lock by exiting the + # context manager before waiting for recv_events() to terminate. + + # If the connection is expected to close soon and the close timeout + # elapses, close the socket to terminate the connection. + if wait_for_close: + # Thread.join() returns immediately if timeout is negative. + assert self.close_deadline is not None + timeout = self.close_deadline.timeout(raise_if_elapsed=False) + self.recv_events_thread.join(timeout) + if self.recv_events_thread.is_alive(): + # There's no risk of overwriting another error because + # original_exc is never set when wait_for_close is True. + assert original_exc is None + original_exc = TimeoutError("timed out while closing connection") + # Set recv_exc before closing the socket in order to get + # proper exception reporting. + raise_close_exc = True + with self.protocol_mutex: + self.set_recv_exc(original_exc) + + # If an error occurred, close the socket to terminate the connection and + # raise an exception. + if raise_close_exc: + self.close_socket() + # Wait for the protocol state to be CLOSED before accessing close_exc. + self.recv_events_thread.join() + raise self.protocol.close_exc from original_exc + + def send_data(self) -> None: + """ + Send outgoing data. + + This method requires holding protocol_mutex. + + """ + assert self.protocol_mutex.locked() + for data in self.protocol.data_to_send(): + if data: + if self.close_deadline is not None: + self.socket.settimeout(self.close_deadline.timeout()) + self.socket.sendall(data) + else: + try: + self.socket.shutdown(socket.SHUT_WR) + except OSError: # socket already closed + pass + + def set_recv_exc(self, exc: BaseException | None) -> None: + """ + Set recv_exc, if not set yet. + + This method requires holding protocol_mutex and must be called only from + the thread running recv_events(). + + """ + assert self.protocol_mutex.locked() + if self.recv_exc is None: + self.recv_exc = exc + + def close_socket(self) -> None: + """ + Shutdown and close socket. Close message assembler. + + Calling close_socket() guarantees that recv_events() terminates. Indeed, + recv_events() may block only on socket.recv() or on recv_messages.put(). + + """ + # shutdown() is required to interrupt recv() on Linux. + try: + self.socket.shutdown(socket.SHUT_RDWR) + except OSError: # socket already closed + pass + self.socket.close() + + # Calling protocol.receive_eof() is safe because it's idempotent. + # This guarantees that the protocol state becomes CLOSED. + with self.protocol_mutex: + self.protocol.receive_eof() + assert self.protocol.state is CLOSED + + # Abort recv() with a ConnectionClosed exception. + self.recv_messages.close() + + # Acknowledge pings sent with the ack_on_close option. + self.terminate_pending_pings() diff --git a/.venv/Lib/site-packages/websockets/sync/messages.py b/.venv/Lib/site-packages/websockets/sync/messages.py new file mode 100644 index 0000000000000000000000000000000000000000..127f44430640de1e70effbfeaf1a989518276b42 --- /dev/null +++ b/.venv/Lib/site-packages/websockets/sync/messages.py @@ -0,0 +1,348 @@ +from __future__ import annotations + +import codecs +import queue +import threading +from typing import Any, Callable, Iterable, Iterator, Literal, overload + +from ..exceptions import ConcurrencyError +from ..frames import OP_BINARY, OP_CONT, OP_TEXT, Frame +from ..typing import Data +from .utils import Deadline + + +__all__ = ["Assembler"] + +UTF8Decoder = codecs.getincrementaldecoder("utf-8") + + +class Assembler: + """ + Assemble messages from frames. + + :class:`Assembler` expects only data frames. The stream of frames must + respect the protocol; if it doesn't, the behavior is undefined. + + Args: + pause: Called when the buffer of frames goes above the high water mark; + should pause reading from the network. + resume: Called when the buffer of frames goes below the low water mark; + should resume reading from the network. + + """ + + def __init__( + self, + high: int | None = None, + low: int | None = None, + pause: Callable[[], Any] = lambda: None, + resume: Callable[[], Any] = lambda: None, + ) -> None: + # Serialize reads and writes -- except for reads via synchronization + # primitives provided by the threading and queue modules. + self.mutex = threading.Lock() + + # Queue of incoming frames. + self.frames: queue.SimpleQueue[Frame | None] = queue.SimpleQueue() + + # We cannot put a hard limit on the size of the queue because a single + # call to Protocol.data_received() could produce thousands of frames, + # which must be buffered. Instead, we pause reading when the buffer goes + # above the high limit and we resume when it goes under the low limit. + if high is not None and low is None: + low = high // 4 + if high is None and low is not None: + high = low * 4 + if high is not None and low is not None: + if low < 0: + raise ValueError("low must be positive or equal to zero") + if high < low: + raise ValueError("high must be greater than or equal to low") + self.high, self.low = high, low + self.pause = pause + self.resume = resume + self.paused = False + + # This flag prevents concurrent calls to get() by user code. + self.get_in_progress = False + + # This flag marks the end of the connection. + self.closed = False + + def get_next_frame(self, timeout: float | None = None) -> Frame: + # Helper to factor out the logic for getting the next frame from the + # queue, while handling timeouts and reaching the end of the stream. + if self.closed: + try: + frame = self.frames.get(block=False) + except queue.Empty: + raise EOFError("stream of frames ended") from None + else: + try: + # Check for a frame that's already received if timeout <= 0. + # SimpleQueue.get() doesn't support negative timeout values. + if timeout is not None and timeout <= 0: + frame = self.frames.get(block=False) + else: + frame = self.frames.get(block=True, timeout=timeout) + except queue.Empty: + raise TimeoutError(f"timed out in {timeout:.1f}s") from None + if frame is None: + raise EOFError("stream of frames ended") + return frame + + def reset_queue(self, frames: Iterable[Frame]) -> None: + # Helper to put frames back into the queue after they were fetched. + # This happens only when the queue is empty. However, by the time + # we acquire self.mutex, put() may have added items in the queue. + # Therefore, we must handle the case where the queue is not empty. + frame: Frame | None + with self.mutex: + queued = [] + try: + while True: + queued.append(self.frames.get(block=False)) + except queue.Empty: + pass + for frame in frames: + self.frames.put(frame) + # This loop runs only when a race condition occurs. + for frame in queued: # pragma: no cover + self.frames.put(frame) + + # This overload structure is required to avoid the error: + # "parameter without a default follows parameter with a default" + + @overload + def get(self, timeout: float | None, decode: Literal[True]) -> str: ... + + @overload + def get(self, timeout: float | None, decode: Literal[False]) -> bytes: ... + + @overload + def get(self, timeout: float | None = None, *, decode: Literal[True]) -> str: ... + + @overload + def get(self, timeout: float | None = None, *, decode: Literal[False]) -> bytes: ... + + @overload + def get(self, timeout: float | None = None, decode: bool | None = None) -> Data: ... + + def get(self, timeout: float | None = None, decode: bool | None = None) -> Data: + """ + Read the next message. + + :meth:`get` returns a single :class:`str` or :class:`bytes`. + + If the message is fragmented, :meth:`get` waits until the last frame is + received, then it reassembles the message and returns it. To receive + messages frame by frame, use :meth:`get_iter` instead. + + Args: + timeout: If a timeout is provided and elapses before a complete + message is received, :meth:`get` raises :exc:`TimeoutError`. + decode: :obj:`False` disables UTF-8 decoding of text frames and + returns :class:`bytes`. :obj:`True` forces UTF-8 decoding of + binary frames and returns :class:`str`. + + Raises: + EOFError: If the stream of frames has ended. + UnicodeDecodeError: If a text frame contains invalid UTF-8. + ConcurrencyError: If two coroutines run :meth:`get` or + :meth:`get_iter` concurrently. + TimeoutError: If a timeout is provided and elapses before a + complete message is received. + + """ + with self.mutex: + if self.get_in_progress: + raise ConcurrencyError("get() or get_iter() is already running") + self.get_in_progress = True + + # Locking with get_in_progress prevents concurrent execution + # until get() fetches a complete message or times out. + + try: + deadline = Deadline(timeout) + + # Fetch the first frame. + frame = self.get_next_frame(deadline.timeout(raise_if_elapsed=False)) + with self.mutex: + self.maybe_resume() + assert frame.opcode is OP_TEXT or frame.opcode is OP_BINARY + if decode is None: + decode = frame.opcode is OP_TEXT + frames = [frame] + + # Fetch subsequent frames for fragmented messages. + while not frame.fin: + try: + frame = self.get_next_frame( + deadline.timeout(raise_if_elapsed=False) + ) + except TimeoutError: + # Put frames already received back into the queue + # so that future calls to get() can return them. + self.reset_queue(frames) + raise + with self.mutex: + self.maybe_resume() + assert frame.opcode is OP_CONT + frames.append(frame) + + finally: + self.get_in_progress = False + + # This converts frame.data to bytes when it's a bytearray. + data = b"".join(frame.data for frame in frames) + if decode: + return data.decode() + else: + return data + + @overload + def get_iter(self, decode: Literal[True]) -> Iterator[str]: ... + + @overload + def get_iter(self, decode: Literal[False]) -> Iterator[bytes]: ... + + @overload + def get_iter(self, decode: bool | None = None) -> Iterator[Data]: ... + + def get_iter(self, decode: bool | None = None) -> Iterator[Data]: + """ + Stream the next message. + + Iterating the return value of :meth:`get_iter` yields a :class:`str` or + :class:`bytes` for each frame in the message. + + The iterator must be fully consumed before calling :meth:`get_iter` or + :meth:`get` again. Else, :exc:`ConcurrencyError` is raised. + + This method only makes sense for fragmented messages. If messages aren't + fragmented, use :meth:`get` instead. + + Args: + decode: :obj:`False` disables UTF-8 decoding of text frames and + returns :class:`bytes`. :obj:`True` forces UTF-8 decoding of + binary frames and returns :class:`str`. + + Raises: + EOFError: If the stream of frames has ended. + UnicodeDecodeError: If a text frame contains invalid UTF-8. + ConcurrencyError: If two coroutines run :meth:`get` or + :meth:`get_iter` concurrently. + + """ + with self.mutex: + if self.get_in_progress: + raise ConcurrencyError("get() or get_iter() is already running") + self.get_in_progress = True + + # Locking with get_in_progress prevents concurrent execution + # until get_iter() fetches a complete message or times out. + + # If get_iter() raises an exception e.g. in decoder.decode(), + # get_in_progress remains set and the connection becomes unusable. + + # Yield the first frame. + frame = self.get_next_frame() + with self.mutex: + self.maybe_resume() + assert frame.opcode is OP_TEXT or frame.opcode is OP_BINARY + if decode is None: + decode = frame.opcode is OP_TEXT + if decode: + decoder = UTF8Decoder() + yield decoder.decode(frame.data, frame.fin) + else: + # Convert to bytes when frame.data is a bytearray. + yield bytes(frame.data) + + # Yield subsequent frames for fragmented messages. + while not frame.fin: + frame = self.get_next_frame() + with self.mutex: + self.maybe_resume() + assert frame.opcode is OP_CONT + if decode: + yield decoder.decode(frame.data, frame.fin) + else: + # Convert to bytes when frame.data is a bytearray. + yield bytes(frame.data) + + self.get_in_progress = False + + def put(self, frame: Frame) -> None: + """ + Add ``frame`` to the next message. + + Raises: + EOFError: If the stream of frames has ended. + + """ + with self.mutex: + if self.closed: + raise EOFError("stream of frames ended") + + self.frames.put(frame) + self.maybe_pause() + + # put() and get/get_iter() call maybe_pause() and maybe_resume() while + # holding self.mutex. This guarantees that the calls interleave properly. + # Specifically, it prevents a race condition where maybe_resume() would + # run before maybe_pause(), leaving the connection incorrectly paused. + + # A race condition is possible when get/get_iter() call self.frames.get() + # without holding self.mutex. However, it's harmless β€” and even beneficial! + # It can only result in popping an item from the queue before maybe_resume() + # runs and skipping a pause() - resume() cycle that would otherwise occur. + + def maybe_pause(self) -> None: + """Pause the writer if queue is above the high water mark.""" + # Skip if flow control is disabled. + if self.high is None: + return + + assert self.mutex.locked() + + # Check for "> high" to support high = 0. + if self.frames.qsize() > self.high and not self.paused: + self.paused = True + self.pause() + + def maybe_resume(self) -> None: + """Resume the writer if queue is below the low water mark.""" + # Skip if flow control is disabled. + if self.low is None: + return + + assert self.mutex.locked() + + # Check for "<= low" to support low = 0. + if self.frames.qsize() <= self.low and self.paused: + self.paused = False + self.resume() + + def close(self) -> None: + """ + End the stream of frames. + + Calling :meth:`close` concurrently with :meth:`get`, :meth:`get_iter`, + or :meth:`put` is safe. They will raise :exc:`EOFError`. + + """ + with self.mutex: + if self.closed: + return + + self.closed = True + + if self.get_in_progress: + # Unblock get() or get_iter(). + self.frames.put(None) + + if self.paused: + # Unblock recv_events(). + self.paused = False + self.resume() diff --git a/.venv/Lib/site-packages/websockets/sync/router.py b/.venv/Lib/site-packages/websockets/sync/router.py new file mode 100644 index 0000000000000000000000000000000000000000..99af23b313896f0242c4a313dd3b4d1a61b28eed --- /dev/null +++ b/.venv/Lib/site-packages/websockets/sync/router.py @@ -0,0 +1,213 @@ +from __future__ import annotations + +import http +import ssl as ssl_module +import urllib.parse +from typing import Any, Callable, Literal + +from ..http11 import Request, Response +from .server import Server, ServerConnection, serve + + +__all__ = ["route", "unix_route", "Router"] + + +try: + from werkzeug.exceptions import NotFound + from werkzeug.routing import Map, RequestRedirect + +except ImportError: + + def route( + url_map: Map, + *args: Any, + server_name: str | None = None, + ssl: ssl_module.SSLContext | Literal[True] | None = None, + create_router: type[Router] | None = None, + **kwargs: Any, + ) -> Server: + raise ImportError("route() requires werkzeug") + + def unix_route( + url_map: Map, + path: str | None = None, + **kwargs: Any, + ) -> Server: + raise ImportError("unix_route() requires werkzeug") + +else: + + def route( + url_map: Map, + *args: Any, + server_name: str | None = None, + ssl: ssl_module.SSLContext | Literal[True] | None = None, + create_router: type[Router] | None = None, + **kwargs: Any, + ) -> Server: + """ + Create a WebSocket server dispatching connections to different handlers. + + This feature requires the third-party library `werkzeug`_: + + .. code-block:: console + + $ pip install werkzeug + + .. _werkzeug: https://werkzeug.palletsprojects.com/ + + :func:`route` accepts the same arguments as + :func:`~websockets.sync.server.serve`, except as described below. + + The first argument is a :class:`werkzeug.routing.Map` that maps URL patterns + to connection handlers. In addition to the connection, handlers receive + parameters captured in the URL as keyword arguments. + + Here's an example:: + + + from websockets.sync.router import route + from werkzeug.routing import Map, Rule + + def channel_handler(websocket, channel_id): + ... + + url_map = Map([ + Rule("/channel/", endpoint=channel_handler), + ... + ]) + + with route(url_map, ...) as server: + server.serve_forever() + + Refer to the documentation of :mod:`werkzeug.routing` for details. + + If you define redirects with ``Rule(..., redirect_to=...)`` in the URL map, + when the server runs behind a reverse proxy that modifies the ``Host`` + header or terminates TLS, you need additional configuration: + + * Set ``server_name`` to the name of the server as seen by clients. When + not provided, websockets uses the value of the ``Host`` header. + + * Set ``ssl=True`` to generate ``wss://`` URIs without enabling TLS. + Under the hood, this bind the URL map with a ``url_scheme`` of + ``wss://`` instead of ``ws://``. + + There is no need to specify ``websocket=True`` in each rule. It is added + automatically. + + Args: + url_map: Mapping of URL patterns to connection handlers. + server_name: Name of the server as seen by clients. If :obj:`None`, + websockets uses the value of the ``Host`` header. + ssl: Configuration for enabling TLS on the connection. Set it to + :obj:`True` if a reverse proxy terminates TLS connections. + create_router: Factory for the :class:`Router` dispatching requests to + handlers. Set it to a wrapper or a subclass to customize routing. + + """ + url_scheme = "ws" if ssl is None else "wss" + if ssl is not True and ssl is not None: + kwargs["ssl"] = ssl + + if create_router is None: + create_router = Router + + router = create_router(url_map, server_name, url_scheme) + + _process_request: ( + Callable[ + [ServerConnection, Request], + Response | None, + ] + | None + ) = kwargs.pop("process_request", None) + if _process_request is None: + process_request: Callable[ + [ServerConnection, Request], + Response | None, + ] = router.route_request + else: + + def process_request( + connection: ServerConnection, request: Request + ) -> Response | None: + response = _process_request(connection, request) + if response is not None: + return response + return router.route_request(connection, request) + + return serve(router.handler, *args, process_request=process_request, **kwargs) + + def unix_route( + url_map: Map, + path: str | None = None, + **kwargs: Any, + ) -> Server: + """ + Create a WebSocket Unix server dispatching connections to different handlers. + + :func:`unix_route` combines the behaviors of :func:`route` and + :func:`~websockets.sync.server.unix_serve`. + + Args: + url_map: Mapping of URL patterns to connection handlers. + path: File system path to the Unix socket. + + """ + return route(url_map, unix=True, path=path, **kwargs) + + +class Router: + """WebSocket router supporting :func:`route`.""" + + def __init__( + self, + url_map: Map, + server_name: str | None = None, + url_scheme: str = "ws", + ) -> None: + self.url_map = url_map + self.server_name = server_name + self.url_scheme = url_scheme + for rule in self.url_map.iter_rules(): + rule.websocket = True + + def get_server_name(self, connection: ServerConnection, request: Request) -> str: + if self.server_name is None: + return request.headers["Host"] + else: + return self.server_name + + def redirect(self, connection: ServerConnection, url: str) -> Response: + response = connection.respond(http.HTTPStatus.FOUND, f"Found at {url}") + response.headers["Location"] = url + return response + + def not_found(self, connection: ServerConnection) -> Response: + return connection.respond(http.HTTPStatus.NOT_FOUND, "Not Found") + + def route_request( + self, connection: ServerConnection, request: Request + ) -> Response | None: + """Route incoming request.""" + url_map_adapter = self.url_map.bind( + server_name=self.get_server_name(connection, request), + url_scheme=self.url_scheme, + ) + try: + parsed = urllib.parse.urlparse(request.path) + handler, kwargs = url_map_adapter.match( + path_info=parsed.path, + query_args=parsed.query, + ) + except RequestRedirect as redirect: + return self.redirect(connection, redirect.new_url) + except NotFound: + return self.not_found(connection) + connection.handler, connection.handler_kwargs = handler, kwargs + return None + + def handler(self, connection: ServerConnection) -> None: + """Handle a connection.""" + return connection.handler(connection, **connection.handler_kwargs) diff --git a/.venv/Lib/site-packages/websockets/sync/server.py b/.venv/Lib/site-packages/websockets/sync/server.py new file mode 100644 index 0000000000000000000000000000000000000000..24f77e51be7580a985eedd2997d2f4562b00806f --- /dev/null +++ b/.venv/Lib/site-packages/websockets/sync/server.py @@ -0,0 +1,765 @@ +from __future__ import annotations + +import hmac +import http +import logging +import os +import re +import selectors +import socket +import ssl as ssl_module +import sys +import threading +import warnings +from collections.abc import Iterable, Sequence +from types import TracebackType +from typing import Any, Callable, Mapping, cast + +from ..exceptions import InvalidHeader +from ..extensions.base import ServerExtensionFactory +from ..extensions.permessage_deflate import enable_server_permessage_deflate +from ..frames import CloseCode +from ..headers import ( + build_www_authenticate_basic, + parse_authorization_basic, + validate_subprotocols, +) +from ..http11 import SERVER, Request, Response +from ..protocol import CONNECTING, OPEN, Event +from ..server import ServerProtocol +from ..typing import LoggerLike, Origin, StatusLike, Subprotocol +from .connection import Connection +from .utils import Deadline + + +__all__ = ["serve", "unix_serve", "ServerConnection", "Server", "basic_auth"] + + +class ServerConnection(Connection): + """ + :mod:`threading` implementation of a WebSocket server connection. + + :class:`ServerConnection` provides :meth:`recv` and :meth:`send` methods for + receiving and sending messages. + + It supports iteration to receive messages:: + + for message in websocket: + process(message) + + The iterator exits normally when the connection is closed with code + 1000 (OK) or 1001 (going away) or without a close code. It raises a + :exc:`~websockets.exceptions.ConnectionClosedError` when the connection is + closed with any other code. + + The ``ping_interval``, ``ping_timeout``, ``close_timeout``, and + ``max_queue`` arguments have the same meaning as in :func:`serve`. + + Args: + socket: Socket connected to a WebSocket client. + protocol: Sans-I/O connection. + + """ + + def __init__( + self, + socket: socket.socket, + protocol: ServerProtocol, + *, + ping_interval: float | None = 20, + ping_timeout: float | None = 20, + close_timeout: float | None = 10, + max_queue: int | None | tuple[int | None, int | None] = 16, + ) -> None: + self.protocol: ServerProtocol + self.request_rcvd = threading.Event() + super().__init__( + socket, + protocol, + ping_interval=ping_interval, + ping_timeout=ping_timeout, + close_timeout=close_timeout, + max_queue=max_queue, + ) + self.username: str # see basic_auth() + self.handler: Callable[[ServerConnection], None] # see route() + self.handler_kwargs: Mapping[str, Any] # see route() + + def respond(self, status: StatusLike, text: str) -> Response: + """ + Create a plain text HTTP response. + + ``process_request`` and ``process_response`` may call this method to + return an HTTP response instead of performing the WebSocket opening + handshake. + + You can modify the response before returning it, for example by changing + HTTP headers. + + Args: + status: HTTP status code. + text: HTTP response body; it will be encoded to UTF-8. + + Returns: + HTTP response to send to the client. + + """ + return self.protocol.reject(status, text) + + def handshake( + self, + process_request: ( + Callable[ + [ServerConnection, Request], + Response | None, + ] + | None + ) = None, + process_response: ( + Callable[ + [ServerConnection, Request, Response], + Response | None, + ] + | None + ) = None, + server_header: str | None = SERVER, + timeout: float | None = None, + ) -> None: + """ + Perform the opening handshake. + + """ + if not self.request_rcvd.wait(timeout): + raise TimeoutError("timed out while waiting for handshake request") + + if self.request is not None: + with self.send_context(expected_state=CONNECTING): + response = None + + if process_request is not None: + try: + response = process_request(self, self.request) + except Exception as exc: + self.protocol.handshake_exc = exc + response = self.protocol.reject( + http.HTTPStatus.INTERNAL_SERVER_ERROR, + ( + "Failed to open a WebSocket connection.\n" + "See server log for more information.\n" + ), + ) + + if response is None: + self.response = self.protocol.accept(self.request) + else: + self.response = response + + if server_header: + self.response.headers["Server"] = server_header + + response = None + + if process_response is not None: + try: + response = process_response(self, self.request, self.response) + except Exception as exc: + self.protocol.handshake_exc = exc + response = self.protocol.reject( + http.HTTPStatus.INTERNAL_SERVER_ERROR, + ( + "Failed to open a WebSocket connection.\n" + "See server log for more information.\n" + ), + ) + + if response is not None: + self.response = response + + self.protocol.send_response(self.response) + + # self.protocol.handshake_exc is set when the connection is lost before + # receiving a request, when the request cannot be parsed, or when the + # handshake fails, including when process_request or process_response + # raises an exception. + + # It isn't set when process_request or process_response sends an HTTP + # response that rejects the handshake. + + if self.protocol.handshake_exc is not None: + raise self.protocol.handshake_exc + + def process_event(self, event: Event) -> None: + """ + Process one incoming event. + + """ + # First event - handshake request. + if self.request is None: + assert isinstance(event, Request) + self.request = event + self.request_rcvd.set() + # Later events - frames. + else: + super().process_event(event) + + def recv_events(self) -> None: + """ + Read incoming data from the socket and process events. + + """ + try: + super().recv_events() + finally: + # If the connection is closed during the handshake, unblock it. + self.request_rcvd.set() + + +class Server: + """ + WebSocket server returned by :func:`serve`. + + This class mirrors the API of :class:`~socketserver.BaseServer`, notably the + :meth:`~socketserver.BaseServer.serve_forever` and + :meth:`~socketserver.BaseServer.shutdown` methods, as well as the context + manager protocol. + + Args: + socket: Server socket listening for new connections. + handler: Handler for one connection. Receives the socket and address + returned by :meth:`~socket.socket.accept`. + logger: Logger for this server. + It defaults to ``logging.getLogger("websockets.server")``. + See the :doc:`logging guide <../../topics/logging>` for details. + + """ + + def __init__( + self, + socket: socket.socket, + handler: Callable[[socket.socket, Any], None], + logger: LoggerLike | None = None, + ) -> None: + self.socket = socket + self.handler = handler + if logger is None: + logger = logging.getLogger("websockets.server") + self.logger = logger + if sys.platform != "win32": + self.shutdown_watcher, self.shutdown_notifier = os.pipe() + + def serve_forever(self) -> None: + """ + See :meth:`socketserver.BaseServer.serve_forever`. + + This method doesn't return. Calling :meth:`shutdown` from another thread + stops the server. + + Typical use:: + + with serve(...) as server: + server.serve_forever() + + """ + poller = selectors.DefaultSelector() + try: + poller.register(self.socket, selectors.EVENT_READ) + except ValueError: # pragma: no cover + # If shutdown() is called before poller.register(), + # the socket is closed and poller.register() raises + # ValueError: Invalid file descriptor: -1 + return + if sys.platform != "win32": + poller.register(self.shutdown_watcher, selectors.EVENT_READ) + + while True: + poller.select() + try: + # If the socket is closed, this will raise an exception and exit + # the loop. So we don't need to check the return value of select(). + sock, addr = self.socket.accept() + except OSError: + break + # Since there isn't a mechanism for tracking connections and waiting + # for them to terminate, we cannot use daemon threads, or else all + # connections would be terminate brutally when closing the server. + thread = threading.Thread(target=self.handler, args=(sock, addr)) + thread.start() + + def shutdown(self) -> None: + """ + See :meth:`socketserver.BaseServer.shutdown`. + + """ + self.socket.close() + if sys.platform != "win32": + os.write(self.shutdown_notifier, b"x") + + def fileno(self) -> int: + """ + See :meth:`socketserver.BaseServer.fileno`. + + """ + return self.socket.fileno() + + def __enter__(self) -> Server: + return self + + def __exit__( + self, + exc_type: type[BaseException] | None, + exc_value: BaseException | None, + traceback: TracebackType | None, + ) -> None: + self.shutdown() + + +def __getattr__(name: str) -> Any: + if name == "WebSocketServer": + warnings.warn( # deprecated in 13.0 - 2024-08-20 + "WebSocketServer was renamed to Server", + DeprecationWarning, + ) + return Server + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") + + +def serve( + handler: Callable[[ServerConnection], None], + host: str | None = None, + port: int | None = None, + *, + # TCP/TLS + sock: socket.socket | None = None, + ssl: ssl_module.SSLContext | None = None, + # WebSocket + origins: Sequence[Origin | re.Pattern[str] | None] | None = None, + extensions: Sequence[ServerExtensionFactory] | None = None, + subprotocols: Sequence[Subprotocol] | None = None, + select_subprotocol: ( + Callable[ + [ServerConnection, Sequence[Subprotocol]], + Subprotocol | None, + ] + | None + ) = None, + compression: str | None = "deflate", + # HTTP + process_request: ( + Callable[ + [ServerConnection, Request], + Response | None, + ] + | None + ) = None, + process_response: ( + Callable[ + [ServerConnection, Request, Response], + Response | None, + ] + | None + ) = None, + server_header: str | None = SERVER, + # Timeouts + open_timeout: float | None = 10, + ping_interval: float | None = 20, + ping_timeout: float | None = 20, + close_timeout: float | None = 10, + # Limits + max_size: int | None | tuple[int | None, int | None] = 2**20, + max_queue: int | None | tuple[int | None, int | None] = 16, + # Logging + logger: LoggerLike | None = None, + # Escape hatch for advanced customization + create_connection: type[ServerConnection] | None = None, + **kwargs: Any, +) -> Server: + """ + Create a WebSocket server listening on ``host`` and ``port``. + + Whenever a client connects, the server creates a :class:`ServerConnection`, + performs the opening handshake, and delegates to the ``handler``. + + The handler receives the :class:`ServerConnection` instance, which you can + use to send and receive messages. + + Once the handler completes, either normally or with an exception, the server + performs the closing handshake and closes the connection. + + This function returns a :class:`Server` whose API mirrors + :class:`~socketserver.BaseServer`. Treat it as a context manager to ensure + that it will be closed and call :meth:`~Server.serve_forever` to serve + requests:: + + from websockets.sync.server import serve + + def handler(websocket): + ... + + with serve(handler, ...) as server: + server.serve_forever() + + Args: + handler: Connection handler. It receives the WebSocket connection, + which is a :class:`ServerConnection`, in argument. + host: Network interfaces the server binds to. + See :func:`~socket.create_server` for details. + port: TCP port the server listens on. + See :func:`~socket.create_server` for details. + sock: Preexisting TCP socket. ``sock`` replaces ``host`` and ``port``. + You may call :func:`socket.create_server` to create a suitable TCP + socket. + ssl: Configuration for enabling TLS on the connection. + origins: Acceptable values of the ``Origin`` header, for defending + against Cross-Site WebSocket Hijacking attacks. Values can be + :class:`str` to test for an exact match or regular expressions + compiled by :func:`re.compile` to test against a pattern. Include + :obj:`None` in the list if the lack of an origin is acceptable. + extensions: List of supported extensions, in order in which they + should be negotiated and run. + subprotocols: List of supported subprotocols, in order of decreasing + preference. + select_subprotocol: Callback for selecting a subprotocol among + those supported by the client and the server. It receives a + :class:`ServerConnection` (not a + :class:`~websockets.server.ServerProtocol`!) instance and a list of + subprotocols offered by the client. Other than the first argument, + it has the same behavior as the + :meth:`ServerProtocol.select_subprotocol + ` method. + compression: The "permessage-deflate" extension is enabled by default. + Set ``compression`` to :obj:`None` to disable it. See the + :doc:`compression guide <../../topics/compression>` for details. + process_request: Intercept the request during the opening handshake. + Return an HTTP response to force the response. Return :obj:`None` to + continue normally. When you force an HTTP 101 Continue response, the + handshake is successful. Else, the connection is aborted. + process_response: Intercept the response during the opening handshake. + Modify the response or return a new HTTP response to force the + response. Return :obj:`None` to continue normally. When you force an + HTTP 101 Continue response, the handshake is successful. Else, the + connection is aborted. + server_header: Value of the ``Server`` response header. + It defaults to ``"Python/x.y.z websockets/X.Y"``. Setting it to + :obj:`None` removes the header. + open_timeout: Timeout for opening connections in seconds. + :obj:`None` disables the timeout. + ping_interval: Interval between keepalive pings in seconds. + :obj:`None` disables keepalive. + ping_timeout: Timeout for keepalive pings in seconds. + :obj:`None` disables timeouts. + close_timeout: Timeout for closing connections in seconds. + :obj:`None` disables the timeout. + max_size: Maximum size of incoming messages in bytes. + :obj:`None` disables the limit. You may pass a ``(max_message_size, + max_fragment_size)`` tuple to set different limits for messages and + fragments when you expect long messages sent in short fragments. + max_queue: High-water mark of the buffer where frames are received. + It defaults to 16 frames. The low-water mark defaults to ``max_queue + // 4``. You may pass a ``(high, low)`` tuple to set the high-water + and low-water marks. If you want to disable flow control entirely, + you may set it to ``None``, although that's a bad idea. + logger: Logger for this server. + It defaults to ``logging.getLogger("websockets.server")``. See the + :doc:`logging guide <../../topics/logging>` for details. + create_connection: Factory for the :class:`ServerConnection` managing + the connection. Set it to a wrapper or a subclass to customize + connection handling. + + Any other keyword arguments are passed to :func:`~socket.create_server`. + + """ + + # Process parameters + + # Backwards compatibility: ssl used to be called ssl_context. + if ssl is None and "ssl_context" in kwargs: + ssl = kwargs.pop("ssl_context") + warnings.warn( # deprecated in 13.0 - 2024-08-20 + "ssl_context was renamed to ssl", + DeprecationWarning, + ) + + if subprotocols is not None: + validate_subprotocols(subprotocols) + + if compression == "deflate": + extensions = enable_server_permessage_deflate(extensions) + elif compression is not None: + raise ValueError(f"unsupported compression: {compression}") + + if create_connection is None: + create_connection = ServerConnection + + # Bind socket and listen + + # Private APIs for unix_connect() + unix: bool = kwargs.pop("unix", False) + path: str | None = kwargs.pop("path", None) + + if sock is None: + if unix: + if path is None: + raise ValueError("missing path argument") + kwargs.setdefault("family", socket.AF_UNIX) + sock = socket.create_server(path, **kwargs) + else: + sock = socket.create_server((host, port), **kwargs) + else: + if path is not None: + raise ValueError("path and sock arguments are incompatible") + + # Initialize TLS wrapper + + if ssl is not None: + sock = ssl.wrap_socket( + sock, + server_side=True, + # Delay TLS handshake until after we set a timeout on the socket. + do_handshake_on_connect=False, + ) + + # Define request handler + + def conn_handler(sock: socket.socket, addr: Any) -> None: + # Calculate timeouts on the TLS and WebSocket handshakes. + # The TLS timeout must be set on the socket, then removed + # to avoid conflicting with the WebSocket timeout in handshake(). + deadline = Deadline(open_timeout) + + try: + # Disable Nagle algorithm + + if not unix: + sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, True) + + # Perform TLS handshake + + if ssl is not None: + sock.settimeout(deadline.timeout()) + # mypy cannot figure this out + assert isinstance(sock, ssl_module.SSLSocket) + sock.do_handshake() + sock.settimeout(None) + + # Create a closure to give select_subprotocol access to connection. + protocol_select_subprotocol: ( + Callable[ + [ServerProtocol, Sequence[Subprotocol]], + Subprotocol | None, + ] + | None + ) = None + if select_subprotocol is not None: + + def protocol_select_subprotocol( + protocol: ServerProtocol, + subprotocols: Sequence[Subprotocol], + ) -> Subprotocol | None: + # mypy doesn't know that select_subprotocol is immutable. + assert select_subprotocol is not None + # Ensure this function is only used in the intended context. + assert protocol is connection.protocol + return select_subprotocol(connection, subprotocols) + + # Initialize WebSocket protocol + + protocol = ServerProtocol( + origins=origins, + extensions=extensions, + subprotocols=subprotocols, + select_subprotocol=protocol_select_subprotocol, + max_size=max_size, + logger=logger, + ) + + # Initialize WebSocket connection + + assert create_connection is not None # help mypy + connection = create_connection( + sock, + protocol, + ping_interval=ping_interval, + ping_timeout=ping_timeout, + close_timeout=close_timeout, + max_queue=max_queue, + ) + except Exception: + sock.close() + return + + try: + try: + connection.handshake( + process_request, + process_response, + server_header, + deadline.timeout(), + ) + except TimeoutError: + connection.close_socket() + connection.recv_events_thread.join() + return + except Exception: + connection.logger.error("opening handshake failed", exc_info=True) + connection.close_socket() + connection.recv_events_thread.join() + return + + assert connection.protocol.state is OPEN + try: + connection.start_keepalive() + handler(connection) + except Exception: + connection.logger.error("connection handler failed", exc_info=True) + connection.close(CloseCode.INTERNAL_ERROR) + else: + connection.close() + + except Exception: # pragma: no cover + # Don't leak sockets on unexpected errors. + sock.close() + + # Initialize server + + return Server(sock, conn_handler, logger) + + +def unix_serve( + handler: Callable[[ServerConnection], None], + path: str | None = None, + **kwargs: Any, +) -> Server: + """ + Create a WebSocket server listening on a Unix socket. + + This function accepts the same keyword arguments as :func:`serve`. + + It's only available on Unix. + + It's useful for deploying a server behind a reverse proxy such as nginx. + + Args: + handler: Connection handler. It receives the WebSocket connection, + which is a :class:`ServerConnection`, in argument. + path: File system path to the Unix socket. + + """ + return serve(handler, unix=True, path=path, **kwargs) + + +def is_credentials(credentials: Any) -> bool: + try: + username, password = credentials + except (TypeError, ValueError): + return False + else: + return isinstance(username, str) and isinstance(password, str) + + +def basic_auth( + realm: str = "", + credentials: tuple[str, str] | Iterable[tuple[str, str]] | None = None, + check_credentials: Callable[[str, str], bool] | None = None, +) -> Callable[[ServerConnection, Request], Response | None]: + """ + Factory for ``process_request`` to enforce HTTP Basic Authentication. + + :func:`basic_auth` is designed to integrate with :func:`serve` as follows:: + + from websockets.sync.server import basic_auth, serve + + with serve( + ..., + process_request=basic_auth( + realm="my dev server", + credentials=("hello", "iloveyou"), + ), + ): + + If authentication succeeds, the connection's ``username`` attribute is set. + If it fails, the server responds with an HTTP 401 Unauthorized status. + + One of ``credentials`` or ``check_credentials`` must be provided; not both. + + Args: + realm: Scope of protection. It should contain only ASCII characters + because the encoding of non-ASCII characters is undefined. Refer to + section 2.2 of :rfc:`7235` for details. + credentials: Hard coded authorized credentials. It can be a + ``(username, password)`` pair or a list of such pairs. + check_credentials: Function that verifies credentials. + It receives ``username`` and ``password`` arguments and returns + whether they're valid. + Raises: + TypeError: If ``credentials`` or ``check_credentials`` is wrong. + ValueError: If ``credentials`` and ``check_credentials`` are both + provided or both not provided. + + """ + if (credentials is None) == (check_credentials is None): + raise ValueError("provide either credentials or check_credentials") + + if credentials is not None: + if is_credentials(credentials): + credentials_list = [cast(tuple[str, str], credentials)] + elif isinstance(credentials, Iterable): + credentials_list = list(cast(Iterable[tuple[str, str]], credentials)) + if not all(is_credentials(item) for item in credentials_list): + raise TypeError(f"invalid credentials argument: {credentials}") + else: + raise TypeError(f"invalid credentials argument: {credentials}") + + credentials_dict = dict(credentials_list) + + def check_credentials(username: str, password: str) -> bool: + try: + expected_password = credentials_dict[username] + except KeyError: + return False + return hmac.compare_digest(expected_password, password) + + assert check_credentials is not None # help mypy + + def process_request( + connection: ServerConnection, + request: Request, + ) -> Response | None: + """ + Perform HTTP Basic Authentication. + + If it succeeds, set the connection's ``username`` attribute and return + :obj:`None`. If it fails, return an HTTP 401 Unauthorized responss. + + """ + try: + authorization = request.headers["Authorization"] + except KeyError: + response = connection.respond( + http.HTTPStatus.UNAUTHORIZED, + "Missing credentials\n", + ) + response.headers["WWW-Authenticate"] = build_www_authenticate_basic(realm) + return response + + try: + username, password = parse_authorization_basic(authorization) + except InvalidHeader: + response = connection.respond( + http.HTTPStatus.UNAUTHORIZED, + "Unsupported credentials\n", + ) + response.headers["WWW-Authenticate"] = build_www_authenticate_basic(realm) + return response + + if not check_credentials(username, password): + response = connection.respond( + http.HTTPStatus.UNAUTHORIZED, + "Invalid credentials\n", + ) + response.headers["WWW-Authenticate"] = build_www_authenticate_basic(realm) + return response + + connection.username = username + return None + + return process_request diff --git a/.venv/Lib/site-packages/websockets/sync/utils.py b/.venv/Lib/site-packages/websockets/sync/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..d8890411e16d144dec095b4c2eb86183d0f05bca --- /dev/null +++ b/.venv/Lib/site-packages/websockets/sync/utils.py @@ -0,0 +1,45 @@ +from __future__ import annotations + +import time + + +__all__ = ["Deadline"] + + +class Deadline: + """ + Manage timeouts across multiple steps. + + Args: + timeout: Time available in seconds or :obj:`None` if there is no limit. + + """ + + def __init__(self, timeout: float | None) -> None: + self.deadline: float | None + if timeout is None: + self.deadline = None + else: + self.deadline = time.monotonic() + timeout + + def timeout(self, *, raise_if_elapsed: bool = True) -> float | None: + """ + Calculate a timeout from a deadline. + + Args: + raise_if_elapsed: Whether to raise :exc:`TimeoutError` + if the deadline lapsed. + + Raises: + TimeoutError: If the deadline lapsed. + + Returns: + Time left in seconds or :obj:`None` if there is no limit. + + """ + if self.deadline is None: + return None + timeout = self.deadline - time.monotonic() + if raise_if_elapsed and timeout <= 0: + raise TimeoutError("timed out") + return timeout diff --git a/.venv/Lib/site-packages/websockets/typing.py b/.venv/Lib/site-packages/websockets/typing.py new file mode 100644 index 0000000000000000000000000000000000000000..5103336ffe8be86d508893d95d929300ac6bf5db --- /dev/null +++ b/.venv/Lib/site-packages/websockets/typing.py @@ -0,0 +1,75 @@ +from __future__ import annotations + +import http +import logging +from typing import TYPE_CHECKING, Any, NewType, Sequence + + +__all__ = [ + "Data", + "LoggerLike", + "StatusLike", + "Origin", + "Subprotocol", + "ExtensionName", + "ExtensionParameter", +] + + +# Public types used in the signature of public APIs + +Data = str | bytes +"""Types supported in a WebSocket message: +:class:`str` for a Text_ frame, :class:`bytes` for a Binary_ frame. + +.. _Text: https://datatracker.ietf.org/doc/html/rfc6455#section-5.6 +.. _Binary : https://datatracker.ietf.org/doc/html/rfc6455#section-5.6 + +""" + +BytesLike = bytes | bytearray | memoryview +"""Types accepted where :class:`bytes` is expected.""" + +DataLike = str | bytes | bytearray | memoryview +"""Types accepted where :class:`Data` is expected.""" + +if TYPE_CHECKING: + LoggerLike = logging.Logger | logging.LoggerAdapter[Any] + """Types accepted where a :class:`~logging.Logger` is expected.""" +else: # remove this branch when dropping support for Python < 3.11 + LoggerLike = logging.Logger | logging.LoggerAdapter + """Types accepted where a :class:`~logging.Logger` is expected.""" + + +StatusLike = http.HTTPStatus | int +""" +Types accepted where an :class:`~http.HTTPStatus` is expected.""" + + +Origin = NewType("Origin", str) +"""Value of a ``Origin`` header.""" + + +Subprotocol = NewType("Subprotocol", str) +"""Subprotocol in a ``Sec-WebSocket-Protocol`` header.""" + + +ExtensionName = NewType("ExtensionName", str) +"""Name of a WebSocket extension.""" + +ExtensionParameter = tuple[str, str | None] +"""Parameter of a WebSocket extension.""" + + +# Private types + +ExtensionHeader = tuple[ExtensionName, Sequence[ExtensionParameter]] +"""Extension in a ``Sec-WebSocket-Extensions`` header.""" + + +ConnectionOption = NewType("ConnectionOption", str) +"""Connection option in a ``Connection`` header.""" + + +UpgradeProtocol = NewType("UpgradeProtocol", str) +"""Upgrade protocol in an ``Upgrade`` header.""" diff --git a/.venv/Lib/site-packages/websockets/uri.py b/.venv/Lib/site-packages/websockets/uri.py new file mode 100644 index 0000000000000000000000000000000000000000..1d5b71a172bbde66bbb08bd127a4f0cc42829750 --- /dev/null +++ b/.venv/Lib/site-packages/websockets/uri.py @@ -0,0 +1,107 @@ +from __future__ import annotations + +import dataclasses +import urllib.parse + +from .exceptions import InvalidURI + + +__all__ = ["parse_uri", "WebSocketURI"] + + +# All characters from the gen-delims and sub-delims sets in RFC 3987. +DELIMS = ":/?#[]@!$&'()*+,;=" + + +@dataclasses.dataclass +class WebSocketURI: + """ + WebSocket URI. + + Attributes: + secure: :obj:`True` for a ``wss`` URI, :obj:`False` for a ``ws`` URI. + host: Normalized to lower case. + port: Always set even if it's the default. + path: May be empty. + query: May be empty if the URI doesn't include a query component. + username: Available when the URI contains `User Information`_. + password: Available when the URI contains `User Information`_. + + .. _User Information: https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.1 + + """ + + secure: bool + host: str + port: int + path: str + query: str + username: str | None = None + password: str | None = None + + @property + def resource_name(self) -> str: + if self.path: + resource_name = self.path + else: + resource_name = "/" + if self.query: + resource_name += "?" + self.query + return resource_name + + @property + def user_info(self) -> tuple[str, str] | None: + if self.username is None: + return None + assert self.password is not None + return (self.username, self.password) + + +def parse_uri(uri: str) -> WebSocketURI: + """ + Parse and validate a WebSocket URI. + + Args: + uri: WebSocket URI. + + Returns: + Parsed WebSocket URI. + + Raises: + InvalidURI: If ``uri`` isn't a valid WebSocket URI. + + """ + parsed = urllib.parse.urlparse(uri) + if parsed.scheme not in ["ws", "wss"]: + raise InvalidURI(uri, "scheme isn't ws or wss") + if parsed.hostname is None: + raise InvalidURI(uri, "hostname isn't provided") + if parsed.fragment != "": + raise InvalidURI(uri, "fragment identifier is meaningless") + + secure = parsed.scheme == "wss" + host = parsed.hostname + port = parsed.port or (443 if secure else 80) + path = parsed.path + query = parsed.query + username = parsed.username + password = parsed.password + # urllib.parse.urlparse accepts URLs with a username but without a + # password. This doesn't make sense for HTTP Basic Auth credentials. + if username is not None and password is None: + raise InvalidURI(uri, "username provided without password") + + try: + uri.encode("ascii") + except UnicodeEncodeError: + # Input contains non-ASCII characters. + # It must be an IRI. Convert it to a URI. + host = host.encode("idna").decode() + path = urllib.parse.quote(path, safe=DELIMS) + query = urllib.parse.quote(query, safe=DELIMS) + if username is not None: + assert password is not None + username = urllib.parse.quote(username, safe=DELIMS) + password = urllib.parse.quote(password, safe=DELIMS) + + return WebSocketURI(secure, host, port, path, query, username, password) diff --git a/.venv/Lib/site-packages/websockets/utils.py b/.venv/Lib/site-packages/websockets/utils.py new file mode 100644 index 0000000000000000000000000000000000000000..33c842bdd355740530970c5f66b01c77d107f5f5 --- /dev/null +++ b/.venv/Lib/site-packages/websockets/utils.py @@ -0,0 +1,57 @@ +from __future__ import annotations + +import base64 +import hashlib +import secrets +import sys + +from .typing import BytesLike + + +__all__ = ["accept_key", "apply_mask"] + + +GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" + + +def generate_key() -> str: + """ + Generate a random key for the Sec-WebSocket-Key header. + + """ + key = secrets.token_bytes(16) + return base64.b64encode(key).decode() + + +def accept_key(key: str) -> str: + """ + Compute the value of the Sec-WebSocket-Accept header. + + Args: + key: Value of the Sec-WebSocket-Key header. + + """ + sha1 = hashlib.sha1((key + GUID).encode()).digest() + return base64.b64encode(sha1).decode() + + +def apply_mask(data: BytesLike, mask: bytes | bytearray) -> bytes: + """ + Apply masking to the data of a WebSocket message. + + Args: + data: Data to mask. + mask: 4-bytes mask. + + """ + if len(mask) != 4: + raise ValueError("mask must contain 4 bytes") + + # Python 3.15+ requires C-contiguous buffers for int.from_bytes(). + if isinstance(data, memoryview) and not data.c_contiguous: + data = bytes(data) + + data_int = int.from_bytes(data, sys.byteorder) + mask_repeated = mask * (len(data) // 4) + mask[: len(data) % 4] + mask_int = int.from_bytes(mask_repeated, sys.byteorder) + return (data_int ^ mask_int).to_bytes(len(data), sys.byteorder) diff --git a/.venv/Lib/site-packages/websockets/version.py b/.venv/Lib/site-packages/websockets/version.py new file mode 100644 index 0000000000000000000000000000000000000000..278ba3982c26c905bd34e6f9a7f904e4ec2208a1 --- /dev/null +++ b/.venv/Lib/site-packages/websockets/version.py @@ -0,0 +1,92 @@ +from __future__ import annotations + +import importlib.metadata + + +__all__ = ["tag", "version", "commit"] + + +# ========= =========== =================== +# release development +# ========= =========== =================== +# tag X.Y X.Y (upcoming) +# version X.Y X.Y.dev1+g5678cde +# commit X.Y 5678cde +# ========= =========== =================== + + +# When tagging a release, set `released = True`. +# After tagging a release, set `released = False` and increment `tag`. + +released = True + +tag = version = commit = "16.1" + + +if not released: # pragma: no cover + import pathlib + import re + import subprocess + + def get_version(tag: str) -> str: + # Since setup.py executes the contents of src/websockets/version.py, + # __file__ can point to either of these two files. + file_path = pathlib.Path(__file__) + root_dir = file_path.parents[0 if file_path.name == "setup.py" else 2] + + # Read version from package metadata if it is installed. + try: + version = importlib.metadata.version("websockets") + except ImportError: + pass + else: + # Check that this file belongs to the installed package. + files = importlib.metadata.files("websockets") + if files: + version_files = [f for f in files if f.name == file_path.name] + if version_files: + version_file = version_files[0] + if version_file.locate() == file_path: + return version + + # Read version from git if available. + try: + description = subprocess.run( + ["git", "describe", "--dirty", "--tags", "--long"], + capture_output=True, + cwd=root_dir, + timeout=1, + check=True, + text=True, + ).stdout.strip() + # subprocess.run raises FileNotFoundError if git isn't on $PATH. + except ( + FileNotFoundError, + subprocess.CalledProcessError, + subprocess.TimeoutExpired, + ): + pass + else: + description_re = r"[0-9.]+-([0-9]+)-(g[0-9a-f]{7,}(?:-dirty)?)" + match = re.fullmatch(description_re, description) + if match is None: + raise ValueError(f"Unexpected git description: {description}") + distance, remainder = match.groups() + remainder = remainder.replace("-", ".") # required by PEP 440 + return f"{tag}.dev{distance}+{remainder}" + + # Avoid crashing if the development version cannot be determined. + return f"{tag}.dev0+gunknown" + + version = get_version(tag) + + def get_commit(tag: str, version: str) -> str: + # Extract commit from version, falling back to tag if not available. + version_re = r"[0-9.]+\.dev[0-9]+\+g([0-9a-f]{7,}|unknown)(?:\.dirty)?" + match = re.fullmatch(version_re, version) + if match is None: + raise ValueError(f"Unexpected version: {version}") + (commit,) = match.groups() + return tag if commit == "unknown" else commit + + commit = get_commit(tag, version) diff --git a/.venv/Lib/site-packages/yaml/__init__.py b/.venv/Lib/site-packages/yaml/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..d58f0891737def7f38e5d86dde2dbf9be0c13dce --- /dev/null +++ b/.venv/Lib/site-packages/yaml/__init__.py @@ -0,0 +1,390 @@ + +from .error import * + +from .tokens import * +from .events import * +from .nodes import * + +from .loader import * +from .dumper import * + +__version__ = '6.0.3' +try: + from .cyaml import * + __with_libyaml__ = True +except ImportError: + __with_libyaml__ = False + +import io + +#------------------------------------------------------------------------------ +# XXX "Warnings control" is now deprecated. Leaving in the API function to not +# break code that uses it. +#------------------------------------------------------------------------------ +def warnings(settings=None): + if settings is None: + return {} + +#------------------------------------------------------------------------------ +def scan(stream, Loader=Loader): + """ + Scan a YAML stream and produce scanning tokens. + """ + loader = Loader(stream) + try: + while loader.check_token(): + yield loader.get_token() + finally: + loader.dispose() + +def parse(stream, Loader=Loader): + """ + Parse a YAML stream and produce parsing events. + """ + loader = Loader(stream) + try: + while loader.check_event(): + yield loader.get_event() + finally: + loader.dispose() + +def compose(stream, Loader=Loader): + """ + Parse the first YAML document in a stream + and produce the corresponding representation tree. + """ + loader = Loader(stream) + try: + return loader.get_single_node() + finally: + loader.dispose() + +def compose_all(stream, Loader=Loader): + """ + Parse all YAML documents in a stream + and produce corresponding representation trees. + """ + loader = Loader(stream) + try: + while loader.check_node(): + yield loader.get_node() + finally: + loader.dispose() + +def load(stream, Loader): + """ + Parse the first YAML document in a stream + and produce the corresponding Python object. + """ + loader = Loader(stream) + try: + return loader.get_single_data() + finally: + loader.dispose() + +def load_all(stream, Loader): + """ + Parse all YAML documents in a stream + and produce corresponding Python objects. + """ + loader = Loader(stream) + try: + while loader.check_data(): + yield loader.get_data() + finally: + loader.dispose() + +def full_load(stream): + """ + Parse the first YAML document in a stream + and produce the corresponding Python object. + + Resolve all tags except those known to be + unsafe on untrusted input. + """ + return load(stream, FullLoader) + +def full_load_all(stream): + """ + Parse all YAML documents in a stream + and produce corresponding Python objects. + + Resolve all tags except those known to be + unsafe on untrusted input. + """ + return load_all(stream, FullLoader) + +def safe_load(stream): + """ + Parse the first YAML document in a stream + and produce the corresponding Python object. + + Resolve only basic YAML tags. This is known + to be safe for untrusted input. + """ + return load(stream, SafeLoader) + +def safe_load_all(stream): + """ + Parse all YAML documents in a stream + and produce corresponding Python objects. + + Resolve only basic YAML tags. This is known + to be safe for untrusted input. + """ + return load_all(stream, SafeLoader) + +def unsafe_load(stream): + """ + Parse the first YAML document in a stream + and produce the corresponding Python object. + + Resolve all tags, even those known to be + unsafe on untrusted input. + """ + return load(stream, UnsafeLoader) + +def unsafe_load_all(stream): + """ + Parse all YAML documents in a stream + and produce corresponding Python objects. + + Resolve all tags, even those known to be + unsafe on untrusted input. + """ + return load_all(stream, UnsafeLoader) + +def emit(events, stream=None, Dumper=Dumper, + canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None): + """ + Emit YAML parsing events into a stream. + If stream is None, return the produced string instead. + """ + getvalue = None + if stream is None: + stream = io.StringIO() + getvalue = stream.getvalue + dumper = Dumper(stream, canonical=canonical, indent=indent, width=width, + allow_unicode=allow_unicode, line_break=line_break) + try: + for event in events: + dumper.emit(event) + finally: + dumper.dispose() + if getvalue: + return getvalue() + +def serialize_all(nodes, stream=None, Dumper=Dumper, + canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None, + encoding=None, explicit_start=None, explicit_end=None, + version=None, tags=None): + """ + Serialize a sequence of representation trees into a YAML stream. + If stream is None, return the produced string instead. + """ + getvalue = None + if stream is None: + if encoding is None: + stream = io.StringIO() + else: + stream = io.BytesIO() + getvalue = stream.getvalue + dumper = Dumper(stream, canonical=canonical, indent=indent, width=width, + allow_unicode=allow_unicode, line_break=line_break, + encoding=encoding, version=version, tags=tags, + explicit_start=explicit_start, explicit_end=explicit_end) + try: + dumper.open() + for node in nodes: + dumper.serialize(node) + dumper.close() + finally: + dumper.dispose() + if getvalue: + return getvalue() + +def serialize(node, stream=None, Dumper=Dumper, **kwds): + """ + Serialize a representation tree into a YAML stream. + If stream is None, return the produced string instead. + """ + return serialize_all([node], stream, Dumper=Dumper, **kwds) + +def dump_all(documents, stream=None, Dumper=Dumper, + default_style=None, default_flow_style=False, + canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None, + encoding=None, explicit_start=None, explicit_end=None, + version=None, tags=None, sort_keys=True): + """ + Serialize a sequence of Python objects into a YAML stream. + If stream is None, return the produced string instead. + """ + getvalue = None + if stream is None: + if encoding is None: + stream = io.StringIO() + else: + stream = io.BytesIO() + getvalue = stream.getvalue + dumper = Dumper(stream, default_style=default_style, + default_flow_style=default_flow_style, + canonical=canonical, indent=indent, width=width, + allow_unicode=allow_unicode, line_break=line_break, + encoding=encoding, version=version, tags=tags, + explicit_start=explicit_start, explicit_end=explicit_end, sort_keys=sort_keys) + try: + dumper.open() + for data in documents: + dumper.represent(data) + dumper.close() + finally: + dumper.dispose() + if getvalue: + return getvalue() + +def dump(data, stream=None, Dumper=Dumper, **kwds): + """ + Serialize a Python object into a YAML stream. + If stream is None, return the produced string instead. + """ + return dump_all([data], stream, Dumper=Dumper, **kwds) + +def safe_dump_all(documents, stream=None, **kwds): + """ + Serialize a sequence of Python objects into a YAML stream. + Produce only basic YAML tags. + If stream is None, return the produced string instead. + """ + return dump_all(documents, stream, Dumper=SafeDumper, **kwds) + +def safe_dump(data, stream=None, **kwds): + """ + Serialize a Python object into a YAML stream. + Produce only basic YAML tags. + If stream is None, return the produced string instead. + """ + return dump_all([data], stream, Dumper=SafeDumper, **kwds) + +def add_implicit_resolver(tag, regexp, first=None, + Loader=None, Dumper=Dumper): + """ + Add an implicit scalar detector. + If an implicit scalar value matches the given regexp, + the corresponding tag is assigned to the scalar. + first is a sequence of possible initial characters or None. + """ + if Loader is None: + loader.Loader.add_implicit_resolver(tag, regexp, first) + loader.FullLoader.add_implicit_resolver(tag, regexp, first) + loader.UnsafeLoader.add_implicit_resolver(tag, regexp, first) + else: + Loader.add_implicit_resolver(tag, regexp, first) + Dumper.add_implicit_resolver(tag, regexp, first) + +def add_path_resolver(tag, path, kind=None, Loader=None, Dumper=Dumper): + """ + Add a path based resolver for the given tag. + A path is a list of keys that forms a path + to a node in the representation tree. + Keys can be string values, integers, or None. + """ + if Loader is None: + loader.Loader.add_path_resolver(tag, path, kind) + loader.FullLoader.add_path_resolver(tag, path, kind) + loader.UnsafeLoader.add_path_resolver(tag, path, kind) + else: + Loader.add_path_resolver(tag, path, kind) + Dumper.add_path_resolver(tag, path, kind) + +def add_constructor(tag, constructor, Loader=None): + """ + Add a constructor for the given tag. + Constructor is a function that accepts a Loader instance + and a node object and produces the corresponding Python object. + """ + if Loader is None: + loader.Loader.add_constructor(tag, constructor) + loader.FullLoader.add_constructor(tag, constructor) + loader.UnsafeLoader.add_constructor(tag, constructor) + else: + Loader.add_constructor(tag, constructor) + +def add_multi_constructor(tag_prefix, multi_constructor, Loader=None): + """ + Add a multi-constructor for the given tag prefix. + Multi-constructor is called for a node if its tag starts with tag_prefix. + Multi-constructor accepts a Loader instance, a tag suffix, + and a node object and produces the corresponding Python object. + """ + if Loader is None: + loader.Loader.add_multi_constructor(tag_prefix, multi_constructor) + loader.FullLoader.add_multi_constructor(tag_prefix, multi_constructor) + loader.UnsafeLoader.add_multi_constructor(tag_prefix, multi_constructor) + else: + Loader.add_multi_constructor(tag_prefix, multi_constructor) + +def add_representer(data_type, representer, Dumper=Dumper): + """ + Add a representer for the given type. + Representer is a function accepting a Dumper instance + and an instance of the given data type + and producing the corresponding representation node. + """ + Dumper.add_representer(data_type, representer) + +def add_multi_representer(data_type, multi_representer, Dumper=Dumper): + """ + Add a representer for the given type. + Multi-representer is a function accepting a Dumper instance + and an instance of the given data type or subtype + and producing the corresponding representation node. + """ + Dumper.add_multi_representer(data_type, multi_representer) + +class YAMLObjectMetaclass(type): + """ + The metaclass for YAMLObject. + """ + def __init__(cls, name, bases, kwds): + super(YAMLObjectMetaclass, cls).__init__(name, bases, kwds) + if 'yaml_tag' in kwds and kwds['yaml_tag'] is not None: + if isinstance(cls.yaml_loader, list): + for loader in cls.yaml_loader: + loader.add_constructor(cls.yaml_tag, cls.from_yaml) + else: + cls.yaml_loader.add_constructor(cls.yaml_tag, cls.from_yaml) + + cls.yaml_dumper.add_representer(cls, cls.to_yaml) + +class YAMLObject(metaclass=YAMLObjectMetaclass): + """ + An object that can dump itself to a YAML stream + and load itself from a YAML stream. + """ + + __slots__ = () # no direct instantiation, so allow immutable subclasses + + yaml_loader = [Loader, FullLoader, UnsafeLoader] + yaml_dumper = Dumper + + yaml_tag = None + yaml_flow_style = None + + @classmethod + def from_yaml(cls, loader, node): + """ + Convert a representation node to a Python object. + """ + return loader.construct_yaml_object(node, cls) + + @classmethod + def to_yaml(cls, dumper, data): + """ + Convert a Python object to a representation node. + """ + return dumper.represent_yaml_object(cls.yaml_tag, data, cls, + flow_style=cls.yaml_flow_style) + diff --git a/.venv/Lib/site-packages/yaml/composer.py b/.venv/Lib/site-packages/yaml/composer.py new file mode 100644 index 0000000000000000000000000000000000000000..6d15cb40e3b4198819c91c6f8d8b32807fcf53b2 --- /dev/null +++ b/.venv/Lib/site-packages/yaml/composer.py @@ -0,0 +1,139 @@ + +__all__ = ['Composer', 'ComposerError'] + +from .error import MarkedYAMLError +from .events import * +from .nodes import * + +class ComposerError(MarkedYAMLError): + pass + +class Composer: + + def __init__(self): + self.anchors = {} + + def check_node(self): + # Drop the STREAM-START event. + if self.check_event(StreamStartEvent): + self.get_event() + + # If there are more documents available? + return not self.check_event(StreamEndEvent) + + def get_node(self): + # Get the root node of the next document. + if not self.check_event(StreamEndEvent): + return self.compose_document() + + def get_single_node(self): + # Drop the STREAM-START event. + self.get_event() + + # Compose a document if the stream is not empty. + document = None + if not self.check_event(StreamEndEvent): + document = self.compose_document() + + # Ensure that the stream contains no more documents. + if not self.check_event(StreamEndEvent): + event = self.get_event() + raise ComposerError("expected a single document in the stream", + document.start_mark, "but found another document", + event.start_mark) + + # Drop the STREAM-END event. + self.get_event() + + return document + + def compose_document(self): + # Drop the DOCUMENT-START event. + self.get_event() + + # Compose the root node. + node = self.compose_node(None, None) + + # Drop the DOCUMENT-END event. + self.get_event() + + self.anchors = {} + return node + + def compose_node(self, parent, index): + if self.check_event(AliasEvent): + event = self.get_event() + anchor = event.anchor + if anchor not in self.anchors: + raise ComposerError(None, None, "found undefined alias %r" + % anchor, event.start_mark) + return self.anchors[anchor] + event = self.peek_event() + anchor = event.anchor + if anchor is not None: + if anchor in self.anchors: + raise ComposerError("found duplicate anchor %r; first occurrence" + % anchor, self.anchors[anchor].start_mark, + "second occurrence", event.start_mark) + self.descend_resolver(parent, index) + if self.check_event(ScalarEvent): + node = self.compose_scalar_node(anchor) + elif self.check_event(SequenceStartEvent): + node = self.compose_sequence_node(anchor) + elif self.check_event(MappingStartEvent): + node = self.compose_mapping_node(anchor) + self.ascend_resolver() + return node + + def compose_scalar_node(self, anchor): + event = self.get_event() + tag = event.tag + if tag is None or tag == '!': + tag = self.resolve(ScalarNode, event.value, event.implicit) + node = ScalarNode(tag, event.value, + event.start_mark, event.end_mark, style=event.style) + if anchor is not None: + self.anchors[anchor] = node + return node + + def compose_sequence_node(self, anchor): + start_event = self.get_event() + tag = start_event.tag + if tag is None or tag == '!': + tag = self.resolve(SequenceNode, None, start_event.implicit) + node = SequenceNode(tag, [], + start_event.start_mark, None, + flow_style=start_event.flow_style) + if anchor is not None: + self.anchors[anchor] = node + index = 0 + while not self.check_event(SequenceEndEvent): + node.value.append(self.compose_node(node, index)) + index += 1 + end_event = self.get_event() + node.end_mark = end_event.end_mark + return node + + def compose_mapping_node(self, anchor): + start_event = self.get_event() + tag = start_event.tag + if tag is None or tag == '!': + tag = self.resolve(MappingNode, None, start_event.implicit) + node = MappingNode(tag, [], + start_event.start_mark, None, + flow_style=start_event.flow_style) + if anchor is not None: + self.anchors[anchor] = node + while not self.check_event(MappingEndEvent): + #key_event = self.peek_event() + item_key = self.compose_node(node, None) + #if item_key in node.value: + # raise ComposerError("while composing a mapping", start_event.start_mark, + # "found duplicate key", key_event.start_mark) + item_value = self.compose_node(node, item_key) + #node.value[item_key] = item_value + node.value.append((item_key, item_value)) + end_event = self.get_event() + node.end_mark = end_event.end_mark + return node + diff --git a/.venv/Lib/site-packages/yaml/constructor.py b/.venv/Lib/site-packages/yaml/constructor.py new file mode 100644 index 0000000000000000000000000000000000000000..619acd3070a4845c653fcf22a626e05158035bc2 --- /dev/null +++ b/.venv/Lib/site-packages/yaml/constructor.py @@ -0,0 +1,748 @@ + +__all__ = [ + 'BaseConstructor', + 'SafeConstructor', + 'FullConstructor', + 'UnsafeConstructor', + 'Constructor', + 'ConstructorError' +] + +from .error import * +from .nodes import * + +import collections.abc, datetime, base64, binascii, re, sys, types + +class ConstructorError(MarkedYAMLError): + pass + +class BaseConstructor: + + yaml_constructors = {} + yaml_multi_constructors = {} + + def __init__(self): + self.constructed_objects = {} + self.recursive_objects = {} + self.state_generators = [] + self.deep_construct = False + + def check_data(self): + # If there are more documents available? + return self.check_node() + + def check_state_key(self, key): + """Block special attributes/methods from being set in a newly created + object, to prevent user-controlled methods from being called during + deserialization""" + if self.get_state_keys_blacklist_regexp().match(key): + raise ConstructorError(None, None, + "blacklisted key '%s' in instance state found" % (key,), None) + + def get_data(self): + # Construct and return the next document. + if self.check_node(): + return self.construct_document(self.get_node()) + + def get_single_data(self): + # Ensure that the stream contains a single document and construct it. + node = self.get_single_node() + if node is not None: + return self.construct_document(node) + return None + + def construct_document(self, node): + data = self.construct_object(node) + while self.state_generators: + state_generators = self.state_generators + self.state_generators = [] + for generator in state_generators: + for dummy in generator: + pass + self.constructed_objects = {} + self.recursive_objects = {} + self.deep_construct = False + return data + + def construct_object(self, node, deep=False): + if node in self.constructed_objects: + return self.constructed_objects[node] + if deep: + old_deep = self.deep_construct + self.deep_construct = True + if node in self.recursive_objects: + raise ConstructorError(None, None, + "found unconstructable recursive node", node.start_mark) + self.recursive_objects[node] = None + constructor = None + tag_suffix = None + if node.tag in self.yaml_constructors: + constructor = self.yaml_constructors[node.tag] + else: + for tag_prefix in self.yaml_multi_constructors: + if tag_prefix is not None and node.tag.startswith(tag_prefix): + tag_suffix = node.tag[len(tag_prefix):] + constructor = self.yaml_multi_constructors[tag_prefix] + break + else: + if None in self.yaml_multi_constructors: + tag_suffix = node.tag + constructor = self.yaml_multi_constructors[None] + elif None in self.yaml_constructors: + constructor = self.yaml_constructors[None] + elif isinstance(node, ScalarNode): + constructor = self.__class__.construct_scalar + elif isinstance(node, SequenceNode): + constructor = self.__class__.construct_sequence + elif isinstance(node, MappingNode): + constructor = self.__class__.construct_mapping + if tag_suffix is None: + data = constructor(self, node) + else: + data = constructor(self, tag_suffix, node) + if isinstance(data, types.GeneratorType): + generator = data + data = next(generator) + if self.deep_construct: + for dummy in generator: + pass + else: + self.state_generators.append(generator) + self.constructed_objects[node] = data + del self.recursive_objects[node] + if deep: + self.deep_construct = old_deep + return data + + def construct_scalar(self, node): + if not isinstance(node, ScalarNode): + raise ConstructorError(None, None, + "expected a scalar node, but found %s" % node.id, + node.start_mark) + return node.value + + def construct_sequence(self, node, deep=False): + if not isinstance(node, SequenceNode): + raise ConstructorError(None, None, + "expected a sequence node, but found %s" % node.id, + node.start_mark) + return [self.construct_object(child, deep=deep) + for child in node.value] + + def construct_mapping(self, node, deep=False): + if not isinstance(node, MappingNode): + raise ConstructorError(None, None, + "expected a mapping node, but found %s" % node.id, + node.start_mark) + mapping = {} + for key_node, value_node in node.value: + key = self.construct_object(key_node, deep=deep) + if not isinstance(key, collections.abc.Hashable): + raise ConstructorError("while constructing a mapping", node.start_mark, + "found unhashable key", key_node.start_mark) + value = self.construct_object(value_node, deep=deep) + mapping[key] = value + return mapping + + def construct_pairs(self, node, deep=False): + if not isinstance(node, MappingNode): + raise ConstructorError(None, None, + "expected a mapping node, but found %s" % node.id, + node.start_mark) + pairs = [] + for key_node, value_node in node.value: + key = self.construct_object(key_node, deep=deep) + value = self.construct_object(value_node, deep=deep) + pairs.append((key, value)) + return pairs + + @classmethod + def add_constructor(cls, tag, constructor): + if not 'yaml_constructors' in cls.__dict__: + cls.yaml_constructors = cls.yaml_constructors.copy() + cls.yaml_constructors[tag] = constructor + + @classmethod + def add_multi_constructor(cls, tag_prefix, multi_constructor): + if not 'yaml_multi_constructors' in cls.__dict__: + cls.yaml_multi_constructors = cls.yaml_multi_constructors.copy() + cls.yaml_multi_constructors[tag_prefix] = multi_constructor + +class SafeConstructor(BaseConstructor): + + def construct_scalar(self, node): + if isinstance(node, MappingNode): + for key_node, value_node in node.value: + if key_node.tag == 'tag:yaml.org,2002:value': + return self.construct_scalar(value_node) + return super().construct_scalar(node) + + def flatten_mapping(self, node): + merge = [] + index = 0 + while index < len(node.value): + key_node, value_node = node.value[index] + if key_node.tag == 'tag:yaml.org,2002:merge': + del node.value[index] + if isinstance(value_node, MappingNode): + self.flatten_mapping(value_node) + merge.extend(value_node.value) + elif isinstance(value_node, SequenceNode): + submerge = [] + for subnode in value_node.value: + if not isinstance(subnode, MappingNode): + raise ConstructorError("while constructing a mapping", + node.start_mark, + "expected a mapping for merging, but found %s" + % subnode.id, subnode.start_mark) + self.flatten_mapping(subnode) + submerge.append(subnode.value) + submerge.reverse() + for value in submerge: + merge.extend(value) + else: + raise ConstructorError("while constructing a mapping", node.start_mark, + "expected a mapping or list of mappings for merging, but found %s" + % value_node.id, value_node.start_mark) + elif key_node.tag == 'tag:yaml.org,2002:value': + key_node.tag = 'tag:yaml.org,2002:str' + index += 1 + else: + index += 1 + if merge: + node.value = merge + node.value + + def construct_mapping(self, node, deep=False): + if isinstance(node, MappingNode): + self.flatten_mapping(node) + return super().construct_mapping(node, deep=deep) + + def construct_yaml_null(self, node): + self.construct_scalar(node) + return None + + bool_values = { + 'yes': True, + 'no': False, + 'true': True, + 'false': False, + 'on': True, + 'off': False, + } + + def construct_yaml_bool(self, node): + value = self.construct_scalar(node) + return self.bool_values[value.lower()] + + def construct_yaml_int(self, node): + value = self.construct_scalar(node) + value = value.replace('_', '') + sign = +1 + if value[0] == '-': + sign = -1 + if value[0] in '+-': + value = value[1:] + if value == '0': + return 0 + elif value.startswith('0b'): + return sign*int(value[2:], 2) + elif value.startswith('0x'): + return sign*int(value[2:], 16) + elif value[0] == '0': + return sign*int(value, 8) + elif ':' in value: + digits = [int(part) for part in value.split(':')] + digits.reverse() + base = 1 + value = 0 + for digit in digits: + value += digit*base + base *= 60 + return sign*value + else: + return sign*int(value) + + inf_value = 1e300 + while inf_value != inf_value*inf_value: + inf_value *= inf_value + nan_value = -inf_value/inf_value # Trying to make a quiet NaN (like C99). + + def construct_yaml_float(self, node): + value = self.construct_scalar(node) + value = value.replace('_', '').lower() + sign = +1 + if value[0] == '-': + sign = -1 + if value[0] in '+-': + value = value[1:] + if value == '.inf': + return sign*self.inf_value + elif value == '.nan': + return self.nan_value + elif ':' in value: + digits = [float(part) for part in value.split(':')] + digits.reverse() + base = 1 + value = 0.0 + for digit in digits: + value += digit*base + base *= 60 + return sign*value + else: + return sign*float(value) + + def construct_yaml_binary(self, node): + try: + value = self.construct_scalar(node).encode('ascii') + except UnicodeEncodeError as exc: + raise ConstructorError(None, None, + "failed to convert base64 data into ascii: %s" % exc, + node.start_mark) + try: + if hasattr(base64, 'decodebytes'): + return base64.decodebytes(value) + else: + return base64.decodestring(value) + except binascii.Error as exc: + raise ConstructorError(None, None, + "failed to decode base64 data: %s" % exc, node.start_mark) + + timestamp_regexp = re.compile( + r'''^(?P[0-9][0-9][0-9][0-9]) + -(?P[0-9][0-9]?) + -(?P[0-9][0-9]?) + (?:(?:[Tt]|[ \t]+) + (?P[0-9][0-9]?) + :(?P[0-9][0-9]) + :(?P[0-9][0-9]) + (?:\.(?P[0-9]*))? + (?:[ \t]*(?PZ|(?P[-+])(?P[0-9][0-9]?) + (?::(?P[0-9][0-9]))?))?)?$''', re.X) + + def construct_yaml_timestamp(self, node): + value = self.construct_scalar(node) + match = self.timestamp_regexp.match(node.value) + values = match.groupdict() + year = int(values['year']) + month = int(values['month']) + day = int(values['day']) + if not values['hour']: + return datetime.date(year, month, day) + hour = int(values['hour']) + minute = int(values['minute']) + second = int(values['second']) + fraction = 0 + tzinfo = None + if values['fraction']: + fraction = values['fraction'][:6] + while len(fraction) < 6: + fraction += '0' + fraction = int(fraction) + if values['tz_sign']: + tz_hour = int(values['tz_hour']) + tz_minute = int(values['tz_minute'] or 0) + delta = datetime.timedelta(hours=tz_hour, minutes=tz_minute) + if values['tz_sign'] == '-': + delta = -delta + tzinfo = datetime.timezone(delta) + elif values['tz']: + tzinfo = datetime.timezone.utc + return datetime.datetime(year, month, day, hour, minute, second, fraction, + tzinfo=tzinfo) + + def construct_yaml_omap(self, node): + # Note: we do not check for duplicate keys, because it's too + # CPU-expensive. + omap = [] + yield omap + if not isinstance(node, SequenceNode): + raise ConstructorError("while constructing an ordered map", node.start_mark, + "expected a sequence, but found %s" % node.id, node.start_mark) + for subnode in node.value: + if not isinstance(subnode, MappingNode): + raise ConstructorError("while constructing an ordered map", node.start_mark, + "expected a mapping of length 1, but found %s" % subnode.id, + subnode.start_mark) + if len(subnode.value) != 1: + raise ConstructorError("while constructing an ordered map", node.start_mark, + "expected a single mapping item, but found %d items" % len(subnode.value), + subnode.start_mark) + key_node, value_node = subnode.value[0] + key = self.construct_object(key_node) + value = self.construct_object(value_node) + omap.append((key, value)) + + def construct_yaml_pairs(self, node): + # Note: the same code as `construct_yaml_omap`. + pairs = [] + yield pairs + if not isinstance(node, SequenceNode): + raise ConstructorError("while constructing pairs", node.start_mark, + "expected a sequence, but found %s" % node.id, node.start_mark) + for subnode in node.value: + if not isinstance(subnode, MappingNode): + raise ConstructorError("while constructing pairs", node.start_mark, + "expected a mapping of length 1, but found %s" % subnode.id, + subnode.start_mark) + if len(subnode.value) != 1: + raise ConstructorError("while constructing pairs", node.start_mark, + "expected a single mapping item, but found %d items" % len(subnode.value), + subnode.start_mark) + key_node, value_node = subnode.value[0] + key = self.construct_object(key_node) + value = self.construct_object(value_node) + pairs.append((key, value)) + + def construct_yaml_set(self, node): + data = set() + yield data + value = self.construct_mapping(node) + data.update(value) + + def construct_yaml_str(self, node): + return self.construct_scalar(node) + + def construct_yaml_seq(self, node): + data = [] + yield data + data.extend(self.construct_sequence(node)) + + def construct_yaml_map(self, node): + data = {} + yield data + value = self.construct_mapping(node) + data.update(value) + + def construct_yaml_object(self, node, cls): + data = cls.__new__(cls) + yield data + if hasattr(data, '__setstate__'): + state = self.construct_mapping(node, deep=True) + data.__setstate__(state) + else: + state = self.construct_mapping(node) + data.__dict__.update(state) + + def construct_undefined(self, node): + raise ConstructorError(None, None, + "could not determine a constructor for the tag %r" % node.tag, + node.start_mark) + +SafeConstructor.add_constructor( + 'tag:yaml.org,2002:null', + SafeConstructor.construct_yaml_null) + +SafeConstructor.add_constructor( + 'tag:yaml.org,2002:bool', + SafeConstructor.construct_yaml_bool) + +SafeConstructor.add_constructor( + 'tag:yaml.org,2002:int', + SafeConstructor.construct_yaml_int) + +SafeConstructor.add_constructor( + 'tag:yaml.org,2002:float', + SafeConstructor.construct_yaml_float) + +SafeConstructor.add_constructor( + 'tag:yaml.org,2002:binary', + SafeConstructor.construct_yaml_binary) + +SafeConstructor.add_constructor( + 'tag:yaml.org,2002:timestamp', + SafeConstructor.construct_yaml_timestamp) + +SafeConstructor.add_constructor( + 'tag:yaml.org,2002:omap', + SafeConstructor.construct_yaml_omap) + +SafeConstructor.add_constructor( + 'tag:yaml.org,2002:pairs', + SafeConstructor.construct_yaml_pairs) + +SafeConstructor.add_constructor( + 'tag:yaml.org,2002:set', + SafeConstructor.construct_yaml_set) + +SafeConstructor.add_constructor( + 'tag:yaml.org,2002:str', + SafeConstructor.construct_yaml_str) + +SafeConstructor.add_constructor( + 'tag:yaml.org,2002:seq', + SafeConstructor.construct_yaml_seq) + +SafeConstructor.add_constructor( + 'tag:yaml.org,2002:map', + SafeConstructor.construct_yaml_map) + +SafeConstructor.add_constructor(None, + SafeConstructor.construct_undefined) + +class FullConstructor(SafeConstructor): + # 'extend' is blacklisted because it is used by + # construct_python_object_apply to add `listitems` to a newly generate + # python instance + def get_state_keys_blacklist(self): + return ['^extend$', '^__.*__$'] + + def get_state_keys_blacklist_regexp(self): + if not hasattr(self, 'state_keys_blacklist_regexp'): + self.state_keys_blacklist_regexp = re.compile('(' + '|'.join(self.get_state_keys_blacklist()) + ')') + return self.state_keys_blacklist_regexp + + def construct_python_str(self, node): + return self.construct_scalar(node) + + def construct_python_unicode(self, node): + return self.construct_scalar(node) + + def construct_python_bytes(self, node): + try: + value = self.construct_scalar(node).encode('ascii') + except UnicodeEncodeError as exc: + raise ConstructorError(None, None, + "failed to convert base64 data into ascii: %s" % exc, + node.start_mark) + try: + if hasattr(base64, 'decodebytes'): + return base64.decodebytes(value) + else: + return base64.decodestring(value) + except binascii.Error as exc: + raise ConstructorError(None, None, + "failed to decode base64 data: %s" % exc, node.start_mark) + + def construct_python_long(self, node): + return self.construct_yaml_int(node) + + def construct_python_complex(self, node): + return complex(self.construct_scalar(node)) + + def construct_python_tuple(self, node): + return tuple(self.construct_sequence(node)) + + def find_python_module(self, name, mark, unsafe=False): + if not name: + raise ConstructorError("while constructing a Python module", mark, + "expected non-empty name appended to the tag", mark) + if unsafe: + try: + __import__(name) + except ImportError as exc: + raise ConstructorError("while constructing a Python module", mark, + "cannot find module %r (%s)" % (name, exc), mark) + if name not in sys.modules: + raise ConstructorError("while constructing a Python module", mark, + "module %r is not imported" % name, mark) + return sys.modules[name] + + def find_python_name(self, name, mark, unsafe=False): + if not name: + raise ConstructorError("while constructing a Python object", mark, + "expected non-empty name appended to the tag", mark) + if '.' in name: + module_name, object_name = name.rsplit('.', 1) + else: + module_name = 'builtins' + object_name = name + if unsafe: + try: + __import__(module_name) + except ImportError as exc: + raise ConstructorError("while constructing a Python object", mark, + "cannot find module %r (%s)" % (module_name, exc), mark) + if module_name not in sys.modules: + raise ConstructorError("while constructing a Python object", mark, + "module %r is not imported" % module_name, mark) + module = sys.modules[module_name] + if not hasattr(module, object_name): + raise ConstructorError("while constructing a Python object", mark, + "cannot find %r in the module %r" + % (object_name, module.__name__), mark) + return getattr(module, object_name) + + def construct_python_name(self, suffix, node): + value = self.construct_scalar(node) + if value: + raise ConstructorError("while constructing a Python name", node.start_mark, + "expected the empty value, but found %r" % value, node.start_mark) + return self.find_python_name(suffix, node.start_mark) + + def construct_python_module(self, suffix, node): + value = self.construct_scalar(node) + if value: + raise ConstructorError("while constructing a Python module", node.start_mark, + "expected the empty value, but found %r" % value, node.start_mark) + return self.find_python_module(suffix, node.start_mark) + + def make_python_instance(self, suffix, node, + args=None, kwds=None, newobj=False, unsafe=False): + if not args: + args = [] + if not kwds: + kwds = {} + cls = self.find_python_name(suffix, node.start_mark) + if not (unsafe or isinstance(cls, type)): + raise ConstructorError("while constructing a Python instance", node.start_mark, + "expected a class, but found %r" % type(cls), + node.start_mark) + if newobj and isinstance(cls, type): + return cls.__new__(cls, *args, **kwds) + else: + return cls(*args, **kwds) + + def set_python_instance_state(self, instance, state, unsafe=False): + if hasattr(instance, '__setstate__'): + instance.__setstate__(state) + else: + slotstate = {} + if isinstance(state, tuple) and len(state) == 2: + state, slotstate = state + if hasattr(instance, '__dict__'): + if not unsafe and state: + for key in state.keys(): + self.check_state_key(key) + instance.__dict__.update(state) + elif state: + slotstate.update(state) + for key, value in slotstate.items(): + if not unsafe: + self.check_state_key(key) + setattr(instance, key, value) + + def construct_python_object(self, suffix, node): + # Format: + # !!python/object:module.name { ... state ... } + instance = self.make_python_instance(suffix, node, newobj=True) + yield instance + deep = hasattr(instance, '__setstate__') + state = self.construct_mapping(node, deep=deep) + self.set_python_instance_state(instance, state) + + def construct_python_object_apply(self, suffix, node, newobj=False): + # Format: + # !!python/object/apply # (or !!python/object/new) + # args: [ ... arguments ... ] + # kwds: { ... keywords ... } + # state: ... state ... + # listitems: [ ... listitems ... ] + # dictitems: { ... dictitems ... } + # or short format: + # !!python/object/apply [ ... arguments ... ] + # The difference between !!python/object/apply and !!python/object/new + # is how an object is created, check make_python_instance for details. + if isinstance(node, SequenceNode): + args = self.construct_sequence(node, deep=True) + kwds = {} + state = {} + listitems = [] + dictitems = {} + else: + value = self.construct_mapping(node, deep=True) + args = value.get('args', []) + kwds = value.get('kwds', {}) + state = value.get('state', {}) + listitems = value.get('listitems', []) + dictitems = value.get('dictitems', {}) + instance = self.make_python_instance(suffix, node, args, kwds, newobj) + if state: + self.set_python_instance_state(instance, state) + if listitems: + instance.extend(listitems) + if dictitems: + for key in dictitems: + instance[key] = dictitems[key] + return instance + + def construct_python_object_new(self, suffix, node): + return self.construct_python_object_apply(suffix, node, newobj=True) + +FullConstructor.add_constructor( + 'tag:yaml.org,2002:python/none', + FullConstructor.construct_yaml_null) + +FullConstructor.add_constructor( + 'tag:yaml.org,2002:python/bool', + FullConstructor.construct_yaml_bool) + +FullConstructor.add_constructor( + 'tag:yaml.org,2002:python/str', + FullConstructor.construct_python_str) + +FullConstructor.add_constructor( + 'tag:yaml.org,2002:python/unicode', + FullConstructor.construct_python_unicode) + +FullConstructor.add_constructor( + 'tag:yaml.org,2002:python/bytes', + FullConstructor.construct_python_bytes) + +FullConstructor.add_constructor( + 'tag:yaml.org,2002:python/int', + FullConstructor.construct_yaml_int) + +FullConstructor.add_constructor( + 'tag:yaml.org,2002:python/long', + FullConstructor.construct_python_long) + +FullConstructor.add_constructor( + 'tag:yaml.org,2002:python/float', + FullConstructor.construct_yaml_float) + +FullConstructor.add_constructor( + 'tag:yaml.org,2002:python/complex', + FullConstructor.construct_python_complex) + +FullConstructor.add_constructor( + 'tag:yaml.org,2002:python/list', + FullConstructor.construct_yaml_seq) + +FullConstructor.add_constructor( + 'tag:yaml.org,2002:python/tuple', + FullConstructor.construct_python_tuple) + +FullConstructor.add_constructor( + 'tag:yaml.org,2002:python/dict', + FullConstructor.construct_yaml_map) + +FullConstructor.add_multi_constructor( + 'tag:yaml.org,2002:python/name:', + FullConstructor.construct_python_name) + +class UnsafeConstructor(FullConstructor): + + def find_python_module(self, name, mark): + return super(UnsafeConstructor, self).find_python_module(name, mark, unsafe=True) + + def find_python_name(self, name, mark): + return super(UnsafeConstructor, self).find_python_name(name, mark, unsafe=True) + + def make_python_instance(self, suffix, node, args=None, kwds=None, newobj=False): + return super(UnsafeConstructor, self).make_python_instance( + suffix, node, args, kwds, newobj, unsafe=True) + + def set_python_instance_state(self, instance, state): + return super(UnsafeConstructor, self).set_python_instance_state( + instance, state, unsafe=True) + +UnsafeConstructor.add_multi_constructor( + 'tag:yaml.org,2002:python/module:', + UnsafeConstructor.construct_python_module) + +UnsafeConstructor.add_multi_constructor( + 'tag:yaml.org,2002:python/object:', + UnsafeConstructor.construct_python_object) + +UnsafeConstructor.add_multi_constructor( + 'tag:yaml.org,2002:python/object/new:', + UnsafeConstructor.construct_python_object_new) + +UnsafeConstructor.add_multi_constructor( + 'tag:yaml.org,2002:python/object/apply:', + UnsafeConstructor.construct_python_object_apply) + +# Constructor is same as UnsafeConstructor. Need to leave this in place in case +# people have extended it directly. +class Constructor(UnsafeConstructor): + pass diff --git a/.venv/Lib/site-packages/yaml/cyaml.py b/.venv/Lib/site-packages/yaml/cyaml.py new file mode 100644 index 0000000000000000000000000000000000000000..0c21345879b298bb8668201bebe7d289586b17f9 --- /dev/null +++ b/.venv/Lib/site-packages/yaml/cyaml.py @@ -0,0 +1,101 @@ + +__all__ = [ + 'CBaseLoader', 'CSafeLoader', 'CFullLoader', 'CUnsafeLoader', 'CLoader', + 'CBaseDumper', 'CSafeDumper', 'CDumper' +] + +from yaml._yaml import CParser, CEmitter + +from .constructor import * + +from .serializer import * +from .representer import * + +from .resolver import * + +class CBaseLoader(CParser, BaseConstructor, BaseResolver): + + def __init__(self, stream): + CParser.__init__(self, stream) + BaseConstructor.__init__(self) + BaseResolver.__init__(self) + +class CSafeLoader(CParser, SafeConstructor, Resolver): + + def __init__(self, stream): + CParser.__init__(self, stream) + SafeConstructor.__init__(self) + Resolver.__init__(self) + +class CFullLoader(CParser, FullConstructor, Resolver): + + def __init__(self, stream): + CParser.__init__(self, stream) + FullConstructor.__init__(self) + Resolver.__init__(self) + +class CUnsafeLoader(CParser, UnsafeConstructor, Resolver): + + def __init__(self, stream): + CParser.__init__(self, stream) + UnsafeConstructor.__init__(self) + Resolver.__init__(self) + +class CLoader(CParser, Constructor, Resolver): + + def __init__(self, stream): + CParser.__init__(self, stream) + Constructor.__init__(self) + Resolver.__init__(self) + +class CBaseDumper(CEmitter, BaseRepresenter, BaseResolver): + + def __init__(self, stream, + default_style=None, default_flow_style=False, + canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None, + encoding=None, explicit_start=None, explicit_end=None, + version=None, tags=None, sort_keys=True): + CEmitter.__init__(self, stream, canonical=canonical, + indent=indent, width=width, encoding=encoding, + allow_unicode=allow_unicode, line_break=line_break, + explicit_start=explicit_start, explicit_end=explicit_end, + version=version, tags=tags) + Representer.__init__(self, default_style=default_style, + default_flow_style=default_flow_style, sort_keys=sort_keys) + Resolver.__init__(self) + +class CSafeDumper(CEmitter, SafeRepresenter, Resolver): + + def __init__(self, stream, + default_style=None, default_flow_style=False, + canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None, + encoding=None, explicit_start=None, explicit_end=None, + version=None, tags=None, sort_keys=True): + CEmitter.__init__(self, stream, canonical=canonical, + indent=indent, width=width, encoding=encoding, + allow_unicode=allow_unicode, line_break=line_break, + explicit_start=explicit_start, explicit_end=explicit_end, + version=version, tags=tags) + SafeRepresenter.__init__(self, default_style=default_style, + default_flow_style=default_flow_style, sort_keys=sort_keys) + Resolver.__init__(self) + +class CDumper(CEmitter, Serializer, Representer, Resolver): + + def __init__(self, stream, + default_style=None, default_flow_style=False, + canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None, + encoding=None, explicit_start=None, explicit_end=None, + version=None, tags=None, sort_keys=True): + CEmitter.__init__(self, stream, canonical=canonical, + indent=indent, width=width, encoding=encoding, + allow_unicode=allow_unicode, line_break=line_break, + explicit_start=explicit_start, explicit_end=explicit_end, + version=version, tags=tags) + Representer.__init__(self, default_style=default_style, + default_flow_style=default_flow_style, sort_keys=sort_keys) + Resolver.__init__(self) + diff --git a/.venv/Lib/site-packages/yaml/dumper.py b/.venv/Lib/site-packages/yaml/dumper.py new file mode 100644 index 0000000000000000000000000000000000000000..6aadba551f3836b02f4752277f4b3027073defad --- /dev/null +++ b/.venv/Lib/site-packages/yaml/dumper.py @@ -0,0 +1,62 @@ + +__all__ = ['BaseDumper', 'SafeDumper', 'Dumper'] + +from .emitter import * +from .serializer import * +from .representer import * +from .resolver import * + +class BaseDumper(Emitter, Serializer, BaseRepresenter, BaseResolver): + + def __init__(self, stream, + default_style=None, default_flow_style=False, + canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None, + encoding=None, explicit_start=None, explicit_end=None, + version=None, tags=None, sort_keys=True): + Emitter.__init__(self, stream, canonical=canonical, + indent=indent, width=width, + allow_unicode=allow_unicode, line_break=line_break) + Serializer.__init__(self, encoding=encoding, + explicit_start=explicit_start, explicit_end=explicit_end, + version=version, tags=tags) + Representer.__init__(self, default_style=default_style, + default_flow_style=default_flow_style, sort_keys=sort_keys) + Resolver.__init__(self) + +class SafeDumper(Emitter, Serializer, SafeRepresenter, Resolver): + + def __init__(self, stream, + default_style=None, default_flow_style=False, + canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None, + encoding=None, explicit_start=None, explicit_end=None, + version=None, tags=None, sort_keys=True): + Emitter.__init__(self, stream, canonical=canonical, + indent=indent, width=width, + allow_unicode=allow_unicode, line_break=line_break) + Serializer.__init__(self, encoding=encoding, + explicit_start=explicit_start, explicit_end=explicit_end, + version=version, tags=tags) + SafeRepresenter.__init__(self, default_style=default_style, + default_flow_style=default_flow_style, sort_keys=sort_keys) + Resolver.__init__(self) + +class Dumper(Emitter, Serializer, Representer, Resolver): + + def __init__(self, stream, + default_style=None, default_flow_style=False, + canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None, + encoding=None, explicit_start=None, explicit_end=None, + version=None, tags=None, sort_keys=True): + Emitter.__init__(self, stream, canonical=canonical, + indent=indent, width=width, + allow_unicode=allow_unicode, line_break=line_break) + Serializer.__init__(self, encoding=encoding, + explicit_start=explicit_start, explicit_end=explicit_end, + version=version, tags=tags) + Representer.__init__(self, default_style=default_style, + default_flow_style=default_flow_style, sort_keys=sort_keys) + Resolver.__init__(self) + diff --git a/.venv/Lib/site-packages/yaml/emitter.py b/.venv/Lib/site-packages/yaml/emitter.py new file mode 100644 index 0000000000000000000000000000000000000000..a664d011162af69184df2f8e59ab7feec818f7c7 --- /dev/null +++ b/.venv/Lib/site-packages/yaml/emitter.py @@ -0,0 +1,1137 @@ + +# Emitter expects events obeying the following grammar: +# stream ::= STREAM-START document* STREAM-END +# document ::= DOCUMENT-START node DOCUMENT-END +# node ::= SCALAR | sequence | mapping +# sequence ::= SEQUENCE-START node* SEQUENCE-END +# mapping ::= MAPPING-START (node node)* MAPPING-END + +__all__ = ['Emitter', 'EmitterError'] + +from .error import YAMLError +from .events import * + +class EmitterError(YAMLError): + pass + +class ScalarAnalysis: + def __init__(self, scalar, empty, multiline, + allow_flow_plain, allow_block_plain, + allow_single_quoted, allow_double_quoted, + allow_block): + self.scalar = scalar + self.empty = empty + self.multiline = multiline + self.allow_flow_plain = allow_flow_plain + self.allow_block_plain = allow_block_plain + self.allow_single_quoted = allow_single_quoted + self.allow_double_quoted = allow_double_quoted + self.allow_block = allow_block + +class Emitter: + + DEFAULT_TAG_PREFIXES = { + '!' : '!', + 'tag:yaml.org,2002:' : '!!', + } + + def __init__(self, stream, canonical=None, indent=None, width=None, + allow_unicode=None, line_break=None): + + # The stream should have the methods `write` and possibly `flush`. + self.stream = stream + + # Encoding can be overridden by STREAM-START. + self.encoding = None + + # Emitter is a state machine with a stack of states to handle nested + # structures. + self.states = [] + self.state = self.expect_stream_start + + # Current event and the event queue. + self.events = [] + self.event = None + + # The current indentation level and the stack of previous indents. + self.indents = [] + self.indent = None + + # Flow level. + self.flow_level = 0 + + # Contexts. + self.root_context = False + self.sequence_context = False + self.mapping_context = False + self.simple_key_context = False + + # Characteristics of the last emitted character: + # - current position. + # - is it a whitespace? + # - is it an indention character + # (indentation space, '-', '?', or ':')? + self.line = 0 + self.column = 0 + self.whitespace = True + self.indention = True + + # Whether the document requires an explicit document indicator + self.open_ended = False + + # Formatting details. + self.canonical = canonical + self.allow_unicode = allow_unicode + self.best_indent = 2 + if indent and 1 < indent < 10: + self.best_indent = indent + self.best_width = 80 + if width and width > self.best_indent*2: + self.best_width = width + self.best_line_break = '\n' + if line_break in ['\r', '\n', '\r\n']: + self.best_line_break = line_break + + # Tag prefixes. + self.tag_prefixes = None + + # Prepared anchor and tag. + self.prepared_anchor = None + self.prepared_tag = None + + # Scalar analysis and style. + self.analysis = None + self.style = None + + def dispose(self): + # Reset the state attributes (to clear self-references) + self.states = [] + self.state = None + + def emit(self, event): + self.events.append(event) + while not self.need_more_events(): + self.event = self.events.pop(0) + self.state() + self.event = None + + # In some cases, we wait for a few next events before emitting. + + def need_more_events(self): + if not self.events: + return True + event = self.events[0] + if isinstance(event, DocumentStartEvent): + return self.need_events(1) + elif isinstance(event, SequenceStartEvent): + return self.need_events(2) + elif isinstance(event, MappingStartEvent): + return self.need_events(3) + else: + return False + + def need_events(self, count): + level = 0 + for event in self.events[1:]: + if isinstance(event, (DocumentStartEvent, CollectionStartEvent)): + level += 1 + elif isinstance(event, (DocumentEndEvent, CollectionEndEvent)): + level -= 1 + elif isinstance(event, StreamEndEvent): + level = -1 + if level < 0: + return False + return (len(self.events) < count+1) + + def increase_indent(self, flow=False, indentless=False): + self.indents.append(self.indent) + if self.indent is None: + if flow: + self.indent = self.best_indent + else: + self.indent = 0 + elif not indentless: + self.indent += self.best_indent + + # States. + + # Stream handlers. + + def expect_stream_start(self): + if isinstance(self.event, StreamStartEvent): + if self.event.encoding and not hasattr(self.stream, 'encoding'): + self.encoding = self.event.encoding + self.write_stream_start() + self.state = self.expect_first_document_start + else: + raise EmitterError("expected StreamStartEvent, but got %s" + % self.event) + + def expect_nothing(self): + raise EmitterError("expected nothing, but got %s" % self.event) + + # Document handlers. + + def expect_first_document_start(self): + return self.expect_document_start(first=True) + + def expect_document_start(self, first=False): + if isinstance(self.event, DocumentStartEvent): + if (self.event.version or self.event.tags) and self.open_ended: + self.write_indicator('...', True) + self.write_indent() + if self.event.version: + version_text = self.prepare_version(self.event.version) + self.write_version_directive(version_text) + self.tag_prefixes = self.DEFAULT_TAG_PREFIXES.copy() + if self.event.tags: + handles = sorted(self.event.tags.keys()) + for handle in handles: + prefix = self.event.tags[handle] + self.tag_prefixes[prefix] = handle + handle_text = self.prepare_tag_handle(handle) + prefix_text = self.prepare_tag_prefix(prefix) + self.write_tag_directive(handle_text, prefix_text) + implicit = (first and not self.event.explicit and not self.canonical + and not self.event.version and not self.event.tags + and not self.check_empty_document()) + if not implicit: + self.write_indent() + self.write_indicator('---', True) + if self.canonical: + self.write_indent() + self.state = self.expect_document_root + elif isinstance(self.event, StreamEndEvent): + if self.open_ended: + self.write_indicator('...', True) + self.write_indent() + self.write_stream_end() + self.state = self.expect_nothing + else: + raise EmitterError("expected DocumentStartEvent, but got %s" + % self.event) + + def expect_document_end(self): + if isinstance(self.event, DocumentEndEvent): + self.write_indent() + if self.event.explicit: + self.write_indicator('...', True) + self.write_indent() + self.flush_stream() + self.state = self.expect_document_start + else: + raise EmitterError("expected DocumentEndEvent, but got %s" + % self.event) + + def expect_document_root(self): + self.states.append(self.expect_document_end) + self.expect_node(root=True) + + # Node handlers. + + def expect_node(self, root=False, sequence=False, mapping=False, + simple_key=False): + self.root_context = root + self.sequence_context = sequence + self.mapping_context = mapping + self.simple_key_context = simple_key + if isinstance(self.event, AliasEvent): + self.expect_alias() + elif isinstance(self.event, (ScalarEvent, CollectionStartEvent)): + self.process_anchor('&') + self.process_tag() + if isinstance(self.event, ScalarEvent): + self.expect_scalar() + elif isinstance(self.event, SequenceStartEvent): + if self.flow_level or self.canonical or self.event.flow_style \ + or self.check_empty_sequence(): + self.expect_flow_sequence() + else: + self.expect_block_sequence() + elif isinstance(self.event, MappingStartEvent): + if self.flow_level or self.canonical or self.event.flow_style \ + or self.check_empty_mapping(): + self.expect_flow_mapping() + else: + self.expect_block_mapping() + else: + raise EmitterError("expected NodeEvent, but got %s" % self.event) + + def expect_alias(self): + if self.event.anchor is None: + raise EmitterError("anchor is not specified for alias") + self.process_anchor('*') + self.state = self.states.pop() + + def expect_scalar(self): + self.increase_indent(flow=True) + self.process_scalar() + self.indent = self.indents.pop() + self.state = self.states.pop() + + # Flow sequence handlers. + + def expect_flow_sequence(self): + self.write_indicator('[', True, whitespace=True) + self.flow_level += 1 + self.increase_indent(flow=True) + self.state = self.expect_first_flow_sequence_item + + def expect_first_flow_sequence_item(self): + if isinstance(self.event, SequenceEndEvent): + self.indent = self.indents.pop() + self.flow_level -= 1 + self.write_indicator(']', False) + self.state = self.states.pop() + else: + if self.canonical or self.column > self.best_width: + self.write_indent() + self.states.append(self.expect_flow_sequence_item) + self.expect_node(sequence=True) + + def expect_flow_sequence_item(self): + if isinstance(self.event, SequenceEndEvent): + self.indent = self.indents.pop() + self.flow_level -= 1 + if self.canonical: + self.write_indicator(',', False) + self.write_indent() + self.write_indicator(']', False) + self.state = self.states.pop() + else: + self.write_indicator(',', False) + if self.canonical or self.column > self.best_width: + self.write_indent() + self.states.append(self.expect_flow_sequence_item) + self.expect_node(sequence=True) + + # Flow mapping handlers. + + def expect_flow_mapping(self): + self.write_indicator('{', True, whitespace=True) + self.flow_level += 1 + self.increase_indent(flow=True) + self.state = self.expect_first_flow_mapping_key + + def expect_first_flow_mapping_key(self): + if isinstance(self.event, MappingEndEvent): + self.indent = self.indents.pop() + self.flow_level -= 1 + self.write_indicator('}', False) + self.state = self.states.pop() + else: + if self.canonical or self.column > self.best_width: + self.write_indent() + if not self.canonical and self.check_simple_key(): + self.states.append(self.expect_flow_mapping_simple_value) + self.expect_node(mapping=True, simple_key=True) + else: + self.write_indicator('?', True) + self.states.append(self.expect_flow_mapping_value) + self.expect_node(mapping=True) + + def expect_flow_mapping_key(self): + if isinstance(self.event, MappingEndEvent): + self.indent = self.indents.pop() + self.flow_level -= 1 + if self.canonical: + self.write_indicator(',', False) + self.write_indent() + self.write_indicator('}', False) + self.state = self.states.pop() + else: + self.write_indicator(',', False) + if self.canonical or self.column > self.best_width: + self.write_indent() + if not self.canonical and self.check_simple_key(): + self.states.append(self.expect_flow_mapping_simple_value) + self.expect_node(mapping=True, simple_key=True) + else: + self.write_indicator('?', True) + self.states.append(self.expect_flow_mapping_value) + self.expect_node(mapping=True) + + def expect_flow_mapping_simple_value(self): + self.write_indicator(':', False) + self.states.append(self.expect_flow_mapping_key) + self.expect_node(mapping=True) + + def expect_flow_mapping_value(self): + if self.canonical or self.column > self.best_width: + self.write_indent() + self.write_indicator(':', True) + self.states.append(self.expect_flow_mapping_key) + self.expect_node(mapping=True) + + # Block sequence handlers. + + def expect_block_sequence(self): + indentless = (self.mapping_context and not self.indention) + self.increase_indent(flow=False, indentless=indentless) + self.state = self.expect_first_block_sequence_item + + def expect_first_block_sequence_item(self): + return self.expect_block_sequence_item(first=True) + + def expect_block_sequence_item(self, first=False): + if not first and isinstance(self.event, SequenceEndEvent): + self.indent = self.indents.pop() + self.state = self.states.pop() + else: + self.write_indent() + self.write_indicator('-', True, indention=True) + self.states.append(self.expect_block_sequence_item) + self.expect_node(sequence=True) + + # Block mapping handlers. + + def expect_block_mapping(self): + self.increase_indent(flow=False) + self.state = self.expect_first_block_mapping_key + + def expect_first_block_mapping_key(self): + return self.expect_block_mapping_key(first=True) + + def expect_block_mapping_key(self, first=False): + if not first and isinstance(self.event, MappingEndEvent): + self.indent = self.indents.pop() + self.state = self.states.pop() + else: + self.write_indent() + if self.check_simple_key(): + self.states.append(self.expect_block_mapping_simple_value) + self.expect_node(mapping=True, simple_key=True) + else: + self.write_indicator('?', True, indention=True) + self.states.append(self.expect_block_mapping_value) + self.expect_node(mapping=True) + + def expect_block_mapping_simple_value(self): + self.write_indicator(':', False) + self.states.append(self.expect_block_mapping_key) + self.expect_node(mapping=True) + + def expect_block_mapping_value(self): + self.write_indent() + self.write_indicator(':', True, indention=True) + self.states.append(self.expect_block_mapping_key) + self.expect_node(mapping=True) + + # Checkers. + + def check_empty_sequence(self): + return (isinstance(self.event, SequenceStartEvent) and self.events + and isinstance(self.events[0], SequenceEndEvent)) + + def check_empty_mapping(self): + return (isinstance(self.event, MappingStartEvent) and self.events + and isinstance(self.events[0], MappingEndEvent)) + + def check_empty_document(self): + if not isinstance(self.event, DocumentStartEvent) or not self.events: + return False + event = self.events[0] + return (isinstance(event, ScalarEvent) and event.anchor is None + and event.tag is None and event.implicit and event.value == '') + + def check_simple_key(self): + length = 0 + if isinstance(self.event, NodeEvent) and self.event.anchor is not None: + if self.prepared_anchor is None: + self.prepared_anchor = self.prepare_anchor(self.event.anchor) + length += len(self.prepared_anchor) + if isinstance(self.event, (ScalarEvent, CollectionStartEvent)) \ + and self.event.tag is not None: + if self.prepared_tag is None: + self.prepared_tag = self.prepare_tag(self.event.tag) + length += len(self.prepared_tag) + if isinstance(self.event, ScalarEvent): + if self.analysis is None: + self.analysis = self.analyze_scalar(self.event.value) + length += len(self.analysis.scalar) + return (length < 128 and (isinstance(self.event, AliasEvent) + or (isinstance(self.event, ScalarEvent) + and not self.analysis.empty and not self.analysis.multiline) + or self.check_empty_sequence() or self.check_empty_mapping())) + + # Anchor, Tag, and Scalar processors. + + def process_anchor(self, indicator): + if self.event.anchor is None: + self.prepared_anchor = None + return + if self.prepared_anchor is None: + self.prepared_anchor = self.prepare_anchor(self.event.anchor) + if self.prepared_anchor: + self.write_indicator(indicator+self.prepared_anchor, True) + self.prepared_anchor = None + + def process_tag(self): + tag = self.event.tag + if isinstance(self.event, ScalarEvent): + if self.style is None: + self.style = self.choose_scalar_style() + if ((not self.canonical or tag is None) and + ((self.style == '' and self.event.implicit[0]) + or (self.style != '' and self.event.implicit[1]))): + self.prepared_tag = None + return + if self.event.implicit[0] and tag is None: + tag = '!' + self.prepared_tag = None + else: + if (not self.canonical or tag is None) and self.event.implicit: + self.prepared_tag = None + return + if tag is None: + raise EmitterError("tag is not specified") + if self.prepared_tag is None: + self.prepared_tag = self.prepare_tag(tag) + if self.prepared_tag: + self.write_indicator(self.prepared_tag, True) + self.prepared_tag = None + + def choose_scalar_style(self): + if self.analysis is None: + self.analysis = self.analyze_scalar(self.event.value) + if self.event.style == '"' or self.canonical: + return '"' + if not self.event.style and self.event.implicit[0]: + if (not (self.simple_key_context and + (self.analysis.empty or self.analysis.multiline)) + and (self.flow_level and self.analysis.allow_flow_plain + or (not self.flow_level and self.analysis.allow_block_plain))): + return '' + if self.event.style and self.event.style in '|>': + if (not self.flow_level and not self.simple_key_context + and self.analysis.allow_block): + return self.event.style + if not self.event.style or self.event.style == '\'': + if (self.analysis.allow_single_quoted and + not (self.simple_key_context and self.analysis.multiline)): + return '\'' + return '"' + + def process_scalar(self): + if self.analysis is None: + self.analysis = self.analyze_scalar(self.event.value) + if self.style is None: + self.style = self.choose_scalar_style() + split = (not self.simple_key_context) + #if self.analysis.multiline and split \ + # and (not self.style or self.style in '\'\"'): + # self.write_indent() + if self.style == '"': + self.write_double_quoted(self.analysis.scalar, split) + elif self.style == '\'': + self.write_single_quoted(self.analysis.scalar, split) + elif self.style == '>': + self.write_folded(self.analysis.scalar) + elif self.style == '|': + self.write_literal(self.analysis.scalar) + else: + self.write_plain(self.analysis.scalar, split) + self.analysis = None + self.style = None + + # Analyzers. + + def prepare_version(self, version): + major, minor = version + if major != 1: + raise EmitterError("unsupported YAML version: %d.%d" % (major, minor)) + return '%d.%d' % (major, minor) + + def prepare_tag_handle(self, handle): + if not handle: + raise EmitterError("tag handle must not be empty") + if handle[0] != '!' or handle[-1] != '!': + raise EmitterError("tag handle must start and end with '!': %r" % handle) + for ch in handle[1:-1]: + if not ('0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' \ + or ch in '-_'): + raise EmitterError("invalid character %r in the tag handle: %r" + % (ch, handle)) + return handle + + def prepare_tag_prefix(self, prefix): + if not prefix: + raise EmitterError("tag prefix must not be empty") + chunks = [] + start = end = 0 + if prefix[0] == '!': + end = 1 + while end < len(prefix): + ch = prefix[end] + if '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' \ + or ch in '-;/?!:@&=+$,_.~*\'()[]': + end += 1 + else: + if start < end: + chunks.append(prefix[start:end]) + start = end = end+1 + data = ch.encode('utf-8') + for ch in data: + chunks.append('%%%02X' % ord(ch)) + if start < end: + chunks.append(prefix[start:end]) + return ''.join(chunks) + + def prepare_tag(self, tag): + if not tag: + raise EmitterError("tag must not be empty") + if tag == '!': + return tag + handle = None + suffix = tag + prefixes = sorted(self.tag_prefixes.keys()) + for prefix in prefixes: + if tag.startswith(prefix) \ + and (prefix == '!' or len(prefix) < len(tag)): + handle = self.tag_prefixes[prefix] + suffix = tag[len(prefix):] + chunks = [] + start = end = 0 + while end < len(suffix): + ch = suffix[end] + if '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' \ + or ch in '-;/?:@&=+$,_.~*\'()[]' \ + or (ch == '!' and handle != '!'): + end += 1 + else: + if start < end: + chunks.append(suffix[start:end]) + start = end = end+1 + data = ch.encode('utf-8') + for ch in data: + chunks.append('%%%02X' % ch) + if start < end: + chunks.append(suffix[start:end]) + suffix_text = ''.join(chunks) + if handle: + return '%s%s' % (handle, suffix_text) + else: + return '!<%s>' % suffix_text + + def prepare_anchor(self, anchor): + if not anchor: + raise EmitterError("anchor must not be empty") + for ch in anchor: + if not ('0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' \ + or ch in '-_'): + raise EmitterError("invalid character %r in the anchor: %r" + % (ch, anchor)) + return anchor + + def analyze_scalar(self, scalar): + + # Empty scalar is a special case. + if not scalar: + return ScalarAnalysis(scalar=scalar, empty=True, multiline=False, + allow_flow_plain=False, allow_block_plain=True, + allow_single_quoted=True, allow_double_quoted=True, + allow_block=False) + + # Indicators and special characters. + block_indicators = False + flow_indicators = False + line_breaks = False + special_characters = False + + # Important whitespace combinations. + leading_space = False + leading_break = False + trailing_space = False + trailing_break = False + break_space = False + space_break = False + + # Check document indicators. + if scalar.startswith('---') or scalar.startswith('...'): + block_indicators = True + flow_indicators = True + + # First character or preceded by a whitespace. + preceded_by_whitespace = True + + # Last character or followed by a whitespace. + followed_by_whitespace = (len(scalar) == 1 or + scalar[1] in '\0 \t\r\n\x85\u2028\u2029') + + # The previous character is a space. + previous_space = False + + # The previous character is a break. + previous_break = False + + index = 0 + while index < len(scalar): + ch = scalar[index] + + # Check for indicators. + if index == 0: + # Leading indicators are special characters. + if ch in '#,[]{}&*!|>\'\"%@`': + flow_indicators = True + block_indicators = True + if ch in '?:': + flow_indicators = True + if followed_by_whitespace: + block_indicators = True + if ch == '-' and followed_by_whitespace: + flow_indicators = True + block_indicators = True + else: + # Some indicators cannot appear within a scalar as well. + if ch in ',?[]{}': + flow_indicators = True + if ch == ':': + flow_indicators = True + if followed_by_whitespace: + block_indicators = True + if ch == '#' and preceded_by_whitespace: + flow_indicators = True + block_indicators = True + + # Check for line breaks, special, and unicode characters. + if ch in '\n\x85\u2028\u2029': + line_breaks = True + if not (ch == '\n' or '\x20' <= ch <= '\x7E'): + if (ch == '\x85' or '\xA0' <= ch <= '\uD7FF' + or '\uE000' <= ch <= '\uFFFD' + or '\U00010000' <= ch < '\U0010ffff') and ch != '\uFEFF': + unicode_characters = True + if not self.allow_unicode: + special_characters = True + else: + special_characters = True + + # Detect important whitespace combinations. + if ch == ' ': + if index == 0: + leading_space = True + if index == len(scalar)-1: + trailing_space = True + if previous_break: + break_space = True + previous_space = True + previous_break = False + elif ch in '\n\x85\u2028\u2029': + if index == 0: + leading_break = True + if index == len(scalar)-1: + trailing_break = True + if previous_space: + space_break = True + previous_space = False + previous_break = True + else: + previous_space = False + previous_break = False + + # Prepare for the next character. + index += 1 + preceded_by_whitespace = (ch in '\0 \t\r\n\x85\u2028\u2029') + followed_by_whitespace = (index+1 >= len(scalar) or + scalar[index+1] in '\0 \t\r\n\x85\u2028\u2029') + + # Let's decide what styles are allowed. + allow_flow_plain = True + allow_block_plain = True + allow_single_quoted = True + allow_double_quoted = True + allow_block = True + + # Leading and trailing whitespaces are bad for plain scalars. + if (leading_space or leading_break + or trailing_space or trailing_break): + allow_flow_plain = allow_block_plain = False + + # We do not permit trailing spaces for block scalars. + if trailing_space: + allow_block = False + + # Spaces at the beginning of a new line are only acceptable for block + # scalars. + if break_space: + allow_flow_plain = allow_block_plain = allow_single_quoted = False + + # Spaces followed by breaks, as well as special character are only + # allowed for double quoted scalars. + if space_break or special_characters: + allow_flow_plain = allow_block_plain = \ + allow_single_quoted = allow_block = False + + # Although the plain scalar writer supports breaks, we never emit + # multiline plain scalars. + if line_breaks: + allow_flow_plain = allow_block_plain = False + + # Flow indicators are forbidden for flow plain scalars. + if flow_indicators: + allow_flow_plain = False + + # Block indicators are forbidden for block plain scalars. + if block_indicators: + allow_block_plain = False + + return ScalarAnalysis(scalar=scalar, + empty=False, multiline=line_breaks, + allow_flow_plain=allow_flow_plain, + allow_block_plain=allow_block_plain, + allow_single_quoted=allow_single_quoted, + allow_double_quoted=allow_double_quoted, + allow_block=allow_block) + + # Writers. + + def flush_stream(self): + if hasattr(self.stream, 'flush'): + self.stream.flush() + + def write_stream_start(self): + # Write BOM if needed. + if self.encoding and self.encoding.startswith('utf-16'): + self.stream.write('\uFEFF'.encode(self.encoding)) + + def write_stream_end(self): + self.flush_stream() + + def write_indicator(self, indicator, need_whitespace, + whitespace=False, indention=False): + if self.whitespace or not need_whitespace: + data = indicator + else: + data = ' '+indicator + self.whitespace = whitespace + self.indention = self.indention and indention + self.column += len(data) + self.open_ended = False + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + + def write_indent(self): + indent = self.indent or 0 + if not self.indention or self.column > indent \ + or (self.column == indent and not self.whitespace): + self.write_line_break() + if self.column < indent: + self.whitespace = True + data = ' '*(indent-self.column) + self.column = indent + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + + def write_line_break(self, data=None): + if data is None: + data = self.best_line_break + self.whitespace = True + self.indention = True + self.line += 1 + self.column = 0 + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + + def write_version_directive(self, version_text): + data = '%%YAML %s' % version_text + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + self.write_line_break() + + def write_tag_directive(self, handle_text, prefix_text): + data = '%%TAG %s %s' % (handle_text, prefix_text) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + self.write_line_break() + + # Scalar streams. + + def write_single_quoted(self, text, split=True): + self.write_indicator('\'', True) + spaces = False + breaks = False + start = end = 0 + while end <= len(text): + ch = None + if end < len(text): + ch = text[end] + if spaces: + if ch is None or ch != ' ': + if start+1 == end and self.column > self.best_width and split \ + and start != 0 and end != len(text): + self.write_indent() + else: + data = text[start:end] + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end + elif breaks: + if ch is None or ch not in '\n\x85\u2028\u2029': + if text[start] == '\n': + self.write_line_break() + for br in text[start:end]: + if br == '\n': + self.write_line_break() + else: + self.write_line_break(br) + self.write_indent() + start = end + else: + if ch is None or ch in ' \n\x85\u2028\u2029' or ch == '\'': + if start < end: + data = text[start:end] + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end + if ch == '\'': + data = '\'\'' + self.column += 2 + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end + 1 + if ch is not None: + spaces = (ch == ' ') + breaks = (ch in '\n\x85\u2028\u2029') + end += 1 + self.write_indicator('\'', False) + + ESCAPE_REPLACEMENTS = { + '\0': '0', + '\x07': 'a', + '\x08': 'b', + '\x09': 't', + '\x0A': 'n', + '\x0B': 'v', + '\x0C': 'f', + '\x0D': 'r', + '\x1B': 'e', + '\"': '\"', + '\\': '\\', + '\x85': 'N', + '\xA0': '_', + '\u2028': 'L', + '\u2029': 'P', + } + + def write_double_quoted(self, text, split=True): + self.write_indicator('"', True) + start = end = 0 + while end <= len(text): + ch = None + if end < len(text): + ch = text[end] + if ch is None or ch in '"\\\x85\u2028\u2029\uFEFF' \ + or not ('\x20' <= ch <= '\x7E' + or (self.allow_unicode + and ('\xA0' <= ch <= '\uD7FF' + or '\uE000' <= ch <= '\uFFFD'))): + if start < end: + data = text[start:end] + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end + if ch is not None: + if ch in self.ESCAPE_REPLACEMENTS: + data = '\\'+self.ESCAPE_REPLACEMENTS[ch] + elif ch <= '\xFF': + data = '\\x%02X' % ord(ch) + elif ch <= '\uFFFF': + data = '\\u%04X' % ord(ch) + else: + data = '\\U%08X' % ord(ch) + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end+1 + if 0 < end < len(text)-1 and (ch == ' ' or start >= end) \ + and self.column+(end-start) > self.best_width and split: + data = text[start:end]+'\\' + if start < end: + start = end + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + self.write_indent() + self.whitespace = False + self.indention = False + if text[start] == ' ': + data = '\\' + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + end += 1 + self.write_indicator('"', False) + + def determine_block_hints(self, text): + hints = '' + if text: + if text[0] in ' \n\x85\u2028\u2029': + hints += str(self.best_indent) + if text[-1] not in '\n\x85\u2028\u2029': + hints += '-' + elif len(text) == 1 or text[-2] in '\n\x85\u2028\u2029': + hints += '+' + return hints + + def write_folded(self, text): + hints = self.determine_block_hints(text) + self.write_indicator('>'+hints, True) + if hints[-1:] == '+': + self.open_ended = True + self.write_line_break() + leading_space = True + spaces = False + breaks = True + start = end = 0 + while end <= len(text): + ch = None + if end < len(text): + ch = text[end] + if breaks: + if ch is None or ch not in '\n\x85\u2028\u2029': + if not leading_space and ch is not None and ch != ' ' \ + and text[start] == '\n': + self.write_line_break() + leading_space = (ch == ' ') + for br in text[start:end]: + if br == '\n': + self.write_line_break() + else: + self.write_line_break(br) + if ch is not None: + self.write_indent() + start = end + elif spaces: + if ch != ' ': + if start+1 == end and self.column > self.best_width: + self.write_indent() + else: + data = text[start:end] + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end + else: + if ch is None or ch in ' \n\x85\u2028\u2029': + data = text[start:end] + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + if ch is None: + self.write_line_break() + start = end + if ch is not None: + breaks = (ch in '\n\x85\u2028\u2029') + spaces = (ch == ' ') + end += 1 + + def write_literal(self, text): + hints = self.determine_block_hints(text) + self.write_indicator('|'+hints, True) + if hints[-1:] == '+': + self.open_ended = True + self.write_line_break() + breaks = True + start = end = 0 + while end <= len(text): + ch = None + if end < len(text): + ch = text[end] + if breaks: + if ch is None or ch not in '\n\x85\u2028\u2029': + for br in text[start:end]: + if br == '\n': + self.write_line_break() + else: + self.write_line_break(br) + if ch is not None: + self.write_indent() + start = end + else: + if ch is None or ch in '\n\x85\u2028\u2029': + data = text[start:end] + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + if ch is None: + self.write_line_break() + start = end + if ch is not None: + breaks = (ch in '\n\x85\u2028\u2029') + end += 1 + + def write_plain(self, text, split=True): + if self.root_context: + self.open_ended = True + if not text: + return + if not self.whitespace: + data = ' ' + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + self.whitespace = False + self.indention = False + spaces = False + breaks = False + start = end = 0 + while end <= len(text): + ch = None + if end < len(text): + ch = text[end] + if spaces: + if ch != ' ': + if start+1 == end and self.column > self.best_width and split: + self.write_indent() + self.whitespace = False + self.indention = False + else: + data = text[start:end] + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end + elif breaks: + if ch not in '\n\x85\u2028\u2029': + if text[start] == '\n': + self.write_line_break() + for br in text[start:end]: + if br == '\n': + self.write_line_break() + else: + self.write_line_break(br) + self.write_indent() + self.whitespace = False + self.indention = False + start = end + else: + if ch is None or ch in ' \n\x85\u2028\u2029': + data = text[start:end] + self.column += len(data) + if self.encoding: + data = data.encode(self.encoding) + self.stream.write(data) + start = end + if ch is not None: + spaces = (ch == ' ') + breaks = (ch in '\n\x85\u2028\u2029') + end += 1 diff --git a/.venv/Lib/site-packages/yaml/error.py b/.venv/Lib/site-packages/yaml/error.py new file mode 100644 index 0000000000000000000000000000000000000000..b796b4dc519512c4825ff539a2e6aa20f4d370d0 --- /dev/null +++ b/.venv/Lib/site-packages/yaml/error.py @@ -0,0 +1,75 @@ + +__all__ = ['Mark', 'YAMLError', 'MarkedYAMLError'] + +class Mark: + + def __init__(self, name, index, line, column, buffer, pointer): + self.name = name + self.index = index + self.line = line + self.column = column + self.buffer = buffer + self.pointer = pointer + + def get_snippet(self, indent=4, max_length=75): + if self.buffer is None: + return None + head = '' + start = self.pointer + while start > 0 and self.buffer[start-1] not in '\0\r\n\x85\u2028\u2029': + start -= 1 + if self.pointer-start > max_length/2-1: + head = ' ... ' + start += 5 + break + tail = '' + end = self.pointer + while end < len(self.buffer) and self.buffer[end] not in '\0\r\n\x85\u2028\u2029': + end += 1 + if end-self.pointer > max_length/2-1: + tail = ' ... ' + end -= 5 + break + snippet = self.buffer[start:end] + return ' '*indent + head + snippet + tail + '\n' \ + + ' '*(indent+self.pointer-start+len(head)) + '^' + + def __str__(self): + snippet = self.get_snippet() + where = " in \"%s\", line %d, column %d" \ + % (self.name, self.line+1, self.column+1) + if snippet is not None: + where += ":\n"+snippet + return where + +class YAMLError(Exception): + pass + +class MarkedYAMLError(YAMLError): + + def __init__(self, context=None, context_mark=None, + problem=None, problem_mark=None, note=None): + self.context = context + self.context_mark = context_mark + self.problem = problem + self.problem_mark = problem_mark + self.note = note + + def __str__(self): + lines = [] + if self.context is not None: + lines.append(self.context) + if self.context_mark is not None \ + and (self.problem is None or self.problem_mark is None + or self.context_mark.name != self.problem_mark.name + or self.context_mark.line != self.problem_mark.line + or self.context_mark.column != self.problem_mark.column): + lines.append(str(self.context_mark)) + if self.problem is not None: + lines.append(self.problem) + if self.problem_mark is not None: + lines.append(str(self.problem_mark)) + if self.note is not None: + lines.append(self.note) + return '\n'.join(lines) + diff --git a/.venv/Lib/site-packages/yaml/events.py b/.venv/Lib/site-packages/yaml/events.py new file mode 100644 index 0000000000000000000000000000000000000000..f79ad389cb6c9517e391dcd25534866bc9ccd36a --- /dev/null +++ b/.venv/Lib/site-packages/yaml/events.py @@ -0,0 +1,86 @@ + +# Abstract classes. + +class Event(object): + def __init__(self, start_mark=None, end_mark=None): + self.start_mark = start_mark + self.end_mark = end_mark + def __repr__(self): + attributes = [key for key in ['anchor', 'tag', 'implicit', 'value'] + if hasattr(self, key)] + arguments = ', '.join(['%s=%r' % (key, getattr(self, key)) + for key in attributes]) + return '%s(%s)' % (self.__class__.__name__, arguments) + +class NodeEvent(Event): + def __init__(self, anchor, start_mark=None, end_mark=None): + self.anchor = anchor + self.start_mark = start_mark + self.end_mark = end_mark + +class CollectionStartEvent(NodeEvent): + def __init__(self, anchor, tag, implicit, start_mark=None, end_mark=None, + flow_style=None): + self.anchor = anchor + self.tag = tag + self.implicit = implicit + self.start_mark = start_mark + self.end_mark = end_mark + self.flow_style = flow_style + +class CollectionEndEvent(Event): + pass + +# Implementations. + +class StreamStartEvent(Event): + def __init__(self, start_mark=None, end_mark=None, encoding=None): + self.start_mark = start_mark + self.end_mark = end_mark + self.encoding = encoding + +class StreamEndEvent(Event): + pass + +class DocumentStartEvent(Event): + def __init__(self, start_mark=None, end_mark=None, + explicit=None, version=None, tags=None): + self.start_mark = start_mark + self.end_mark = end_mark + self.explicit = explicit + self.version = version + self.tags = tags + +class DocumentEndEvent(Event): + def __init__(self, start_mark=None, end_mark=None, + explicit=None): + self.start_mark = start_mark + self.end_mark = end_mark + self.explicit = explicit + +class AliasEvent(NodeEvent): + pass + +class ScalarEvent(NodeEvent): + def __init__(self, anchor, tag, implicit, value, + start_mark=None, end_mark=None, style=None): + self.anchor = anchor + self.tag = tag + self.implicit = implicit + self.value = value + self.start_mark = start_mark + self.end_mark = end_mark + self.style = style + +class SequenceStartEvent(CollectionStartEvent): + pass + +class SequenceEndEvent(CollectionEndEvent): + pass + +class MappingStartEvent(CollectionStartEvent): + pass + +class MappingEndEvent(CollectionEndEvent): + pass + diff --git a/.venv/Lib/site-packages/yaml/loader.py b/.venv/Lib/site-packages/yaml/loader.py new file mode 100644 index 0000000000000000000000000000000000000000..e90c11224c38e559cdf0cb205f0692ebd4fb8681 --- /dev/null +++ b/.venv/Lib/site-packages/yaml/loader.py @@ -0,0 +1,63 @@ + +__all__ = ['BaseLoader', 'FullLoader', 'SafeLoader', 'Loader', 'UnsafeLoader'] + +from .reader import * +from .scanner import * +from .parser import * +from .composer import * +from .constructor import * +from .resolver import * + +class BaseLoader(Reader, Scanner, Parser, Composer, BaseConstructor, BaseResolver): + + def __init__(self, stream): + Reader.__init__(self, stream) + Scanner.__init__(self) + Parser.__init__(self) + Composer.__init__(self) + BaseConstructor.__init__(self) + BaseResolver.__init__(self) + +class FullLoader(Reader, Scanner, Parser, Composer, FullConstructor, Resolver): + + def __init__(self, stream): + Reader.__init__(self, stream) + Scanner.__init__(self) + Parser.__init__(self) + Composer.__init__(self) + FullConstructor.__init__(self) + Resolver.__init__(self) + +class SafeLoader(Reader, Scanner, Parser, Composer, SafeConstructor, Resolver): + + def __init__(self, stream): + Reader.__init__(self, stream) + Scanner.__init__(self) + Parser.__init__(self) + Composer.__init__(self) + SafeConstructor.__init__(self) + Resolver.__init__(self) + +class Loader(Reader, Scanner, Parser, Composer, Constructor, Resolver): + + def __init__(self, stream): + Reader.__init__(self, stream) + Scanner.__init__(self) + Parser.__init__(self) + Composer.__init__(self) + Constructor.__init__(self) + Resolver.__init__(self) + +# UnsafeLoader is the same as Loader (which is and was always unsafe on +# untrusted input). Use of either Loader or UnsafeLoader should be rare, since +# FullLoad should be able to load almost all YAML safely. Loader is left intact +# to ensure backwards compatibility. +class UnsafeLoader(Reader, Scanner, Parser, Composer, Constructor, Resolver): + + def __init__(self, stream): + Reader.__init__(self, stream) + Scanner.__init__(self) + Parser.__init__(self) + Composer.__init__(self) + Constructor.__init__(self) + Resolver.__init__(self) diff --git a/.venv/Lib/site-packages/yaml/nodes.py b/.venv/Lib/site-packages/yaml/nodes.py new file mode 100644 index 0000000000000000000000000000000000000000..c4f070c41e1fb1bc01af27d69329e92dded38908 --- /dev/null +++ b/.venv/Lib/site-packages/yaml/nodes.py @@ -0,0 +1,49 @@ + +class Node(object): + def __init__(self, tag, value, start_mark, end_mark): + self.tag = tag + self.value = value + self.start_mark = start_mark + self.end_mark = end_mark + def __repr__(self): + value = self.value + #if isinstance(value, list): + # if len(value) == 0: + # value = '' + # elif len(value) == 1: + # value = '<1 item>' + # else: + # value = '<%d items>' % len(value) + #else: + # if len(value) > 75: + # value = repr(value[:70]+u' ... ') + # else: + # value = repr(value) + value = repr(value) + return '%s(tag=%r, value=%s)' % (self.__class__.__name__, self.tag, value) + +class ScalarNode(Node): + id = 'scalar' + def __init__(self, tag, value, + start_mark=None, end_mark=None, style=None): + self.tag = tag + self.value = value + self.start_mark = start_mark + self.end_mark = end_mark + self.style = style + +class CollectionNode(Node): + def __init__(self, tag, value, + start_mark=None, end_mark=None, flow_style=None): + self.tag = tag + self.value = value + self.start_mark = start_mark + self.end_mark = end_mark + self.flow_style = flow_style + +class SequenceNode(CollectionNode): + id = 'sequence' + +class MappingNode(CollectionNode): + id = 'mapping' + diff --git a/.venv/Lib/site-packages/yaml/parser.py b/.venv/Lib/site-packages/yaml/parser.py new file mode 100644 index 0000000000000000000000000000000000000000..13a5995d292045d0f865a99abf692bd35dc87814 --- /dev/null +++ b/.venv/Lib/site-packages/yaml/parser.py @@ -0,0 +1,589 @@ + +# The following YAML grammar is LL(1) and is parsed by a recursive descent +# parser. +# +# stream ::= STREAM-START implicit_document? explicit_document* STREAM-END +# implicit_document ::= block_node DOCUMENT-END* +# explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* +# block_node_or_indentless_sequence ::= +# ALIAS +# | properties (block_content | indentless_block_sequence)? +# | block_content +# | indentless_block_sequence +# block_node ::= ALIAS +# | properties block_content? +# | block_content +# flow_node ::= ALIAS +# | properties flow_content? +# | flow_content +# properties ::= TAG ANCHOR? | ANCHOR TAG? +# block_content ::= block_collection | flow_collection | SCALAR +# flow_content ::= flow_collection | SCALAR +# block_collection ::= block_sequence | block_mapping +# flow_collection ::= flow_sequence | flow_mapping +# block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END +# indentless_sequence ::= (BLOCK-ENTRY block_node?)+ +# block_mapping ::= BLOCK-MAPPING_START +# ((KEY block_node_or_indentless_sequence?)? +# (VALUE block_node_or_indentless_sequence?)?)* +# BLOCK-END +# flow_sequence ::= FLOW-SEQUENCE-START +# (flow_sequence_entry FLOW-ENTRY)* +# flow_sequence_entry? +# FLOW-SEQUENCE-END +# flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? +# flow_mapping ::= FLOW-MAPPING-START +# (flow_mapping_entry FLOW-ENTRY)* +# flow_mapping_entry? +# FLOW-MAPPING-END +# flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? +# +# FIRST sets: +# +# stream: { STREAM-START } +# explicit_document: { DIRECTIVE DOCUMENT-START } +# implicit_document: FIRST(block_node) +# block_node: { ALIAS TAG ANCHOR SCALAR BLOCK-SEQUENCE-START BLOCK-MAPPING-START FLOW-SEQUENCE-START FLOW-MAPPING-START } +# flow_node: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START FLOW-MAPPING-START } +# block_content: { BLOCK-SEQUENCE-START BLOCK-MAPPING-START FLOW-SEQUENCE-START FLOW-MAPPING-START SCALAR } +# flow_content: { FLOW-SEQUENCE-START FLOW-MAPPING-START SCALAR } +# block_collection: { BLOCK-SEQUENCE-START BLOCK-MAPPING-START } +# flow_collection: { FLOW-SEQUENCE-START FLOW-MAPPING-START } +# block_sequence: { BLOCK-SEQUENCE-START } +# block_mapping: { BLOCK-MAPPING-START } +# block_node_or_indentless_sequence: { ALIAS ANCHOR TAG SCALAR BLOCK-SEQUENCE-START BLOCK-MAPPING-START FLOW-SEQUENCE-START FLOW-MAPPING-START BLOCK-ENTRY } +# indentless_sequence: { ENTRY } +# flow_collection: { FLOW-SEQUENCE-START FLOW-MAPPING-START } +# flow_sequence: { FLOW-SEQUENCE-START } +# flow_mapping: { FLOW-MAPPING-START } +# flow_sequence_entry: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START FLOW-MAPPING-START KEY } +# flow_mapping_entry: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START FLOW-MAPPING-START KEY } + +__all__ = ['Parser', 'ParserError'] + +from .error import MarkedYAMLError +from .tokens import * +from .events import * +from .scanner import * + +class ParserError(MarkedYAMLError): + pass + +class Parser: + # Since writing a recursive-descendant parser is a straightforward task, we + # do not give many comments here. + + DEFAULT_TAGS = { + '!': '!', + '!!': 'tag:yaml.org,2002:', + } + + def __init__(self): + self.current_event = None + self.yaml_version = None + self.tag_handles = {} + self.states = [] + self.marks = [] + self.state = self.parse_stream_start + + def dispose(self): + # Reset the state attributes (to clear self-references) + self.states = [] + self.state = None + + def check_event(self, *choices): + # Check the type of the next event. + if self.current_event is None: + if self.state: + self.current_event = self.state() + if self.current_event is not None: + if not choices: + return True + for choice in choices: + if isinstance(self.current_event, choice): + return True + return False + + def peek_event(self): + # Get the next event. + if self.current_event is None: + if self.state: + self.current_event = self.state() + return self.current_event + + def get_event(self): + # Get the next event and proceed further. + if self.current_event is None: + if self.state: + self.current_event = self.state() + value = self.current_event + self.current_event = None + return value + + # stream ::= STREAM-START implicit_document? explicit_document* STREAM-END + # implicit_document ::= block_node DOCUMENT-END* + # explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* + + def parse_stream_start(self): + + # Parse the stream start. + token = self.get_token() + event = StreamStartEvent(token.start_mark, token.end_mark, + encoding=token.encoding) + + # Prepare the next state. + self.state = self.parse_implicit_document_start + + return event + + def parse_implicit_document_start(self): + + # Parse an implicit document. + if not self.check_token(DirectiveToken, DocumentStartToken, + StreamEndToken): + self.tag_handles = self.DEFAULT_TAGS + token = self.peek_token() + start_mark = end_mark = token.start_mark + event = DocumentStartEvent(start_mark, end_mark, + explicit=False) + + # Prepare the next state. + self.states.append(self.parse_document_end) + self.state = self.parse_block_node + + return event + + else: + return self.parse_document_start() + + def parse_document_start(self): + + # Parse any extra document end indicators. + while self.check_token(DocumentEndToken): + self.get_token() + + # Parse an explicit document. + if not self.check_token(StreamEndToken): + token = self.peek_token() + start_mark = token.start_mark + version, tags = self.process_directives() + if not self.check_token(DocumentStartToken): + raise ParserError(None, None, + "expected '', but found %r" + % self.peek_token().id, + self.peek_token().start_mark) + token = self.get_token() + end_mark = token.end_mark + event = DocumentStartEvent(start_mark, end_mark, + explicit=True, version=version, tags=tags) + self.states.append(self.parse_document_end) + self.state = self.parse_document_content + else: + # Parse the end of the stream. + token = self.get_token() + event = StreamEndEvent(token.start_mark, token.end_mark) + assert not self.states + assert not self.marks + self.state = None + return event + + def parse_document_end(self): + + # Parse the document end. + token = self.peek_token() + start_mark = end_mark = token.start_mark + explicit = False + if self.check_token(DocumentEndToken): + token = self.get_token() + end_mark = token.end_mark + explicit = True + event = DocumentEndEvent(start_mark, end_mark, + explicit=explicit) + + # Prepare the next state. + self.state = self.parse_document_start + + return event + + def parse_document_content(self): + if self.check_token(DirectiveToken, + DocumentStartToken, DocumentEndToken, StreamEndToken): + event = self.process_empty_scalar(self.peek_token().start_mark) + self.state = self.states.pop() + return event + else: + return self.parse_block_node() + + def process_directives(self): + self.yaml_version = None + self.tag_handles = {} + while self.check_token(DirectiveToken): + token = self.get_token() + if token.name == 'YAML': + if self.yaml_version is not None: + raise ParserError(None, None, + "found duplicate YAML directive", token.start_mark) + major, minor = token.value + if major != 1: + raise ParserError(None, None, + "found incompatible YAML document (version 1.* is required)", + token.start_mark) + self.yaml_version = token.value + elif token.name == 'TAG': + handle, prefix = token.value + if handle in self.tag_handles: + raise ParserError(None, None, + "duplicate tag handle %r" % handle, + token.start_mark) + self.tag_handles[handle] = prefix + if self.tag_handles: + value = self.yaml_version, self.tag_handles.copy() + else: + value = self.yaml_version, None + for key in self.DEFAULT_TAGS: + if key not in self.tag_handles: + self.tag_handles[key] = self.DEFAULT_TAGS[key] + return value + + # block_node_or_indentless_sequence ::= ALIAS + # | properties (block_content | indentless_block_sequence)? + # | block_content + # | indentless_block_sequence + # block_node ::= ALIAS + # | properties block_content? + # | block_content + # flow_node ::= ALIAS + # | properties flow_content? + # | flow_content + # properties ::= TAG ANCHOR? | ANCHOR TAG? + # block_content ::= block_collection | flow_collection | SCALAR + # flow_content ::= flow_collection | SCALAR + # block_collection ::= block_sequence | block_mapping + # flow_collection ::= flow_sequence | flow_mapping + + def parse_block_node(self): + return self.parse_node(block=True) + + def parse_flow_node(self): + return self.parse_node() + + def parse_block_node_or_indentless_sequence(self): + return self.parse_node(block=True, indentless_sequence=True) + + def parse_node(self, block=False, indentless_sequence=False): + if self.check_token(AliasToken): + token = self.get_token() + event = AliasEvent(token.value, token.start_mark, token.end_mark) + self.state = self.states.pop() + else: + anchor = None + tag = None + start_mark = end_mark = tag_mark = None + if self.check_token(AnchorToken): + token = self.get_token() + start_mark = token.start_mark + end_mark = token.end_mark + anchor = token.value + if self.check_token(TagToken): + token = self.get_token() + tag_mark = token.start_mark + end_mark = token.end_mark + tag = token.value + elif self.check_token(TagToken): + token = self.get_token() + start_mark = tag_mark = token.start_mark + end_mark = token.end_mark + tag = token.value + if self.check_token(AnchorToken): + token = self.get_token() + end_mark = token.end_mark + anchor = token.value + if tag is not None: + handle, suffix = tag + if handle is not None: + if handle not in self.tag_handles: + raise ParserError("while parsing a node", start_mark, + "found undefined tag handle %r" % handle, + tag_mark) + tag = self.tag_handles[handle]+suffix + else: + tag = suffix + #if tag == '!': + # raise ParserError("while parsing a node", start_mark, + # "found non-specific tag '!'", tag_mark, + # "Please check 'http://pyyaml.org/wiki/YAMLNonSpecificTag' and share your opinion.") + if start_mark is None: + start_mark = end_mark = self.peek_token().start_mark + event = None + implicit = (tag is None or tag == '!') + if indentless_sequence and self.check_token(BlockEntryToken): + end_mark = self.peek_token().end_mark + event = SequenceStartEvent(anchor, tag, implicit, + start_mark, end_mark) + self.state = self.parse_indentless_sequence_entry + else: + if self.check_token(ScalarToken): + token = self.get_token() + end_mark = token.end_mark + if (token.plain and tag is None) or tag == '!': + implicit = (True, False) + elif tag is None: + implicit = (False, True) + else: + implicit = (False, False) + event = ScalarEvent(anchor, tag, implicit, token.value, + start_mark, end_mark, style=token.style) + self.state = self.states.pop() + elif self.check_token(FlowSequenceStartToken): + end_mark = self.peek_token().end_mark + event = SequenceStartEvent(anchor, tag, implicit, + start_mark, end_mark, flow_style=True) + self.state = self.parse_flow_sequence_first_entry + elif self.check_token(FlowMappingStartToken): + end_mark = self.peek_token().end_mark + event = MappingStartEvent(anchor, tag, implicit, + start_mark, end_mark, flow_style=True) + self.state = self.parse_flow_mapping_first_key + elif block and self.check_token(BlockSequenceStartToken): + end_mark = self.peek_token().start_mark + event = SequenceStartEvent(anchor, tag, implicit, + start_mark, end_mark, flow_style=False) + self.state = self.parse_block_sequence_first_entry + elif block and self.check_token(BlockMappingStartToken): + end_mark = self.peek_token().start_mark + event = MappingStartEvent(anchor, tag, implicit, + start_mark, end_mark, flow_style=False) + self.state = self.parse_block_mapping_first_key + elif anchor is not None or tag is not None: + # Empty scalars are allowed even if a tag or an anchor is + # specified. + event = ScalarEvent(anchor, tag, (implicit, False), '', + start_mark, end_mark) + self.state = self.states.pop() + else: + if block: + node = 'block' + else: + node = 'flow' + token = self.peek_token() + raise ParserError("while parsing a %s node" % node, start_mark, + "expected the node content, but found %r" % token.id, + token.start_mark) + return event + + # block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END + + def parse_block_sequence_first_entry(self): + token = self.get_token() + self.marks.append(token.start_mark) + return self.parse_block_sequence_entry() + + def parse_block_sequence_entry(self): + if self.check_token(BlockEntryToken): + token = self.get_token() + if not self.check_token(BlockEntryToken, BlockEndToken): + self.states.append(self.parse_block_sequence_entry) + return self.parse_block_node() + else: + self.state = self.parse_block_sequence_entry + return self.process_empty_scalar(token.end_mark) + if not self.check_token(BlockEndToken): + token = self.peek_token() + raise ParserError("while parsing a block collection", self.marks[-1], + "expected , but found %r" % token.id, token.start_mark) + token = self.get_token() + event = SequenceEndEvent(token.start_mark, token.end_mark) + self.state = self.states.pop() + self.marks.pop() + return event + + # indentless_sequence ::= (BLOCK-ENTRY block_node?)+ + + def parse_indentless_sequence_entry(self): + if self.check_token(BlockEntryToken): + token = self.get_token() + if not self.check_token(BlockEntryToken, + KeyToken, ValueToken, BlockEndToken): + self.states.append(self.parse_indentless_sequence_entry) + return self.parse_block_node() + else: + self.state = self.parse_indentless_sequence_entry + return self.process_empty_scalar(token.end_mark) + token = self.peek_token() + event = SequenceEndEvent(token.start_mark, token.start_mark) + self.state = self.states.pop() + return event + + # block_mapping ::= BLOCK-MAPPING_START + # ((KEY block_node_or_indentless_sequence?)? + # (VALUE block_node_or_indentless_sequence?)?)* + # BLOCK-END + + def parse_block_mapping_first_key(self): + token = self.get_token() + self.marks.append(token.start_mark) + return self.parse_block_mapping_key() + + def parse_block_mapping_key(self): + if self.check_token(KeyToken): + token = self.get_token() + if not self.check_token(KeyToken, ValueToken, BlockEndToken): + self.states.append(self.parse_block_mapping_value) + return self.parse_block_node_or_indentless_sequence() + else: + self.state = self.parse_block_mapping_value + return self.process_empty_scalar(token.end_mark) + if not self.check_token(BlockEndToken): + token = self.peek_token() + raise ParserError("while parsing a block mapping", self.marks[-1], + "expected , but found %r" % token.id, token.start_mark) + token = self.get_token() + event = MappingEndEvent(token.start_mark, token.end_mark) + self.state = self.states.pop() + self.marks.pop() + return event + + def parse_block_mapping_value(self): + if self.check_token(ValueToken): + token = self.get_token() + if not self.check_token(KeyToken, ValueToken, BlockEndToken): + self.states.append(self.parse_block_mapping_key) + return self.parse_block_node_or_indentless_sequence() + else: + self.state = self.parse_block_mapping_key + return self.process_empty_scalar(token.end_mark) + else: + self.state = self.parse_block_mapping_key + token = self.peek_token() + return self.process_empty_scalar(token.start_mark) + + # flow_sequence ::= FLOW-SEQUENCE-START + # (flow_sequence_entry FLOW-ENTRY)* + # flow_sequence_entry? + # FLOW-SEQUENCE-END + # flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? + # + # Note that while production rules for both flow_sequence_entry and + # flow_mapping_entry are equal, their interpretations are different. + # For `flow_sequence_entry`, the part `KEY flow_node? (VALUE flow_node?)?` + # generate an inline mapping (set syntax). + + def parse_flow_sequence_first_entry(self): + token = self.get_token() + self.marks.append(token.start_mark) + return self.parse_flow_sequence_entry(first=True) + + def parse_flow_sequence_entry(self, first=False): + if not self.check_token(FlowSequenceEndToken): + if not first: + if self.check_token(FlowEntryToken): + self.get_token() + else: + token = self.peek_token() + raise ParserError("while parsing a flow sequence", self.marks[-1], + "expected ',' or ']', but got %r" % token.id, token.start_mark) + + if self.check_token(KeyToken): + token = self.peek_token() + event = MappingStartEvent(None, None, True, + token.start_mark, token.end_mark, + flow_style=True) + self.state = self.parse_flow_sequence_entry_mapping_key + return event + elif not self.check_token(FlowSequenceEndToken): + self.states.append(self.parse_flow_sequence_entry) + return self.parse_flow_node() + token = self.get_token() + event = SequenceEndEvent(token.start_mark, token.end_mark) + self.state = self.states.pop() + self.marks.pop() + return event + + def parse_flow_sequence_entry_mapping_key(self): + token = self.get_token() + if not self.check_token(ValueToken, + FlowEntryToken, FlowSequenceEndToken): + self.states.append(self.parse_flow_sequence_entry_mapping_value) + return self.parse_flow_node() + else: + self.state = self.parse_flow_sequence_entry_mapping_value + return self.process_empty_scalar(token.end_mark) + + def parse_flow_sequence_entry_mapping_value(self): + if self.check_token(ValueToken): + token = self.get_token() + if not self.check_token(FlowEntryToken, FlowSequenceEndToken): + self.states.append(self.parse_flow_sequence_entry_mapping_end) + return self.parse_flow_node() + else: + self.state = self.parse_flow_sequence_entry_mapping_end + return self.process_empty_scalar(token.end_mark) + else: + self.state = self.parse_flow_sequence_entry_mapping_end + token = self.peek_token() + return self.process_empty_scalar(token.start_mark) + + def parse_flow_sequence_entry_mapping_end(self): + self.state = self.parse_flow_sequence_entry + token = self.peek_token() + return MappingEndEvent(token.start_mark, token.start_mark) + + # flow_mapping ::= FLOW-MAPPING-START + # (flow_mapping_entry FLOW-ENTRY)* + # flow_mapping_entry? + # FLOW-MAPPING-END + # flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? + + def parse_flow_mapping_first_key(self): + token = self.get_token() + self.marks.append(token.start_mark) + return self.parse_flow_mapping_key(first=True) + + def parse_flow_mapping_key(self, first=False): + if not self.check_token(FlowMappingEndToken): + if not first: + if self.check_token(FlowEntryToken): + self.get_token() + else: + token = self.peek_token() + raise ParserError("while parsing a flow mapping", self.marks[-1], + "expected ',' or '}', but got %r" % token.id, token.start_mark) + if self.check_token(KeyToken): + token = self.get_token() + if not self.check_token(ValueToken, + FlowEntryToken, FlowMappingEndToken): + self.states.append(self.parse_flow_mapping_value) + return self.parse_flow_node() + else: + self.state = self.parse_flow_mapping_value + return self.process_empty_scalar(token.end_mark) + elif not self.check_token(FlowMappingEndToken): + self.states.append(self.parse_flow_mapping_empty_value) + return self.parse_flow_node() + token = self.get_token() + event = MappingEndEvent(token.start_mark, token.end_mark) + self.state = self.states.pop() + self.marks.pop() + return event + + def parse_flow_mapping_value(self): + if self.check_token(ValueToken): + token = self.get_token() + if not self.check_token(FlowEntryToken, FlowMappingEndToken): + self.states.append(self.parse_flow_mapping_key) + return self.parse_flow_node() + else: + self.state = self.parse_flow_mapping_key + return self.process_empty_scalar(token.end_mark) + else: + self.state = self.parse_flow_mapping_key + token = self.peek_token() + return self.process_empty_scalar(token.start_mark) + + def parse_flow_mapping_empty_value(self): + self.state = self.parse_flow_mapping_key + return self.process_empty_scalar(self.peek_token().start_mark) + + def process_empty_scalar(self, mark): + return ScalarEvent(None, None, (True, False), '', mark, mark) + diff --git a/.venv/Lib/site-packages/yaml/reader.py b/.venv/Lib/site-packages/yaml/reader.py new file mode 100644 index 0000000000000000000000000000000000000000..774b0219b5932a0ee1c27e637371de5ba8d9cb16 --- /dev/null +++ b/.venv/Lib/site-packages/yaml/reader.py @@ -0,0 +1,185 @@ +# This module contains abstractions for the input stream. You don't have to +# looks further, there are no pretty code. +# +# We define two classes here. +# +# Mark(source, line, column) +# It's just a record and its only use is producing nice error messages. +# Parser does not use it for any other purposes. +# +# Reader(source, data) +# Reader determines the encoding of `data` and converts it to unicode. +# Reader provides the following methods and attributes: +# reader.peek(length=1) - return the next `length` characters +# reader.forward(length=1) - move the current position to `length` characters. +# reader.index - the number of the current character. +# reader.line, stream.column - the line and the column of the current character. + +__all__ = ['Reader', 'ReaderError'] + +from .error import YAMLError, Mark + +import codecs, re + +class ReaderError(YAMLError): + + def __init__(self, name, position, character, encoding, reason): + self.name = name + self.character = character + self.position = position + self.encoding = encoding + self.reason = reason + + def __str__(self): + if isinstance(self.character, bytes): + return "'%s' codec can't decode byte #x%02x: %s\n" \ + " in \"%s\", position %d" \ + % (self.encoding, ord(self.character), self.reason, + self.name, self.position) + else: + return "unacceptable character #x%04x: %s\n" \ + " in \"%s\", position %d" \ + % (self.character, self.reason, + self.name, self.position) + +class Reader(object): + # Reader: + # - determines the data encoding and converts it to a unicode string, + # - checks if characters are in allowed range, + # - adds '\0' to the end. + + # Reader accepts + # - a `bytes` object, + # - a `str` object, + # - a file-like object with its `read` method returning `str`, + # - a file-like object with its `read` method returning `unicode`. + + # Yeah, it's ugly and slow. + + def __init__(self, stream): + self.name = None + self.stream = None + self.stream_pointer = 0 + self.eof = True + self.buffer = '' + self.pointer = 0 + self.raw_buffer = None + self.raw_decode = None + self.encoding = None + self.index = 0 + self.line = 0 + self.column = 0 + if isinstance(stream, str): + self.name = "" + self.check_printable(stream) + self.buffer = stream+'\0' + elif isinstance(stream, bytes): + self.name = "" + self.raw_buffer = stream + self.determine_encoding() + else: + self.stream = stream + self.name = getattr(stream, 'name', "") + self.eof = False + self.raw_buffer = None + self.determine_encoding() + + def peek(self, index=0): + try: + return self.buffer[self.pointer+index] + except IndexError: + self.update(index+1) + return self.buffer[self.pointer+index] + + def prefix(self, length=1): + if self.pointer+length >= len(self.buffer): + self.update(length) + return self.buffer[self.pointer:self.pointer+length] + + def forward(self, length=1): + if self.pointer+length+1 >= len(self.buffer): + self.update(length+1) + while length: + ch = self.buffer[self.pointer] + self.pointer += 1 + self.index += 1 + if ch in '\n\x85\u2028\u2029' \ + or (ch == '\r' and self.buffer[self.pointer] != '\n'): + self.line += 1 + self.column = 0 + elif ch != '\uFEFF': + self.column += 1 + length -= 1 + + def get_mark(self): + if self.stream is None: + return Mark(self.name, self.index, self.line, self.column, + self.buffer, self.pointer) + else: + return Mark(self.name, self.index, self.line, self.column, + None, None) + + def determine_encoding(self): + while not self.eof and (self.raw_buffer is None or len(self.raw_buffer) < 2): + self.update_raw() + if isinstance(self.raw_buffer, bytes): + if self.raw_buffer.startswith(codecs.BOM_UTF16_LE): + self.raw_decode = codecs.utf_16_le_decode + self.encoding = 'utf-16-le' + elif self.raw_buffer.startswith(codecs.BOM_UTF16_BE): + self.raw_decode = codecs.utf_16_be_decode + self.encoding = 'utf-16-be' + else: + self.raw_decode = codecs.utf_8_decode + self.encoding = 'utf-8' + self.update(1) + + NON_PRINTABLE = re.compile('[^\x09\x0A\x0D\x20-\x7E\x85\xA0-\uD7FF\uE000-\uFFFD\U00010000-\U0010ffff]') + def check_printable(self, data): + match = self.NON_PRINTABLE.search(data) + if match: + character = match.group() + position = self.index+(len(self.buffer)-self.pointer)+match.start() + raise ReaderError(self.name, position, ord(character), + 'unicode', "special characters are not allowed") + + def update(self, length): + if self.raw_buffer is None: + return + self.buffer = self.buffer[self.pointer:] + self.pointer = 0 + while len(self.buffer) < length: + if not self.eof: + self.update_raw() + if self.raw_decode is not None: + try: + data, converted = self.raw_decode(self.raw_buffer, + 'strict', self.eof) + except UnicodeDecodeError as exc: + character = self.raw_buffer[exc.start] + if self.stream is not None: + position = self.stream_pointer-len(self.raw_buffer)+exc.start + else: + position = exc.start + raise ReaderError(self.name, position, character, + exc.encoding, exc.reason) + else: + data = self.raw_buffer + converted = len(data) + self.check_printable(data) + self.buffer += data + self.raw_buffer = self.raw_buffer[converted:] + if self.eof: + self.buffer += '\0' + self.raw_buffer = None + break + + def update_raw(self, size=4096): + data = self.stream.read(size) + if self.raw_buffer is None: + self.raw_buffer = data + else: + self.raw_buffer += data + self.stream_pointer += len(data) + if not data: + self.eof = True diff --git a/.venv/Lib/site-packages/yaml/representer.py b/.venv/Lib/site-packages/yaml/representer.py new file mode 100644 index 0000000000000000000000000000000000000000..808ca06dfbd60c9a23eb079151b74a82ef688749 --- /dev/null +++ b/.venv/Lib/site-packages/yaml/representer.py @@ -0,0 +1,389 @@ + +__all__ = ['BaseRepresenter', 'SafeRepresenter', 'Representer', + 'RepresenterError'] + +from .error import * +from .nodes import * + +import datetime, copyreg, types, base64, collections + +class RepresenterError(YAMLError): + pass + +class BaseRepresenter: + + yaml_representers = {} + yaml_multi_representers = {} + + def __init__(self, default_style=None, default_flow_style=False, sort_keys=True): + self.default_style = default_style + self.sort_keys = sort_keys + self.default_flow_style = default_flow_style + self.represented_objects = {} + self.object_keeper = [] + self.alias_key = None + + def represent(self, data): + node = self.represent_data(data) + self.serialize(node) + self.represented_objects = {} + self.object_keeper = [] + self.alias_key = None + + def represent_data(self, data): + if self.ignore_aliases(data): + self.alias_key = None + else: + self.alias_key = id(data) + if self.alias_key is not None: + if self.alias_key in self.represented_objects: + node = self.represented_objects[self.alias_key] + #if node is None: + # raise RepresenterError("recursive objects are not allowed: %r" % data) + return node + #self.represented_objects[alias_key] = None + self.object_keeper.append(data) + data_types = type(data).__mro__ + if data_types[0] in self.yaml_representers: + node = self.yaml_representers[data_types[0]](self, data) + else: + for data_type in data_types: + if data_type in self.yaml_multi_representers: + node = self.yaml_multi_representers[data_type](self, data) + break + else: + if None in self.yaml_multi_representers: + node = self.yaml_multi_representers[None](self, data) + elif None in self.yaml_representers: + node = self.yaml_representers[None](self, data) + else: + node = ScalarNode(None, str(data)) + #if alias_key is not None: + # self.represented_objects[alias_key] = node + return node + + @classmethod + def add_representer(cls, data_type, representer): + if not 'yaml_representers' in cls.__dict__: + cls.yaml_representers = cls.yaml_representers.copy() + cls.yaml_representers[data_type] = representer + + @classmethod + def add_multi_representer(cls, data_type, representer): + if not 'yaml_multi_representers' in cls.__dict__: + cls.yaml_multi_representers = cls.yaml_multi_representers.copy() + cls.yaml_multi_representers[data_type] = representer + + def represent_scalar(self, tag, value, style=None): + if style is None: + style = self.default_style + node = ScalarNode(tag, value, style=style) + if self.alias_key is not None: + self.represented_objects[self.alias_key] = node + return node + + def represent_sequence(self, tag, sequence, flow_style=None): + value = [] + node = SequenceNode(tag, value, flow_style=flow_style) + if self.alias_key is not None: + self.represented_objects[self.alias_key] = node + best_style = True + for item in sequence: + node_item = self.represent_data(item) + if not (isinstance(node_item, ScalarNode) and not node_item.style): + best_style = False + value.append(node_item) + if flow_style is None: + if self.default_flow_style is not None: + node.flow_style = self.default_flow_style + else: + node.flow_style = best_style + return node + + def represent_mapping(self, tag, mapping, flow_style=None): + value = [] + node = MappingNode(tag, value, flow_style=flow_style) + if self.alias_key is not None: + self.represented_objects[self.alias_key] = node + best_style = True + if hasattr(mapping, 'items'): + mapping = list(mapping.items()) + if self.sort_keys: + try: + mapping = sorted(mapping) + except TypeError: + pass + for item_key, item_value in mapping: + node_key = self.represent_data(item_key) + node_value = self.represent_data(item_value) + if not (isinstance(node_key, ScalarNode) and not node_key.style): + best_style = False + if not (isinstance(node_value, ScalarNode) and not node_value.style): + best_style = False + value.append((node_key, node_value)) + if flow_style is None: + if self.default_flow_style is not None: + node.flow_style = self.default_flow_style + else: + node.flow_style = best_style + return node + + def ignore_aliases(self, data): + return False + +class SafeRepresenter(BaseRepresenter): + + def ignore_aliases(self, data): + if data is None: + return True + if isinstance(data, tuple) and data == (): + return True + if isinstance(data, (str, bytes, bool, int, float)): + return True + + def represent_none(self, data): + return self.represent_scalar('tag:yaml.org,2002:null', 'null') + + def represent_str(self, data): + return self.represent_scalar('tag:yaml.org,2002:str', data) + + def represent_binary(self, data): + if hasattr(base64, 'encodebytes'): + data = base64.encodebytes(data).decode('ascii') + else: + data = base64.encodestring(data).decode('ascii') + return self.represent_scalar('tag:yaml.org,2002:binary', data, style='|') + + def represent_bool(self, data): + if data: + value = 'true' + else: + value = 'false' + return self.represent_scalar('tag:yaml.org,2002:bool', value) + + def represent_int(self, data): + return self.represent_scalar('tag:yaml.org,2002:int', str(data)) + + inf_value = 1e300 + while repr(inf_value) != repr(inf_value*inf_value): + inf_value *= inf_value + + def represent_float(self, data): + if data != data or (data == 0.0 and data == 1.0): + value = '.nan' + elif data == self.inf_value: + value = '.inf' + elif data == -self.inf_value: + value = '-.inf' + else: + value = repr(data).lower() + # Note that in some cases `repr(data)` represents a float number + # without the decimal parts. For instance: + # >>> repr(1e17) + # '1e17' + # Unfortunately, this is not a valid float representation according + # to the definition of the `!!float` tag. We fix this by adding + # '.0' before the 'e' symbol. + if '.' not in value and 'e' in value: + value = value.replace('e', '.0e', 1) + return self.represent_scalar('tag:yaml.org,2002:float', value) + + def represent_list(self, data): + #pairs = (len(data) > 0 and isinstance(data, list)) + #if pairs: + # for item in data: + # if not isinstance(item, tuple) or len(item) != 2: + # pairs = False + # break + #if not pairs: + return self.represent_sequence('tag:yaml.org,2002:seq', data) + #value = [] + #for item_key, item_value in data: + # value.append(self.represent_mapping(u'tag:yaml.org,2002:map', + # [(item_key, item_value)])) + #return SequenceNode(u'tag:yaml.org,2002:pairs', value) + + def represent_dict(self, data): + return self.represent_mapping('tag:yaml.org,2002:map', data) + + def represent_set(self, data): + value = {} + for key in data: + value[key] = None + return self.represent_mapping('tag:yaml.org,2002:set', value) + + def represent_date(self, data): + value = data.isoformat() + return self.represent_scalar('tag:yaml.org,2002:timestamp', value) + + def represent_datetime(self, data): + value = data.isoformat(' ') + return self.represent_scalar('tag:yaml.org,2002:timestamp', value) + + def represent_yaml_object(self, tag, data, cls, flow_style=None): + if hasattr(data, '__getstate__'): + state = data.__getstate__() + else: + state = data.__dict__.copy() + return self.represent_mapping(tag, state, flow_style=flow_style) + + def represent_undefined(self, data): + raise RepresenterError("cannot represent an object", data) + +SafeRepresenter.add_representer(type(None), + SafeRepresenter.represent_none) + +SafeRepresenter.add_representer(str, + SafeRepresenter.represent_str) + +SafeRepresenter.add_representer(bytes, + SafeRepresenter.represent_binary) + +SafeRepresenter.add_representer(bool, + SafeRepresenter.represent_bool) + +SafeRepresenter.add_representer(int, + SafeRepresenter.represent_int) + +SafeRepresenter.add_representer(float, + SafeRepresenter.represent_float) + +SafeRepresenter.add_representer(list, + SafeRepresenter.represent_list) + +SafeRepresenter.add_representer(tuple, + SafeRepresenter.represent_list) + +SafeRepresenter.add_representer(dict, + SafeRepresenter.represent_dict) + +SafeRepresenter.add_representer(set, + SafeRepresenter.represent_set) + +SafeRepresenter.add_representer(datetime.date, + SafeRepresenter.represent_date) + +SafeRepresenter.add_representer(datetime.datetime, + SafeRepresenter.represent_datetime) + +SafeRepresenter.add_representer(None, + SafeRepresenter.represent_undefined) + +class Representer(SafeRepresenter): + + def represent_complex(self, data): + if data.imag == 0.0: + data = '%r' % data.real + elif data.real == 0.0: + data = '%rj' % data.imag + elif data.imag > 0: + data = '%r+%rj' % (data.real, data.imag) + else: + data = '%r%rj' % (data.real, data.imag) + return self.represent_scalar('tag:yaml.org,2002:python/complex', data) + + def represent_tuple(self, data): + return self.represent_sequence('tag:yaml.org,2002:python/tuple', data) + + def represent_name(self, data): + name = '%s.%s' % (data.__module__, data.__name__) + return self.represent_scalar('tag:yaml.org,2002:python/name:'+name, '') + + def represent_module(self, data): + return self.represent_scalar( + 'tag:yaml.org,2002:python/module:'+data.__name__, '') + + def represent_object(self, data): + # We use __reduce__ API to save the data. data.__reduce__ returns + # a tuple of length 2-5: + # (function, args, state, listitems, dictitems) + + # For reconstructing, we calls function(*args), then set its state, + # listitems, and dictitems if they are not None. + + # A special case is when function.__name__ == '__newobj__'. In this + # case we create the object with args[0].__new__(*args). + + # Another special case is when __reduce__ returns a string - we don't + # support it. + + # We produce a !!python/object, !!python/object/new or + # !!python/object/apply node. + + cls = type(data) + if cls in copyreg.dispatch_table: + reduce = copyreg.dispatch_table[cls](data) + elif hasattr(data, '__reduce_ex__'): + reduce = data.__reduce_ex__(2) + elif hasattr(data, '__reduce__'): + reduce = data.__reduce__() + else: + raise RepresenterError("cannot represent an object", data) + reduce = (list(reduce)+[None]*5)[:5] + function, args, state, listitems, dictitems = reduce + args = list(args) + if state is None: + state = {} + if listitems is not None: + listitems = list(listitems) + if dictitems is not None: + dictitems = dict(dictitems) + if function.__name__ == '__newobj__': + function = args[0] + args = args[1:] + tag = 'tag:yaml.org,2002:python/object/new:' + newobj = True + else: + tag = 'tag:yaml.org,2002:python/object/apply:' + newobj = False + function_name = '%s.%s' % (function.__module__, function.__name__) + if not args and not listitems and not dictitems \ + and isinstance(state, dict) and newobj: + return self.represent_mapping( + 'tag:yaml.org,2002:python/object:'+function_name, state) + if not listitems and not dictitems \ + and isinstance(state, dict) and not state: + return self.represent_sequence(tag+function_name, args) + value = {} + if args: + value['args'] = args + if state or not isinstance(state, dict): + value['state'] = state + if listitems: + value['listitems'] = listitems + if dictitems: + value['dictitems'] = dictitems + return self.represent_mapping(tag+function_name, value) + + def represent_ordered_dict(self, data): + # Provide uniform representation across different Python versions. + data_type = type(data) + tag = 'tag:yaml.org,2002:python/object/apply:%s.%s' \ + % (data_type.__module__, data_type.__name__) + items = [[key, value] for key, value in data.items()] + return self.represent_sequence(tag, [items]) + +Representer.add_representer(complex, + Representer.represent_complex) + +Representer.add_representer(tuple, + Representer.represent_tuple) + +Representer.add_multi_representer(type, + Representer.represent_name) + +Representer.add_representer(collections.OrderedDict, + Representer.represent_ordered_dict) + +Representer.add_representer(types.FunctionType, + Representer.represent_name) + +Representer.add_representer(types.BuiltinFunctionType, + Representer.represent_name) + +Representer.add_representer(types.ModuleType, + Representer.represent_module) + +Representer.add_multi_representer(object, + Representer.represent_object) + diff --git a/.venv/Lib/site-packages/yaml/resolver.py b/.venv/Lib/site-packages/yaml/resolver.py new file mode 100644 index 0000000000000000000000000000000000000000..3522bdaaf6358110b608f4e6503b9d314c82d887 --- /dev/null +++ b/.venv/Lib/site-packages/yaml/resolver.py @@ -0,0 +1,227 @@ + +__all__ = ['BaseResolver', 'Resolver'] + +from .error import * +from .nodes import * + +import re + +class ResolverError(YAMLError): + pass + +class BaseResolver: + + DEFAULT_SCALAR_TAG = 'tag:yaml.org,2002:str' + DEFAULT_SEQUENCE_TAG = 'tag:yaml.org,2002:seq' + DEFAULT_MAPPING_TAG = 'tag:yaml.org,2002:map' + + yaml_implicit_resolvers = {} + yaml_path_resolvers = {} + + def __init__(self): + self.resolver_exact_paths = [] + self.resolver_prefix_paths = [] + + @classmethod + def add_implicit_resolver(cls, tag, regexp, first): + if not 'yaml_implicit_resolvers' in cls.__dict__: + implicit_resolvers = {} + for key in cls.yaml_implicit_resolvers: + implicit_resolvers[key] = cls.yaml_implicit_resolvers[key][:] + cls.yaml_implicit_resolvers = implicit_resolvers + if first is None: + first = [None] + for ch in first: + cls.yaml_implicit_resolvers.setdefault(ch, []).append((tag, regexp)) + + @classmethod + def add_path_resolver(cls, tag, path, kind=None): + # Note: `add_path_resolver` is experimental. The API could be changed. + # `new_path` is a pattern that is matched against the path from the + # root to the node that is being considered. `node_path` elements are + # tuples `(node_check, index_check)`. `node_check` is a node class: + # `ScalarNode`, `SequenceNode`, `MappingNode` or `None`. `None` + # matches any kind of a node. `index_check` could be `None`, a boolean + # value, a string value, or a number. `None` and `False` match against + # any _value_ of sequence and mapping nodes. `True` matches against + # any _key_ of a mapping node. A string `index_check` matches against + # a mapping value that corresponds to a scalar key which content is + # equal to the `index_check` value. An integer `index_check` matches + # against a sequence value with the index equal to `index_check`. + if not 'yaml_path_resolvers' in cls.__dict__: + cls.yaml_path_resolvers = cls.yaml_path_resolvers.copy() + new_path = [] + for element in path: + if isinstance(element, (list, tuple)): + if len(element) == 2: + node_check, index_check = element + elif len(element) == 1: + node_check = element[0] + index_check = True + else: + raise ResolverError("Invalid path element: %s" % element) + else: + node_check = None + index_check = element + if node_check is str: + node_check = ScalarNode + elif node_check is list: + node_check = SequenceNode + elif node_check is dict: + node_check = MappingNode + elif node_check not in [ScalarNode, SequenceNode, MappingNode] \ + and not isinstance(node_check, str) \ + and node_check is not None: + raise ResolverError("Invalid node checker: %s" % node_check) + if not isinstance(index_check, (str, int)) \ + and index_check is not None: + raise ResolverError("Invalid index checker: %s" % index_check) + new_path.append((node_check, index_check)) + if kind is str: + kind = ScalarNode + elif kind is list: + kind = SequenceNode + elif kind is dict: + kind = MappingNode + elif kind not in [ScalarNode, SequenceNode, MappingNode] \ + and kind is not None: + raise ResolverError("Invalid node kind: %s" % kind) + cls.yaml_path_resolvers[tuple(new_path), kind] = tag + + def descend_resolver(self, current_node, current_index): + if not self.yaml_path_resolvers: + return + exact_paths = {} + prefix_paths = [] + if current_node: + depth = len(self.resolver_prefix_paths) + for path, kind in self.resolver_prefix_paths[-1]: + if self.check_resolver_prefix(depth, path, kind, + current_node, current_index): + if len(path) > depth: + prefix_paths.append((path, kind)) + else: + exact_paths[kind] = self.yaml_path_resolvers[path, kind] + else: + for path, kind in self.yaml_path_resolvers: + if not path: + exact_paths[kind] = self.yaml_path_resolvers[path, kind] + else: + prefix_paths.append((path, kind)) + self.resolver_exact_paths.append(exact_paths) + self.resolver_prefix_paths.append(prefix_paths) + + def ascend_resolver(self): + if not self.yaml_path_resolvers: + return + self.resolver_exact_paths.pop() + self.resolver_prefix_paths.pop() + + def check_resolver_prefix(self, depth, path, kind, + current_node, current_index): + node_check, index_check = path[depth-1] + if isinstance(node_check, str): + if current_node.tag != node_check: + return + elif node_check is not None: + if not isinstance(current_node, node_check): + return + if index_check is True and current_index is not None: + return + if (index_check is False or index_check is None) \ + and current_index is None: + return + if isinstance(index_check, str): + if not (isinstance(current_index, ScalarNode) + and index_check == current_index.value): + return + elif isinstance(index_check, int) and not isinstance(index_check, bool): + if index_check != current_index: + return + return True + + def resolve(self, kind, value, implicit): + if kind is ScalarNode and implicit[0]: + if value == '': + resolvers = self.yaml_implicit_resolvers.get('', []) + else: + resolvers = self.yaml_implicit_resolvers.get(value[0], []) + wildcard_resolvers = self.yaml_implicit_resolvers.get(None, []) + for tag, regexp in resolvers + wildcard_resolvers: + if regexp.match(value): + return tag + implicit = implicit[1] + if self.yaml_path_resolvers: + exact_paths = self.resolver_exact_paths[-1] + if kind in exact_paths: + return exact_paths[kind] + if None in exact_paths: + return exact_paths[None] + if kind is ScalarNode: + return self.DEFAULT_SCALAR_TAG + elif kind is SequenceNode: + return self.DEFAULT_SEQUENCE_TAG + elif kind is MappingNode: + return self.DEFAULT_MAPPING_TAG + +class Resolver(BaseResolver): + pass + +Resolver.add_implicit_resolver( + 'tag:yaml.org,2002:bool', + re.compile(r'''^(?:yes|Yes|YES|no|No|NO + |true|True|TRUE|false|False|FALSE + |on|On|ON|off|Off|OFF)$''', re.X), + list('yYnNtTfFoO')) + +Resolver.add_implicit_resolver( + 'tag:yaml.org,2002:float', + re.compile(r'''^(?:[-+]?(?:[0-9][0-9_]*)\.[0-9_]*(?:[eE][-+][0-9]+)? + |\.[0-9][0-9_]*(?:[eE][-+][0-9]+)? + |[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\.[0-9_]* + |[-+]?\.(?:inf|Inf|INF) + |\.(?:nan|NaN|NAN))$''', re.X), + list('-+0123456789.')) + +Resolver.add_implicit_resolver( + 'tag:yaml.org,2002:int', + re.compile(r'''^(?:[-+]?0b[0-1_]+ + |[-+]?0[0-7_]+ + |[-+]?(?:0|[1-9][0-9_]*) + |[-+]?0x[0-9a-fA-F_]+ + |[-+]?[1-9][0-9_]*(?::[0-5]?[0-9])+)$''', re.X), + list('-+0123456789')) + +Resolver.add_implicit_resolver( + 'tag:yaml.org,2002:merge', + re.compile(r'^(?:<<)$'), + ['<']) + +Resolver.add_implicit_resolver( + 'tag:yaml.org,2002:null', + re.compile(r'''^(?: ~ + |null|Null|NULL + | )$''', re.X), + ['~', 'n', 'N', '']) + +Resolver.add_implicit_resolver( + 'tag:yaml.org,2002:timestamp', + re.compile(r'''^(?:[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] + |[0-9][0-9][0-9][0-9] -[0-9][0-9]? -[0-9][0-9]? + (?:[Tt]|[ \t]+)[0-9][0-9]? + :[0-9][0-9] :[0-9][0-9] (?:\.[0-9]*)? + (?:[ \t]*(?:Z|[-+][0-9][0-9]?(?::[0-9][0-9])?))?)$''', re.X), + list('0123456789')) + +Resolver.add_implicit_resolver( + 'tag:yaml.org,2002:value', + re.compile(r'^(?:=)$'), + ['=']) + +# The following resolver is only for documentation purposes. It cannot work +# because plain scalars cannot start with '!', '&', or '*'. +Resolver.add_implicit_resolver( + 'tag:yaml.org,2002:yaml', + re.compile(r'^(?:!|&|\*)$'), + list('!&*')) + diff --git a/.venv/Lib/site-packages/yaml/scanner.py b/.venv/Lib/site-packages/yaml/scanner.py new file mode 100644 index 0000000000000000000000000000000000000000..de925b07f1eaec33c9c305a8a69f9eb7ac5983c5 --- /dev/null +++ b/.venv/Lib/site-packages/yaml/scanner.py @@ -0,0 +1,1435 @@ + +# Scanner produces tokens of the following types: +# STREAM-START +# STREAM-END +# DIRECTIVE(name, value) +# DOCUMENT-START +# DOCUMENT-END +# BLOCK-SEQUENCE-START +# BLOCK-MAPPING-START +# BLOCK-END +# FLOW-SEQUENCE-START +# FLOW-MAPPING-START +# FLOW-SEQUENCE-END +# FLOW-MAPPING-END +# BLOCK-ENTRY +# FLOW-ENTRY +# KEY +# VALUE +# ALIAS(value) +# ANCHOR(value) +# TAG(value) +# SCALAR(value, plain, style) +# +# Read comments in the Scanner code for more details. +# + +__all__ = ['Scanner', 'ScannerError'] + +from .error import MarkedYAMLError +from .tokens import * + +class ScannerError(MarkedYAMLError): + pass + +class SimpleKey: + # See below simple keys treatment. + + def __init__(self, token_number, required, index, line, column, mark): + self.token_number = token_number + self.required = required + self.index = index + self.line = line + self.column = column + self.mark = mark + +class Scanner: + + def __init__(self): + """Initialize the scanner.""" + # It is assumed that Scanner and Reader will have a common descendant. + # Reader do the dirty work of checking for BOM and converting the + # input data to Unicode. It also adds NUL to the end. + # + # Reader supports the following methods + # self.peek(i=0) # peek the next i-th character + # self.prefix(l=1) # peek the next l characters + # self.forward(l=1) # read the next l characters and move the pointer. + + # Had we reached the end of the stream? + self.done = False + + # The number of unclosed '{' and '['. `flow_level == 0` means block + # context. + self.flow_level = 0 + + # List of processed tokens that are not yet emitted. + self.tokens = [] + + # Add the STREAM-START token. + self.fetch_stream_start() + + # Number of tokens that were emitted through the `get_token` method. + self.tokens_taken = 0 + + # The current indentation level. + self.indent = -1 + + # Past indentation levels. + self.indents = [] + + # Variables related to simple keys treatment. + + # A simple key is a key that is not denoted by the '?' indicator. + # Example of simple keys: + # --- + # block simple key: value + # ? not a simple key: + # : { flow simple key: value } + # We emit the KEY token before all keys, so when we find a potential + # simple key, we try to locate the corresponding ':' indicator. + # Simple keys should be limited to a single line and 1024 characters. + + # Can a simple key start at the current position? A simple key may + # start: + # - at the beginning of the line, not counting indentation spaces + # (in block context), + # - after '{', '[', ',' (in the flow context), + # - after '?', ':', '-' (in the block context). + # In the block context, this flag also signifies if a block collection + # may start at the current position. + self.allow_simple_key = True + + # Keep track of possible simple keys. This is a dictionary. The key + # is `flow_level`; there can be no more that one possible simple key + # for each level. The value is a SimpleKey record: + # (token_number, required, index, line, column, mark) + # A simple key may start with ALIAS, ANCHOR, TAG, SCALAR(flow), + # '[', or '{' tokens. + self.possible_simple_keys = {} + + # Public methods. + + def check_token(self, *choices): + # Check if the next token is one of the given types. + while self.need_more_tokens(): + self.fetch_more_tokens() + if self.tokens: + if not choices: + return True + for choice in choices: + if isinstance(self.tokens[0], choice): + return True + return False + + def peek_token(self): + # Return the next token, but do not delete if from the queue. + # Return None if no more tokens. + while self.need_more_tokens(): + self.fetch_more_tokens() + if self.tokens: + return self.tokens[0] + else: + return None + + def get_token(self): + # Return the next token. + while self.need_more_tokens(): + self.fetch_more_tokens() + if self.tokens: + self.tokens_taken += 1 + return self.tokens.pop(0) + + # Private methods. + + def need_more_tokens(self): + if self.done: + return False + if not self.tokens: + return True + # The current token may be a potential simple key, so we + # need to look further. + self.stale_possible_simple_keys() + if self.next_possible_simple_key() == self.tokens_taken: + return True + + def fetch_more_tokens(self): + + # Eat whitespaces and comments until we reach the next token. + self.scan_to_next_token() + + # Remove obsolete possible simple keys. + self.stale_possible_simple_keys() + + # Compare the current indentation and column. It may add some tokens + # and decrease the current indentation level. + self.unwind_indent(self.column) + + # Peek the next character. + ch = self.peek() + + # Is it the end of stream? + if ch == '\0': + return self.fetch_stream_end() + + # Is it a directive? + if ch == '%' and self.check_directive(): + return self.fetch_directive() + + # Is it the document start? + if ch == '-' and self.check_document_start(): + return self.fetch_document_start() + + # Is it the document end? + if ch == '.' and self.check_document_end(): + return self.fetch_document_end() + + # TODO: support for BOM within a stream. + #if ch == '\uFEFF': + # return self.fetch_bom() <-- issue BOMToken + + # Note: the order of the following checks is NOT significant. + + # Is it the flow sequence start indicator? + if ch == '[': + return self.fetch_flow_sequence_start() + + # Is it the flow mapping start indicator? + if ch == '{': + return self.fetch_flow_mapping_start() + + # Is it the flow sequence end indicator? + if ch == ']': + return self.fetch_flow_sequence_end() + + # Is it the flow mapping end indicator? + if ch == '}': + return self.fetch_flow_mapping_end() + + # Is it the flow entry indicator? + if ch == ',': + return self.fetch_flow_entry() + + # Is it the block entry indicator? + if ch == '-' and self.check_block_entry(): + return self.fetch_block_entry() + + # Is it the key indicator? + if ch == '?' and self.check_key(): + return self.fetch_key() + + # Is it the value indicator? + if ch == ':' and self.check_value(): + return self.fetch_value() + + # Is it an alias? + if ch == '*': + return self.fetch_alias() + + # Is it an anchor? + if ch == '&': + return self.fetch_anchor() + + # Is it a tag? + if ch == '!': + return self.fetch_tag() + + # Is it a literal scalar? + if ch == '|' and not self.flow_level: + return self.fetch_literal() + + # Is it a folded scalar? + if ch == '>' and not self.flow_level: + return self.fetch_folded() + + # Is it a single quoted scalar? + if ch == '\'': + return self.fetch_single() + + # Is it a double quoted scalar? + if ch == '\"': + return self.fetch_double() + + # It must be a plain scalar then. + if self.check_plain(): + return self.fetch_plain() + + # No? It's an error. Let's produce a nice error message. + raise ScannerError("while scanning for the next token", None, + "found character %r that cannot start any token" % ch, + self.get_mark()) + + # Simple keys treatment. + + def next_possible_simple_key(self): + # Return the number of the nearest possible simple key. Actually we + # don't need to loop through the whole dictionary. We may replace it + # with the following code: + # if not self.possible_simple_keys: + # return None + # return self.possible_simple_keys[ + # min(self.possible_simple_keys.keys())].token_number + min_token_number = None + for level in self.possible_simple_keys: + key = self.possible_simple_keys[level] + if min_token_number is None or key.token_number < min_token_number: + min_token_number = key.token_number + return min_token_number + + def stale_possible_simple_keys(self): + # Remove entries that are no longer possible simple keys. According to + # the YAML specification, simple keys + # - should be limited to a single line, + # - should be no longer than 1024 characters. + # Disabling this procedure will allow simple keys of any length and + # height (may cause problems if indentation is broken though). + for level in list(self.possible_simple_keys): + key = self.possible_simple_keys[level] + if key.line != self.line \ + or self.index-key.index > 1024: + if key.required: + raise ScannerError("while scanning a simple key", key.mark, + "could not find expected ':'", self.get_mark()) + del self.possible_simple_keys[level] + + def save_possible_simple_key(self): + # The next token may start a simple key. We check if it's possible + # and save its position. This function is called for + # ALIAS, ANCHOR, TAG, SCALAR(flow), '[', and '{'. + + # Check if a simple key is required at the current position. + required = not self.flow_level and self.indent == self.column + + # The next token might be a simple key. Let's save it's number and + # position. + if self.allow_simple_key: + self.remove_possible_simple_key() + token_number = self.tokens_taken+len(self.tokens) + key = SimpleKey(token_number, required, + self.index, self.line, self.column, self.get_mark()) + self.possible_simple_keys[self.flow_level] = key + + def remove_possible_simple_key(self): + # Remove the saved possible key position at the current flow level. + if self.flow_level in self.possible_simple_keys: + key = self.possible_simple_keys[self.flow_level] + + if key.required: + raise ScannerError("while scanning a simple key", key.mark, + "could not find expected ':'", self.get_mark()) + + del self.possible_simple_keys[self.flow_level] + + # Indentation functions. + + def unwind_indent(self, column): + + ## In flow context, tokens should respect indentation. + ## Actually the condition should be `self.indent >= column` according to + ## the spec. But this condition will prohibit intuitively correct + ## constructions such as + ## key : { + ## } + #if self.flow_level and self.indent > column: + # raise ScannerError(None, None, + # "invalid indentation or unclosed '[' or '{'", + # self.get_mark()) + + # In the flow context, indentation is ignored. We make the scanner less + # restrictive then specification requires. + if self.flow_level: + return + + # In block context, we may need to issue the BLOCK-END tokens. + while self.indent > column: + mark = self.get_mark() + self.indent = self.indents.pop() + self.tokens.append(BlockEndToken(mark, mark)) + + def add_indent(self, column): + # Check if we need to increase indentation. + if self.indent < column: + self.indents.append(self.indent) + self.indent = column + return True + return False + + # Fetchers. + + def fetch_stream_start(self): + # We always add STREAM-START as the first token and STREAM-END as the + # last token. + + # Read the token. + mark = self.get_mark() + + # Add STREAM-START. + self.tokens.append(StreamStartToken(mark, mark, + encoding=self.encoding)) + + + def fetch_stream_end(self): + + # Set the current indentation to -1. + self.unwind_indent(-1) + + # Reset simple keys. + self.remove_possible_simple_key() + self.allow_simple_key = False + self.possible_simple_keys = {} + + # Read the token. + mark = self.get_mark() + + # Add STREAM-END. + self.tokens.append(StreamEndToken(mark, mark)) + + # The steam is finished. + self.done = True + + def fetch_directive(self): + + # Set the current indentation to -1. + self.unwind_indent(-1) + + # Reset simple keys. + self.remove_possible_simple_key() + self.allow_simple_key = False + + # Scan and add DIRECTIVE. + self.tokens.append(self.scan_directive()) + + def fetch_document_start(self): + self.fetch_document_indicator(DocumentStartToken) + + def fetch_document_end(self): + self.fetch_document_indicator(DocumentEndToken) + + def fetch_document_indicator(self, TokenClass): + + # Set the current indentation to -1. + self.unwind_indent(-1) + + # Reset simple keys. Note that there could not be a block collection + # after '---'. + self.remove_possible_simple_key() + self.allow_simple_key = False + + # Add DOCUMENT-START or DOCUMENT-END. + start_mark = self.get_mark() + self.forward(3) + end_mark = self.get_mark() + self.tokens.append(TokenClass(start_mark, end_mark)) + + def fetch_flow_sequence_start(self): + self.fetch_flow_collection_start(FlowSequenceStartToken) + + def fetch_flow_mapping_start(self): + self.fetch_flow_collection_start(FlowMappingStartToken) + + def fetch_flow_collection_start(self, TokenClass): + + # '[' and '{' may start a simple key. + self.save_possible_simple_key() + + # Increase the flow level. + self.flow_level += 1 + + # Simple keys are allowed after '[' and '{'. + self.allow_simple_key = True + + # Add FLOW-SEQUENCE-START or FLOW-MAPPING-START. + start_mark = self.get_mark() + self.forward() + end_mark = self.get_mark() + self.tokens.append(TokenClass(start_mark, end_mark)) + + def fetch_flow_sequence_end(self): + self.fetch_flow_collection_end(FlowSequenceEndToken) + + def fetch_flow_mapping_end(self): + self.fetch_flow_collection_end(FlowMappingEndToken) + + def fetch_flow_collection_end(self, TokenClass): + + # Reset possible simple key on the current level. + self.remove_possible_simple_key() + + # Decrease the flow level. + self.flow_level -= 1 + + # No simple keys after ']' or '}'. + self.allow_simple_key = False + + # Add FLOW-SEQUENCE-END or FLOW-MAPPING-END. + start_mark = self.get_mark() + self.forward() + end_mark = self.get_mark() + self.tokens.append(TokenClass(start_mark, end_mark)) + + def fetch_flow_entry(self): + + # Simple keys are allowed after ','. + self.allow_simple_key = True + + # Reset possible simple key on the current level. + self.remove_possible_simple_key() + + # Add FLOW-ENTRY. + start_mark = self.get_mark() + self.forward() + end_mark = self.get_mark() + self.tokens.append(FlowEntryToken(start_mark, end_mark)) + + def fetch_block_entry(self): + + # Block context needs additional checks. + if not self.flow_level: + + # Are we allowed to start a new entry? + if not self.allow_simple_key: + raise ScannerError(None, None, + "sequence entries are not allowed here", + self.get_mark()) + + # We may need to add BLOCK-SEQUENCE-START. + if self.add_indent(self.column): + mark = self.get_mark() + self.tokens.append(BlockSequenceStartToken(mark, mark)) + + # It's an error for the block entry to occur in the flow context, + # but we let the parser detect this. + else: + pass + + # Simple keys are allowed after '-'. + self.allow_simple_key = True + + # Reset possible simple key on the current level. + self.remove_possible_simple_key() + + # Add BLOCK-ENTRY. + start_mark = self.get_mark() + self.forward() + end_mark = self.get_mark() + self.tokens.append(BlockEntryToken(start_mark, end_mark)) + + def fetch_key(self): + + # Block context needs additional checks. + if not self.flow_level: + + # Are we allowed to start a key (not necessary a simple)? + if not self.allow_simple_key: + raise ScannerError(None, None, + "mapping keys are not allowed here", + self.get_mark()) + + # We may need to add BLOCK-MAPPING-START. + if self.add_indent(self.column): + mark = self.get_mark() + self.tokens.append(BlockMappingStartToken(mark, mark)) + + # Simple keys are allowed after '?' in the block context. + self.allow_simple_key = not self.flow_level + + # Reset possible simple key on the current level. + self.remove_possible_simple_key() + + # Add KEY. + start_mark = self.get_mark() + self.forward() + end_mark = self.get_mark() + self.tokens.append(KeyToken(start_mark, end_mark)) + + def fetch_value(self): + + # Do we determine a simple key? + if self.flow_level in self.possible_simple_keys: + + # Add KEY. + key = self.possible_simple_keys[self.flow_level] + del self.possible_simple_keys[self.flow_level] + self.tokens.insert(key.token_number-self.tokens_taken, + KeyToken(key.mark, key.mark)) + + # If this key starts a new block mapping, we need to add + # BLOCK-MAPPING-START. + if not self.flow_level: + if self.add_indent(key.column): + self.tokens.insert(key.token_number-self.tokens_taken, + BlockMappingStartToken(key.mark, key.mark)) + + # There cannot be two simple keys one after another. + self.allow_simple_key = False + + # It must be a part of a complex key. + else: + + # Block context needs additional checks. + # (Do we really need them? They will be caught by the parser + # anyway.) + if not self.flow_level: + + # We are allowed to start a complex value if and only if + # we can start a simple key. + if not self.allow_simple_key: + raise ScannerError(None, None, + "mapping values are not allowed here", + self.get_mark()) + + # If this value starts a new block mapping, we need to add + # BLOCK-MAPPING-START. It will be detected as an error later by + # the parser. + if not self.flow_level: + if self.add_indent(self.column): + mark = self.get_mark() + self.tokens.append(BlockMappingStartToken(mark, mark)) + + # Simple keys are allowed after ':' in the block context. + self.allow_simple_key = not self.flow_level + + # Reset possible simple key on the current level. + self.remove_possible_simple_key() + + # Add VALUE. + start_mark = self.get_mark() + self.forward() + end_mark = self.get_mark() + self.tokens.append(ValueToken(start_mark, end_mark)) + + def fetch_alias(self): + + # ALIAS could be a simple key. + self.save_possible_simple_key() + + # No simple keys after ALIAS. + self.allow_simple_key = False + + # Scan and add ALIAS. + self.tokens.append(self.scan_anchor(AliasToken)) + + def fetch_anchor(self): + + # ANCHOR could start a simple key. + self.save_possible_simple_key() + + # No simple keys after ANCHOR. + self.allow_simple_key = False + + # Scan and add ANCHOR. + self.tokens.append(self.scan_anchor(AnchorToken)) + + def fetch_tag(self): + + # TAG could start a simple key. + self.save_possible_simple_key() + + # No simple keys after TAG. + self.allow_simple_key = False + + # Scan and add TAG. + self.tokens.append(self.scan_tag()) + + def fetch_literal(self): + self.fetch_block_scalar(style='|') + + def fetch_folded(self): + self.fetch_block_scalar(style='>') + + def fetch_block_scalar(self, style): + + # A simple key may follow a block scalar. + self.allow_simple_key = True + + # Reset possible simple key on the current level. + self.remove_possible_simple_key() + + # Scan and add SCALAR. + self.tokens.append(self.scan_block_scalar(style)) + + def fetch_single(self): + self.fetch_flow_scalar(style='\'') + + def fetch_double(self): + self.fetch_flow_scalar(style='"') + + def fetch_flow_scalar(self, style): + + # A flow scalar could be a simple key. + self.save_possible_simple_key() + + # No simple keys after flow scalars. + self.allow_simple_key = False + + # Scan and add SCALAR. + self.tokens.append(self.scan_flow_scalar(style)) + + def fetch_plain(self): + + # A plain scalar could be a simple key. + self.save_possible_simple_key() + + # No simple keys after plain scalars. But note that `scan_plain` will + # change this flag if the scan is finished at the beginning of the + # line. + self.allow_simple_key = False + + # Scan and add SCALAR. May change `allow_simple_key`. + self.tokens.append(self.scan_plain()) + + # Checkers. + + def check_directive(self): + + # DIRECTIVE: ^ '%' ... + # The '%' indicator is already checked. + if self.column == 0: + return True + + def check_document_start(self): + + # DOCUMENT-START: ^ '---' (' '|'\n') + if self.column == 0: + if self.prefix(3) == '---' \ + and self.peek(3) in '\0 \t\r\n\x85\u2028\u2029': + return True + + def check_document_end(self): + + # DOCUMENT-END: ^ '...' (' '|'\n') + if self.column == 0: + if self.prefix(3) == '...' \ + and self.peek(3) in '\0 \t\r\n\x85\u2028\u2029': + return True + + def check_block_entry(self): + + # BLOCK-ENTRY: '-' (' '|'\n') + return self.peek(1) in '\0 \t\r\n\x85\u2028\u2029' + + def check_key(self): + + # KEY(flow context): '?' + if self.flow_level: + return True + + # KEY(block context): '?' (' '|'\n') + else: + return self.peek(1) in '\0 \t\r\n\x85\u2028\u2029' + + def check_value(self): + + # VALUE(flow context): ':' + if self.flow_level: + return True + + # VALUE(block context): ':' (' '|'\n') + else: + return self.peek(1) in '\0 \t\r\n\x85\u2028\u2029' + + def check_plain(self): + + # A plain scalar may start with any non-space character except: + # '-', '?', ':', ',', '[', ']', '{', '}', + # '#', '&', '*', '!', '|', '>', '\'', '\"', + # '%', '@', '`'. + # + # It may also start with + # '-', '?', ':' + # if it is followed by a non-space character. + # + # Note that we limit the last rule to the block context (except the + # '-' character) because we want the flow context to be space + # independent. + ch = self.peek() + return ch not in '\0 \t\r\n\x85\u2028\u2029-?:,[]{}#&*!|>\'\"%@`' \ + or (self.peek(1) not in '\0 \t\r\n\x85\u2028\u2029' + and (ch == '-' or (not self.flow_level and ch in '?:'))) + + # Scanners. + + def scan_to_next_token(self): + # We ignore spaces, line breaks and comments. + # If we find a line break in the block context, we set the flag + # `allow_simple_key` on. + # The byte order mark is stripped if it's the first character in the + # stream. We do not yet support BOM inside the stream as the + # specification requires. Any such mark will be considered as a part + # of the document. + # + # TODO: We need to make tab handling rules more sane. A good rule is + # Tabs cannot precede tokens + # BLOCK-SEQUENCE-START, BLOCK-MAPPING-START, BLOCK-END, + # KEY(block), VALUE(block), BLOCK-ENTRY + # So the checking code is + # if : + # self.allow_simple_keys = False + # We also need to add the check for `allow_simple_keys == True` to + # `unwind_indent` before issuing BLOCK-END. + # Scanners for block, flow, and plain scalars need to be modified. + + if self.index == 0 and self.peek() == '\uFEFF': + self.forward() + found = False + while not found: + while self.peek() == ' ': + self.forward() + if self.peek() == '#': + while self.peek() not in '\0\r\n\x85\u2028\u2029': + self.forward() + if self.scan_line_break(): + if not self.flow_level: + self.allow_simple_key = True + else: + found = True + + def scan_directive(self): + # See the specification for details. + start_mark = self.get_mark() + self.forward() + name = self.scan_directive_name(start_mark) + value = None + if name == 'YAML': + value = self.scan_yaml_directive_value(start_mark) + end_mark = self.get_mark() + elif name == 'TAG': + value = self.scan_tag_directive_value(start_mark) + end_mark = self.get_mark() + else: + end_mark = self.get_mark() + while self.peek() not in '\0\r\n\x85\u2028\u2029': + self.forward() + self.scan_directive_ignored_line(start_mark) + return DirectiveToken(name, value, start_mark, end_mark) + + def scan_directive_name(self, start_mark): + # See the specification for details. + length = 0 + ch = self.peek(length) + while '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' \ + or ch in '-_': + length += 1 + ch = self.peek(length) + if not length: + raise ScannerError("while scanning a directive", start_mark, + "expected alphabetic or numeric character, but found %r" + % ch, self.get_mark()) + value = self.prefix(length) + self.forward(length) + ch = self.peek() + if ch not in '\0 \r\n\x85\u2028\u2029': + raise ScannerError("while scanning a directive", start_mark, + "expected alphabetic or numeric character, but found %r" + % ch, self.get_mark()) + return value + + def scan_yaml_directive_value(self, start_mark): + # See the specification for details. + while self.peek() == ' ': + self.forward() + major = self.scan_yaml_directive_number(start_mark) + if self.peek() != '.': + raise ScannerError("while scanning a directive", start_mark, + "expected a digit or '.', but found %r" % self.peek(), + self.get_mark()) + self.forward() + minor = self.scan_yaml_directive_number(start_mark) + if self.peek() not in '\0 \r\n\x85\u2028\u2029': + raise ScannerError("while scanning a directive", start_mark, + "expected a digit or ' ', but found %r" % self.peek(), + self.get_mark()) + return (major, minor) + + def scan_yaml_directive_number(self, start_mark): + # See the specification for details. + ch = self.peek() + if not ('0' <= ch <= '9'): + raise ScannerError("while scanning a directive", start_mark, + "expected a digit, but found %r" % ch, self.get_mark()) + length = 0 + while '0' <= self.peek(length) <= '9': + length += 1 + value = int(self.prefix(length)) + self.forward(length) + return value + + def scan_tag_directive_value(self, start_mark): + # See the specification for details. + while self.peek() == ' ': + self.forward() + handle = self.scan_tag_directive_handle(start_mark) + while self.peek() == ' ': + self.forward() + prefix = self.scan_tag_directive_prefix(start_mark) + return (handle, prefix) + + def scan_tag_directive_handle(self, start_mark): + # See the specification for details. + value = self.scan_tag_handle('directive', start_mark) + ch = self.peek() + if ch != ' ': + raise ScannerError("while scanning a directive", start_mark, + "expected ' ', but found %r" % ch, self.get_mark()) + return value + + def scan_tag_directive_prefix(self, start_mark): + # See the specification for details. + value = self.scan_tag_uri('directive', start_mark) + ch = self.peek() + if ch not in '\0 \r\n\x85\u2028\u2029': + raise ScannerError("while scanning a directive", start_mark, + "expected ' ', but found %r" % ch, self.get_mark()) + return value + + def scan_directive_ignored_line(self, start_mark): + # See the specification for details. + while self.peek() == ' ': + self.forward() + if self.peek() == '#': + while self.peek() not in '\0\r\n\x85\u2028\u2029': + self.forward() + ch = self.peek() + if ch not in '\0\r\n\x85\u2028\u2029': + raise ScannerError("while scanning a directive", start_mark, + "expected a comment or a line break, but found %r" + % ch, self.get_mark()) + self.scan_line_break() + + def scan_anchor(self, TokenClass): + # The specification does not restrict characters for anchors and + # aliases. This may lead to problems, for instance, the document: + # [ *alias, value ] + # can be interpreted in two ways, as + # [ "value" ] + # and + # [ *alias , "value" ] + # Therefore we restrict aliases to numbers and ASCII letters. + start_mark = self.get_mark() + indicator = self.peek() + if indicator == '*': + name = 'alias' + else: + name = 'anchor' + self.forward() + length = 0 + ch = self.peek(length) + while '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' \ + or ch in '-_': + length += 1 + ch = self.peek(length) + if not length: + raise ScannerError("while scanning an %s" % name, start_mark, + "expected alphabetic or numeric character, but found %r" + % ch, self.get_mark()) + value = self.prefix(length) + self.forward(length) + ch = self.peek() + if ch not in '\0 \t\r\n\x85\u2028\u2029?:,]}%@`': + raise ScannerError("while scanning an %s" % name, start_mark, + "expected alphabetic or numeric character, but found %r" + % ch, self.get_mark()) + end_mark = self.get_mark() + return TokenClass(value, start_mark, end_mark) + + def scan_tag(self): + # See the specification for details. + start_mark = self.get_mark() + ch = self.peek(1) + if ch == '<': + handle = None + self.forward(2) + suffix = self.scan_tag_uri('tag', start_mark) + if self.peek() != '>': + raise ScannerError("while parsing a tag", start_mark, + "expected '>', but found %r" % self.peek(), + self.get_mark()) + self.forward() + elif ch in '\0 \t\r\n\x85\u2028\u2029': + handle = None + suffix = '!' + self.forward() + else: + length = 1 + use_handle = False + while ch not in '\0 \r\n\x85\u2028\u2029': + if ch == '!': + use_handle = True + break + length += 1 + ch = self.peek(length) + handle = '!' + if use_handle: + handle = self.scan_tag_handle('tag', start_mark) + else: + handle = '!' + self.forward() + suffix = self.scan_tag_uri('tag', start_mark) + ch = self.peek() + if ch not in '\0 \r\n\x85\u2028\u2029': + raise ScannerError("while scanning a tag", start_mark, + "expected ' ', but found %r" % ch, self.get_mark()) + value = (handle, suffix) + end_mark = self.get_mark() + return TagToken(value, start_mark, end_mark) + + def scan_block_scalar(self, style): + # See the specification for details. + + if style == '>': + folded = True + else: + folded = False + + chunks = [] + start_mark = self.get_mark() + + # Scan the header. + self.forward() + chomping, increment = self.scan_block_scalar_indicators(start_mark) + self.scan_block_scalar_ignored_line(start_mark) + + # Determine the indentation level and go to the first non-empty line. + min_indent = self.indent+1 + if min_indent < 1: + min_indent = 1 + if increment is None: + breaks, max_indent, end_mark = self.scan_block_scalar_indentation() + indent = max(min_indent, max_indent) + else: + indent = min_indent+increment-1 + breaks, end_mark = self.scan_block_scalar_breaks(indent) + line_break = '' + + # Scan the inner part of the block scalar. + while self.column == indent and self.peek() != '\0': + chunks.extend(breaks) + leading_non_space = self.peek() not in ' \t' + length = 0 + while self.peek(length) not in '\0\r\n\x85\u2028\u2029': + length += 1 + chunks.append(self.prefix(length)) + self.forward(length) + line_break = self.scan_line_break() + breaks, end_mark = self.scan_block_scalar_breaks(indent) + if self.column == indent and self.peek() != '\0': + + # Unfortunately, folding rules are ambiguous. + # + # This is the folding according to the specification: + + if folded and line_break == '\n' \ + and leading_non_space and self.peek() not in ' \t': + if not breaks: + chunks.append(' ') + else: + chunks.append(line_break) + + # This is Clark Evans's interpretation (also in the spec + # examples): + # + #if folded and line_break == '\n': + # if not breaks: + # if self.peek() not in ' \t': + # chunks.append(' ') + # else: + # chunks.append(line_break) + #else: + # chunks.append(line_break) + else: + break + + # Chomp the tail. + if chomping is not False: + chunks.append(line_break) + if chomping is True: + chunks.extend(breaks) + + # We are done. + return ScalarToken(''.join(chunks), False, start_mark, end_mark, + style) + + def scan_block_scalar_indicators(self, start_mark): + # See the specification for details. + chomping = None + increment = None + ch = self.peek() + if ch in '+-': + if ch == '+': + chomping = True + else: + chomping = False + self.forward() + ch = self.peek() + if ch in '0123456789': + increment = int(ch) + if increment == 0: + raise ScannerError("while scanning a block scalar", start_mark, + "expected indentation indicator in the range 1-9, but found 0", + self.get_mark()) + self.forward() + elif ch in '0123456789': + increment = int(ch) + if increment == 0: + raise ScannerError("while scanning a block scalar", start_mark, + "expected indentation indicator in the range 1-9, but found 0", + self.get_mark()) + self.forward() + ch = self.peek() + if ch in '+-': + if ch == '+': + chomping = True + else: + chomping = False + self.forward() + ch = self.peek() + if ch not in '\0 \r\n\x85\u2028\u2029': + raise ScannerError("while scanning a block scalar", start_mark, + "expected chomping or indentation indicators, but found %r" + % ch, self.get_mark()) + return chomping, increment + + def scan_block_scalar_ignored_line(self, start_mark): + # See the specification for details. + while self.peek() == ' ': + self.forward() + if self.peek() == '#': + while self.peek() not in '\0\r\n\x85\u2028\u2029': + self.forward() + ch = self.peek() + if ch not in '\0\r\n\x85\u2028\u2029': + raise ScannerError("while scanning a block scalar", start_mark, + "expected a comment or a line break, but found %r" % ch, + self.get_mark()) + self.scan_line_break() + + def scan_block_scalar_indentation(self): + # See the specification for details. + chunks = [] + max_indent = 0 + end_mark = self.get_mark() + while self.peek() in ' \r\n\x85\u2028\u2029': + if self.peek() != ' ': + chunks.append(self.scan_line_break()) + end_mark = self.get_mark() + else: + self.forward() + if self.column > max_indent: + max_indent = self.column + return chunks, max_indent, end_mark + + def scan_block_scalar_breaks(self, indent): + # See the specification for details. + chunks = [] + end_mark = self.get_mark() + while self.column < indent and self.peek() == ' ': + self.forward() + while self.peek() in '\r\n\x85\u2028\u2029': + chunks.append(self.scan_line_break()) + end_mark = self.get_mark() + while self.column < indent and self.peek() == ' ': + self.forward() + return chunks, end_mark + + def scan_flow_scalar(self, style): + # See the specification for details. + # Note that we loose indentation rules for quoted scalars. Quoted + # scalars don't need to adhere indentation because " and ' clearly + # mark the beginning and the end of them. Therefore we are less + # restrictive then the specification requires. We only need to check + # that document separators are not included in scalars. + if style == '"': + double = True + else: + double = False + chunks = [] + start_mark = self.get_mark() + quote = self.peek() + self.forward() + chunks.extend(self.scan_flow_scalar_non_spaces(double, start_mark)) + while self.peek() != quote: + chunks.extend(self.scan_flow_scalar_spaces(double, start_mark)) + chunks.extend(self.scan_flow_scalar_non_spaces(double, start_mark)) + self.forward() + end_mark = self.get_mark() + return ScalarToken(''.join(chunks), False, start_mark, end_mark, + style) + + ESCAPE_REPLACEMENTS = { + '0': '\0', + 'a': '\x07', + 'b': '\x08', + 't': '\x09', + '\t': '\x09', + 'n': '\x0A', + 'v': '\x0B', + 'f': '\x0C', + 'r': '\x0D', + 'e': '\x1B', + ' ': '\x20', + '\"': '\"', + '\\': '\\', + '/': '/', + 'N': '\x85', + '_': '\xA0', + 'L': '\u2028', + 'P': '\u2029', + } + + ESCAPE_CODES = { + 'x': 2, + 'u': 4, + 'U': 8, + } + + def scan_flow_scalar_non_spaces(self, double, start_mark): + # See the specification for details. + chunks = [] + while True: + length = 0 + while self.peek(length) not in '\'\"\\\0 \t\r\n\x85\u2028\u2029': + length += 1 + if length: + chunks.append(self.prefix(length)) + self.forward(length) + ch = self.peek() + if not double and ch == '\'' and self.peek(1) == '\'': + chunks.append('\'') + self.forward(2) + elif (double and ch == '\'') or (not double and ch in '\"\\'): + chunks.append(ch) + self.forward() + elif double and ch == '\\': + self.forward() + ch = self.peek() + if ch in self.ESCAPE_REPLACEMENTS: + chunks.append(self.ESCAPE_REPLACEMENTS[ch]) + self.forward() + elif ch in self.ESCAPE_CODES: + length = self.ESCAPE_CODES[ch] + self.forward() + for k in range(length): + if self.peek(k) not in '0123456789ABCDEFabcdef': + raise ScannerError("while scanning a double-quoted scalar", start_mark, + "expected escape sequence of %d hexadecimal numbers, but found %r" % + (length, self.peek(k)), self.get_mark()) + code = int(self.prefix(length), 16) + chunks.append(chr(code)) + self.forward(length) + elif ch in '\r\n\x85\u2028\u2029': + self.scan_line_break() + chunks.extend(self.scan_flow_scalar_breaks(double, start_mark)) + else: + raise ScannerError("while scanning a double-quoted scalar", start_mark, + "found unknown escape character %r" % ch, self.get_mark()) + else: + return chunks + + def scan_flow_scalar_spaces(self, double, start_mark): + # See the specification for details. + chunks = [] + length = 0 + while self.peek(length) in ' \t': + length += 1 + whitespaces = self.prefix(length) + self.forward(length) + ch = self.peek() + if ch == '\0': + raise ScannerError("while scanning a quoted scalar", start_mark, + "found unexpected end of stream", self.get_mark()) + elif ch in '\r\n\x85\u2028\u2029': + line_break = self.scan_line_break() + breaks = self.scan_flow_scalar_breaks(double, start_mark) + if line_break != '\n': + chunks.append(line_break) + elif not breaks: + chunks.append(' ') + chunks.extend(breaks) + else: + chunks.append(whitespaces) + return chunks + + def scan_flow_scalar_breaks(self, double, start_mark): + # See the specification for details. + chunks = [] + while True: + # Instead of checking indentation, we check for document + # separators. + prefix = self.prefix(3) + if (prefix == '---' or prefix == '...') \ + and self.peek(3) in '\0 \t\r\n\x85\u2028\u2029': + raise ScannerError("while scanning a quoted scalar", start_mark, + "found unexpected document separator", self.get_mark()) + while self.peek() in ' \t': + self.forward() + if self.peek() in '\r\n\x85\u2028\u2029': + chunks.append(self.scan_line_break()) + else: + return chunks + + def scan_plain(self): + # See the specification for details. + # We add an additional restriction for the flow context: + # plain scalars in the flow context cannot contain ',' or '?'. + # We also keep track of the `allow_simple_key` flag here. + # Indentation rules are loosed for the flow context. + chunks = [] + start_mark = self.get_mark() + end_mark = start_mark + indent = self.indent+1 + # We allow zero indentation for scalars, but then we need to check for + # document separators at the beginning of the line. + #if indent == 0: + # indent = 1 + spaces = [] + while True: + length = 0 + if self.peek() == '#': + break + while True: + ch = self.peek(length) + if ch in '\0 \t\r\n\x85\u2028\u2029' \ + or (ch == ':' and + self.peek(length+1) in '\0 \t\r\n\x85\u2028\u2029' + + (u',[]{}' if self.flow_level else u''))\ + or (self.flow_level and ch in ',?[]{}'): + break + length += 1 + if length == 0: + break + self.allow_simple_key = False + chunks.extend(spaces) + chunks.append(self.prefix(length)) + self.forward(length) + end_mark = self.get_mark() + spaces = self.scan_plain_spaces(indent, start_mark) + if not spaces or self.peek() == '#' \ + or (not self.flow_level and self.column < indent): + break + return ScalarToken(''.join(chunks), True, start_mark, end_mark) + + def scan_plain_spaces(self, indent, start_mark): + # See the specification for details. + # The specification is really confusing about tabs in plain scalars. + # We just forbid them completely. Do not use tabs in YAML! + chunks = [] + length = 0 + while self.peek(length) in ' ': + length += 1 + whitespaces = self.prefix(length) + self.forward(length) + ch = self.peek() + if ch in '\r\n\x85\u2028\u2029': + line_break = self.scan_line_break() + self.allow_simple_key = True + prefix = self.prefix(3) + if (prefix == '---' or prefix == '...') \ + and self.peek(3) in '\0 \t\r\n\x85\u2028\u2029': + return + breaks = [] + while self.peek() in ' \r\n\x85\u2028\u2029': + if self.peek() == ' ': + self.forward() + else: + breaks.append(self.scan_line_break()) + prefix = self.prefix(3) + if (prefix == '---' or prefix == '...') \ + and self.peek(3) in '\0 \t\r\n\x85\u2028\u2029': + return + if line_break != '\n': + chunks.append(line_break) + elif not breaks: + chunks.append(' ') + chunks.extend(breaks) + elif whitespaces: + chunks.append(whitespaces) + return chunks + + def scan_tag_handle(self, name, start_mark): + # See the specification for details. + # For some strange reasons, the specification does not allow '_' in + # tag handles. I have allowed it anyway. + ch = self.peek() + if ch != '!': + raise ScannerError("while scanning a %s" % name, start_mark, + "expected '!', but found %r" % ch, self.get_mark()) + length = 1 + ch = self.peek(length) + if ch != ' ': + while '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' \ + or ch in '-_': + length += 1 + ch = self.peek(length) + if ch != '!': + self.forward(length) + raise ScannerError("while scanning a %s" % name, start_mark, + "expected '!', but found %r" % ch, self.get_mark()) + length += 1 + value = self.prefix(length) + self.forward(length) + return value + + def scan_tag_uri(self, name, start_mark): + # See the specification for details. + # Note: we do not check if URI is well-formed. + chunks = [] + length = 0 + ch = self.peek(length) + while '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z' \ + or ch in '-;/?:@&=+$,_.!~*\'()[]%': + if ch == '%': + chunks.append(self.prefix(length)) + self.forward(length) + length = 0 + chunks.append(self.scan_uri_escapes(name, start_mark)) + else: + length += 1 + ch = self.peek(length) + if length: + chunks.append(self.prefix(length)) + self.forward(length) + length = 0 + if not chunks: + raise ScannerError("while parsing a %s" % name, start_mark, + "expected URI, but found %r" % ch, self.get_mark()) + return ''.join(chunks) + + def scan_uri_escapes(self, name, start_mark): + # See the specification for details. + codes = [] + mark = self.get_mark() + while self.peek() == '%': + self.forward() + for k in range(2): + if self.peek(k) not in '0123456789ABCDEFabcdef': + raise ScannerError("while scanning a %s" % name, start_mark, + "expected URI escape sequence of 2 hexadecimal numbers, but found %r" + % self.peek(k), self.get_mark()) + codes.append(int(self.prefix(2), 16)) + self.forward(2) + try: + value = bytes(codes).decode('utf-8') + except UnicodeDecodeError as exc: + raise ScannerError("while scanning a %s" % name, start_mark, str(exc), mark) + return value + + def scan_line_break(self): + # Transforms: + # '\r\n' : '\n' + # '\r' : '\n' + # '\n' : '\n' + # '\x85' : '\n' + # '\u2028' : '\u2028' + # '\u2029 : '\u2029' + # default : '' + ch = self.peek() + if ch in '\r\n\x85': + if self.prefix(2) == '\r\n': + self.forward(2) + else: + self.forward() + return '\n' + elif ch in '\u2028\u2029': + self.forward() + return ch + return '' diff --git a/.venv/Lib/site-packages/yaml/serializer.py b/.venv/Lib/site-packages/yaml/serializer.py new file mode 100644 index 0000000000000000000000000000000000000000..fe911e67ae7a739abb491fbbc6834b9c37bbda4b --- /dev/null +++ b/.venv/Lib/site-packages/yaml/serializer.py @@ -0,0 +1,111 @@ + +__all__ = ['Serializer', 'SerializerError'] + +from .error import YAMLError +from .events import * +from .nodes import * + +class SerializerError(YAMLError): + pass + +class Serializer: + + ANCHOR_TEMPLATE = 'id%03d' + + def __init__(self, encoding=None, + explicit_start=None, explicit_end=None, version=None, tags=None): + self.use_encoding = encoding + self.use_explicit_start = explicit_start + self.use_explicit_end = explicit_end + self.use_version = version + self.use_tags = tags + self.serialized_nodes = {} + self.anchors = {} + self.last_anchor_id = 0 + self.closed = None + + def open(self): + if self.closed is None: + self.emit(StreamStartEvent(encoding=self.use_encoding)) + self.closed = False + elif self.closed: + raise SerializerError("serializer is closed") + else: + raise SerializerError("serializer is already opened") + + def close(self): + if self.closed is None: + raise SerializerError("serializer is not opened") + elif not self.closed: + self.emit(StreamEndEvent()) + self.closed = True + + #def __del__(self): + # self.close() + + def serialize(self, node): + if self.closed is None: + raise SerializerError("serializer is not opened") + elif self.closed: + raise SerializerError("serializer is closed") + self.emit(DocumentStartEvent(explicit=self.use_explicit_start, + version=self.use_version, tags=self.use_tags)) + self.anchor_node(node) + self.serialize_node(node, None, None) + self.emit(DocumentEndEvent(explicit=self.use_explicit_end)) + self.serialized_nodes = {} + self.anchors = {} + self.last_anchor_id = 0 + + def anchor_node(self, node): + if node in self.anchors: + if self.anchors[node] is None: + self.anchors[node] = self.generate_anchor(node) + else: + self.anchors[node] = None + if isinstance(node, SequenceNode): + for item in node.value: + self.anchor_node(item) + elif isinstance(node, MappingNode): + for key, value in node.value: + self.anchor_node(key) + self.anchor_node(value) + + def generate_anchor(self, node): + self.last_anchor_id += 1 + return self.ANCHOR_TEMPLATE % self.last_anchor_id + + def serialize_node(self, node, parent, index): + alias = self.anchors[node] + if node in self.serialized_nodes: + self.emit(AliasEvent(alias)) + else: + self.serialized_nodes[node] = True + self.descend_resolver(parent, index) + if isinstance(node, ScalarNode): + detected_tag = self.resolve(ScalarNode, node.value, (True, False)) + default_tag = self.resolve(ScalarNode, node.value, (False, True)) + implicit = (node.tag == detected_tag), (node.tag == default_tag) + self.emit(ScalarEvent(alias, node.tag, implicit, node.value, + style=node.style)) + elif isinstance(node, SequenceNode): + implicit = (node.tag + == self.resolve(SequenceNode, node.value, True)) + self.emit(SequenceStartEvent(alias, node.tag, implicit, + flow_style=node.flow_style)) + index = 0 + for item in node.value: + self.serialize_node(item, node, index) + index += 1 + self.emit(SequenceEndEvent()) + elif isinstance(node, MappingNode): + implicit = (node.tag + == self.resolve(MappingNode, node.value, True)) + self.emit(MappingStartEvent(alias, node.tag, implicit, + flow_style=node.flow_style)) + for key, value in node.value: + self.serialize_node(key, node, None) + self.serialize_node(value, node, key) + self.emit(MappingEndEvent()) + self.ascend_resolver() + diff --git a/.venv/Lib/site-packages/yaml/tokens.py b/.venv/Lib/site-packages/yaml/tokens.py new file mode 100644 index 0000000000000000000000000000000000000000..4d0b48a394ac8c019b401516a12f688df361cf90 --- /dev/null +++ b/.venv/Lib/site-packages/yaml/tokens.py @@ -0,0 +1,104 @@ + +class Token(object): + def __init__(self, start_mark, end_mark): + self.start_mark = start_mark + self.end_mark = end_mark + def __repr__(self): + attributes = [key for key in self.__dict__ + if not key.endswith('_mark')] + attributes.sort() + arguments = ', '.join(['%s=%r' % (key, getattr(self, key)) + for key in attributes]) + return '%s(%s)' % (self.__class__.__name__, arguments) + +#class BOMToken(Token): +# id = '' + +class DirectiveToken(Token): + id = '' + def __init__(self, name, value, start_mark, end_mark): + self.name = name + self.value = value + self.start_mark = start_mark + self.end_mark = end_mark + +class DocumentStartToken(Token): + id = '' + +class DocumentEndToken(Token): + id = '' + +class StreamStartToken(Token): + id = '' + def __init__(self, start_mark=None, end_mark=None, + encoding=None): + self.start_mark = start_mark + self.end_mark = end_mark + self.encoding = encoding + +class StreamEndToken(Token): + id = '' + +class BlockSequenceStartToken(Token): + id = '' + +class BlockMappingStartToken(Token): + id = '' + +class BlockEndToken(Token): + id = '' + +class FlowSequenceStartToken(Token): + id = '[' + +class FlowMappingStartToken(Token): + id = '{' + +class FlowSequenceEndToken(Token): + id = ']' + +class FlowMappingEndToken(Token): + id = '}' + +class KeyToken(Token): + id = '?' + +class ValueToken(Token): + id = ':' + +class BlockEntryToken(Token): + id = '-' + +class FlowEntryToken(Token): + id = ',' + +class AliasToken(Token): + id = '' + def __init__(self, value, start_mark, end_mark): + self.value = value + self.start_mark = start_mark + self.end_mark = end_mark + +class AnchorToken(Token): + id = '' + def __init__(self, value, start_mark, end_mark): + self.value = value + self.start_mark = start_mark + self.end_mark = end_mark + +class TagToken(Token): + id = '' + def __init__(self, value, start_mark, end_mark): + self.value = value + self.start_mark = start_mark + self.end_mark = end_mark + +class ScalarToken(Token): + id = '' + def __init__(self, value, plain, start_mark, end_mark, style=None): + self.value = value + self.plain = plain + self.start_mark = start_mark + self.end_mark = end_mark + self.style = style + diff --git a/.venv/Scripts/Activate.ps1 b/.venv/Scripts/Activate.ps1 new file mode 100644 index 0000000000000000000000000000000000000000..733a858ceb84a8cd82fef5ef1f96a018ab1e2fe4 --- /dev/null +++ b/.venv/Scripts/Activate.ps1 @@ -0,0 +1,502 @@ +<# +.Synopsis +Activate a Python virtual environment for the current PowerShell session. + +.Description +Pushes the python executable for a virtual environment to the front of the +$Env:PATH environment variable and sets the prompt to signify that you are +in a Python virtual environment. Makes use of the command line switches as +well as the `pyvenv.cfg` file values present in the virtual environment. + +.Parameter VenvDir +Path to the directory that contains the virtual environment to activate. The +default value for this is the parent of the directory that the Activate.ps1 +script is located within. + +.Parameter Prompt +The prompt prefix to display when this virtual environment is activated. By +default, this prompt is the name of the virtual environment folder (VenvDir) +surrounded by parentheses and followed by a single space (ie. '(.venv) '). + +.Example +Activate.ps1 +Activates the Python virtual environment that contains the Activate.ps1 script. + +.Example +Activate.ps1 -Verbose +Activates the Python virtual environment that contains the Activate.ps1 script, +and shows extra information about the activation as it executes. + +.Example +Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv +Activates the Python virtual environment located in the specified location. + +.Example +Activate.ps1 -Prompt "MyPython" +Activates the Python virtual environment that contains the Activate.ps1 script, +and prefixes the current prompt with the specified string (surrounded in +parentheses) while the virtual environment is active. + +.Notes +On Windows, it may be required to enable this Activate.ps1 script by setting the +execution policy for the user. You can do this by issuing the following PowerShell +command: + +PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser + +For more information on Execution Policies: +https://go.microsoft.com/fwlink/?LinkID=135170 + +#> +Param( + [Parameter(Mandatory = $false)] + [String] + $VenvDir, + [Parameter(Mandatory = $false)] + [String] + $Prompt +) + +<# Function declarations --------------------------------------------------- #> + +<# +.Synopsis +Remove all shell session elements added by the Activate script, including the +addition of the virtual environment's Python executable from the beginning of +the PATH variable. + +.Parameter NonDestructive +If present, do not remove this function from the global namespace for the +session. + +#> +function global:deactivate ([switch]$NonDestructive) { + # Revert to original values + + # The prior prompt: + if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) { + Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt + Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT + } + + # The prior PYTHONHOME: + if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) { + Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME + Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME + } + + # The prior PATH: + if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) { + Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH + Remove-Item -Path Env:_OLD_VIRTUAL_PATH + } + + # Just remove the VIRTUAL_ENV altogether: + if (Test-Path -Path Env:VIRTUAL_ENV) { + Remove-Item -Path env:VIRTUAL_ENV + } + + # Just remove VIRTUAL_ENV_PROMPT altogether. + if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) { + Remove-Item -Path env:VIRTUAL_ENV_PROMPT + } + + # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether: + if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) { + Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force + } + + # Leave deactivate function in the global namespace if requested: + if (-not $NonDestructive) { + Remove-Item -Path function:deactivate + } +} + +<# +.Description +Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the +given folder, and returns them in a map. + +For each line in the pyvenv.cfg file, if that line can be parsed into exactly +two strings separated by `=` (with any amount of whitespace surrounding the =) +then it is considered a `key = value` line. The left hand string is the key, +the right hand is the value. + +If the value starts with a `'` or a `"` then the first and last character is +stripped from the value before being captured. + +.Parameter ConfigDir +Path to the directory that contains the `pyvenv.cfg` file. +#> +function Get-PyVenvConfig( + [String] + $ConfigDir +) { + Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg" + + # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue). + $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue + + # An empty map will be returned if no config file is found. + $pyvenvConfig = @{ } + + if ($pyvenvConfigPath) { + + Write-Verbose "File exists, parse `key = value` lines" + $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath + + $pyvenvConfigContent | ForEach-Object { + $keyval = $PSItem -split "\s*=\s*", 2 + if ($keyval[0] -and $keyval[1]) { + $val = $keyval[1] + + # Remove extraneous quotations around a string value. + if ("'""".Contains($val.Substring(0, 1))) { + $val = $val.Substring(1, $val.Length - 2) + } + + $pyvenvConfig[$keyval[0]] = $val + Write-Verbose "Adding Key: '$($keyval[0])'='$val'" + } + } + } + return $pyvenvConfig +} + + +<# Begin Activate script --------------------------------------------------- #> + +# Determine the containing directory of this script +$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition +$VenvExecDir = Get-Item -Path $VenvExecPath + +Write-Verbose "Activation script is located in path: '$VenvExecPath'" +Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)" +Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)" + +# Set values required in priority: CmdLine, ConfigFile, Default +# First, get the location of the virtual environment, it might not be +# VenvExecDir if specified on the command line. +if ($VenvDir) { + Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values" +} +else { + Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." + $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") + Write-Verbose "VenvDir=$VenvDir" +} + +# Next, read the `pyvenv.cfg` file to determine any required value such +# as `prompt`. +$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir + +# Next, set the prompt from the command line, or the config file, or +# just use the name of the virtual environment folder. +if ($Prompt) { + Write-Verbose "Prompt specified as argument, using '$Prompt'" +} +else { + Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value" + if ($pyvenvCfg -and $pyvenvCfg['prompt']) { + Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'" + $Prompt = $pyvenvCfg['prompt']; + } + else { + Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)" + Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'" + $Prompt = Split-Path -Path $venvDir -Leaf + } +} + +Write-Verbose "Prompt = '$Prompt'" +Write-Verbose "VenvDir='$VenvDir'" + +# Deactivate any currently active virtual environment, but leave the +# deactivate function in place. +deactivate -nondestructive + +# Now set the environment variable VIRTUAL_ENV, used by many tools to determine +# that there is an activated venv. +$env:VIRTUAL_ENV = $VenvDir + +if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) { + + Write-Verbose "Setting prompt to '$Prompt'" + + # Set the prompt to include the env name + # Make sure _OLD_VIRTUAL_PROMPT is global + function global:_OLD_VIRTUAL_PROMPT { "" } + Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT + New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt + + function global:prompt { + Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " + _OLD_VIRTUAL_PROMPT + } + $env:VIRTUAL_ENV_PROMPT = $Prompt +} + +# Clear PYTHONHOME +if (Test-Path -Path Env:PYTHONHOME) { + Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME + Remove-Item -Path Env:PYTHONHOME +} + +# Add the venv to the PATH +Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH +$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH" + +# SIG # Begin signature block +# MIIvIwYJKoZIhvcNAQcCoIIvFDCCLxACAQExDzANBglghkgBZQMEAgEFADB5Bgor +# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG +# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBnL745ElCYk8vk +# dBtMuQhLeWJ3ZGfzKW4DHCYzAn+QB6CCE8MwggWQMIIDeKADAgECAhAFmxtXno4h +# MuI5B72nd3VcMA0GCSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK +# EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNV +# BAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0xMzA4MDExMjAwMDBaFw0z +# ODAxMTUxMjAwMDBaMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ +# bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0 +# IFRydXN0ZWQgUm9vdCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +# AL/mkHNo3rvkXUo8MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3EMB/z +# G6Q4FutWxpdtHauyefLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKyunWZ +# anMylNEQRBAu34LzB4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsFxl7s +# Wxq868nPzaw0QF+xembud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU15zHL +# 2pNe3I6PgNq2kZhAkHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJBMtfb +# BHMqbpEBfCFM1LyuGwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObURWBf3 +# JFxGj2T3wWmIdph2PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6nj3c +# AORFJYm2mkQZK37AlLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxBYKqx +# YxhElRp2Yn72gLD76GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5SUUd0 +# viastkF13nqsX40/ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+xq4aL +# T8LWRV+dIPyhHsXAj6KxfgommfXkaS+YHS312amyHeUbAgMBAAGjQjBAMA8GA1Ud +# EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTs1+OC0nFdZEzf +# Lmc/57qYrhwPTzANBgkqhkiG9w0BAQwFAAOCAgEAu2HZfalsvhfEkRvDoaIAjeNk +# aA9Wz3eucPn9mkqZucl4XAwMX+TmFClWCzZJXURj4K2clhhmGyMNPXnpbWvWVPjS +# PMFDQK4dUPVS/JA7u5iZaWvHwaeoaKQn3J35J64whbn2Z006Po9ZOSJTROvIXQPK +# 7VB6fWIhCoDIc2bRoAVgX+iltKevqPdtNZx8WorWojiZ83iL9E3SIAveBO6Mm0eB +# cg3AFDLvMFkuruBx8lbkapdvklBtlo1oepqyNhR6BvIkuQkRUNcIsbiJeoQjYUIp +# 5aPNoiBB19GcZNnqJqGLFNdMGbJQQXE9P01wI4YMStyB0swylIQNCAmXHE/A7msg +# dDDS4Dk0EIUhFQEI6FUy3nFJ2SgXUE3mvk3RdazQyvtBuEOlqtPDBURPLDab4vri +# RbgjU2wGb2dVf0a1TD9uKFp5JtKkqGKX0h7i7UqLvBv9R0oN32dmfrJbQdA75PQ7 +# 9ARj6e/CVABRoIoqyc54zNXqhwQYs86vSYiv85KZtrPmYQ/ShQDnUBrkG5WdGaG5 +# nLGbsQAe79APT0JsyQq87kP6OnGlyE0mpTX9iV28hWIdMtKgK1TtmlfB2/oQzxm3 +# i0objwG2J5VT6LaJbVu8aNQj6ItRolb58KaAoNYes7wPD1N1KarqE3fk3oyBIa0H +# EEcRrYc9B9F1vM/zZn4wggawMIIEmKADAgECAhAIrUCyYNKcTJ9ezam9k67ZMA0G +# CSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ +# bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0 +# IFRydXN0ZWQgUm9vdCBHNDAeFw0yMTA0MjkwMDAwMDBaFw0zNjA0MjgyMzU5NTla +# MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE +# AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz +# ODQgMjAyMSBDQTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDVtC9C +# 0CiteLdd1TlZG7GIQvUzjOs9gZdwxbvEhSYwn6SOaNhc9es0JAfhS0/TeEP0F9ce +# 2vnS1WcaUk8OoVf8iJnBkcyBAz5NcCRks43iCH00fUyAVxJrQ5qZ8sU7H/Lvy0da +# E6ZMswEgJfMQ04uy+wjwiuCdCcBlp/qYgEk1hz1RGeiQIXhFLqGfLOEYwhrMxe6T +# SXBCMo/7xuoc82VokaJNTIIRSFJo3hC9FFdd6BgTZcV/sk+FLEikVoQ11vkunKoA +# FdE3/hoGlMJ8yOobMubKwvSnowMOdKWvObarYBLj6Na59zHh3K3kGKDYwSNHR7Oh +# D26jq22YBoMbt2pnLdK9RBqSEIGPsDsJ18ebMlrC/2pgVItJwZPt4bRc4G/rJvmM +# 1bL5OBDm6s6R9b7T+2+TYTRcvJNFKIM2KmYoX7BzzosmJQayg9Rc9hUZTO1i4F4z +# 8ujo7AqnsAMrkbI2eb73rQgedaZlzLvjSFDzd5Ea/ttQokbIYViY9XwCFjyDKK05 +# huzUtw1T0PhH5nUwjewwk3YUpltLXXRhTT8SkXbev1jLchApQfDVxW0mdmgRQRNY +# mtwmKwH0iU1Z23jPgUo+QEdfyYFQc4UQIyFZYIpkVMHMIRroOBl8ZhzNeDhFMJlP +# /2NPTLuqDQhTQXxYPUez+rbsjDIJAsxsPAxWEQIDAQABo4IBWTCCAVUwEgYDVR0T +# AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUaDfg67Y7+F8Rhvv+YXsIiGX0TkIwHwYD +# VR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMG +# A1UdJQQMMAoGCCsGAQUFBwMDMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYY +# aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2Fj +# ZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNV +# HR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRU +# cnVzdGVkUm9vdEc0LmNybDAcBgNVHSAEFTATMAcGBWeBDAEDMAgGBmeBDAEEATAN +# BgkqhkiG9w0BAQwFAAOCAgEAOiNEPY0Idu6PvDqZ01bgAhql+Eg08yy25nRm95Ry +# sQDKr2wwJxMSnpBEn0v9nqN8JtU3vDpdSG2V1T9J9Ce7FoFFUP2cvbaF4HZ+N3HL +# IvdaqpDP9ZNq4+sg0dVQeYiaiorBtr2hSBh+3NiAGhEZGM1hmYFW9snjdufE5Btf +# Q/g+lP92OT2e1JnPSt0o618moZVYSNUa/tcnP/2Q0XaG3RywYFzzDaju4ImhvTnh +# OE7abrs2nfvlIVNaw8rpavGiPttDuDPITzgUkpn13c5UbdldAhQfQDN8A+KVssIh +# dXNSy0bYxDQcoqVLjc1vdjcshT8azibpGL6QB7BDf5WIIIJw8MzK7/0pNVwfiThV +# 9zeKiwmhywvpMRr/LhlcOXHhvpynCgbWJme3kuZOX956rEnPLqR0kq3bPKSchh/j +# wVYbKyP/j7XqiHtwa+aguv06P0WmxOgWkVKLQcBIhEuWTatEQOON8BUozu3xGFYH +# Ki8QxAwIZDwzj64ojDzLj4gLDb879M4ee47vtevLt/B3E+bnKD+sEq6lLyJsQfmC +# XBVmzGwOysWGw/YmMwwHS6DTBwJqakAwSEs0qFEgu60bhQjiWQ1tygVQK+pKHJ6l +# /aCnHwZ05/LWUpD9r4VIIflXO7ScA+2GRfS0YW6/aOImYIbqyK+p/pQd52MbOoZW +# eE4wggd3MIIFX6ADAgECAhAHHxQbizANJfMU6yMM0NHdMA0GCSqGSIb3DQEBCwUA +# MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE +# AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz +# ODQgMjAyMSBDQTEwHhcNMjIwMTE3MDAwMDAwWhcNMjUwMTE1MjM1OTU5WjB8MQsw +# CQYDVQQGEwJVUzEPMA0GA1UECBMGT3JlZ29uMRIwEAYDVQQHEwlCZWF2ZXJ0b24x +# IzAhBgNVBAoTGlB5dGhvbiBTb2Z0d2FyZSBGb3VuZGF0aW9uMSMwIQYDVQQDExpQ +# eXRob24gU29mdHdhcmUgRm91bmRhdGlvbjCCAiIwDQYJKoZIhvcNAQEBBQADggIP +# ADCCAgoCggIBAKgc0BTT+iKbtK6f2mr9pNMUTcAJxKdsuOiSYgDFfwhjQy89koM7 +# uP+QV/gwx8MzEt3c9tLJvDccVWQ8H7mVsk/K+X+IufBLCgUi0GGAZUegEAeRlSXx +# xhYScr818ma8EvGIZdiSOhqjYc4KnfgfIS4RLtZSrDFG2tN16yS8skFa3IHyvWdb +# D9PvZ4iYNAS4pjYDRjT/9uzPZ4Pan+53xZIcDgjiTwOh8VGuppxcia6a7xCyKoOA +# GjvCyQsj5223v1/Ig7Dp9mGI+nh1E3IwmyTIIuVHyK6Lqu352diDY+iCMpk9Zanm +# SjmB+GMVs+H/gOiofjjtf6oz0ki3rb7sQ8fTnonIL9dyGTJ0ZFYKeb6BLA66d2GA +# LwxZhLe5WH4Np9HcyXHACkppsE6ynYjTOd7+jN1PRJahN1oERzTzEiV6nCO1M3U1 +# HbPTGyq52IMFSBM2/07WTJSbOeXjvYR7aUxK9/ZkJiacl2iZI7IWe7JKhHohqKuc +# eQNyOzxTakLcRkzynvIrk33R9YVqtB4L6wtFxhUjvDnQg16xot2KVPdfyPAWd81w +# tZADmrUtsZ9qG79x1hBdyOl4vUtVPECuyhCxaw+faVjumapPUnwo8ygflJJ74J+B +# Yxf6UuD7m8yzsfXWkdv52DjL74TxzuFTLHPyARWCSCAbzn3ZIly+qIqDAgMBAAGj +# ggIGMIICAjAfBgNVHSMEGDAWgBRoN+Drtjv4XxGG+/5hewiIZfROQjAdBgNVHQ4E +# FgQUt/1Teh2XDuUj2WW3siYWJgkZHA8wDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQM +# MAoGCCsGAQUFBwMDMIG1BgNVHR8Ega0wgaowU6BRoE+GTWh0dHA6Ly9jcmwzLmRp +# Z2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNENvZGVTaWduaW5nUlNBNDA5NlNI +# QTM4NDIwMjFDQTEuY3JsMFOgUaBPhk1odHRwOi8vY3JsNC5kaWdpY2VydC5jb20v +# RGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JTQTQwOTZTSEEzODQyMDIxQ0Ex +# LmNybDA+BgNVHSAENzA1MDMGBmeBDAEEATApMCcGCCsGAQUFBwIBFhtodHRwOi8v +# d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwgZQGCCsGAQUFBwEBBIGHMIGEMCQGCCsGAQUF +# BzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wXAYIKwYBBQUHMAKGUGh0dHA6 +# Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNENvZGVTaWdu +# aW5nUlNBNDA5NlNIQTM4NDIwMjFDQTEuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZI +# hvcNAQELBQADggIBABxv4AeV/5ltkELHSC63fXAFYS5tadcWTiNc2rskrNLrfH1N +# s0vgSZFoQxYBFKI159E8oQQ1SKbTEubZ/B9kmHPhprHya08+VVzxC88pOEvz68nA +# 82oEM09584aILqYmj8Pj7h/kmZNzuEL7WiwFa/U1hX+XiWfLIJQsAHBla0i7QRF2 +# de8/VSF0XXFa2kBQ6aiTsiLyKPNbaNtbcucaUdn6vVUS5izWOXM95BSkFSKdE45O +# q3FForNJXjBvSCpwcP36WklaHL+aHu1upIhCTUkzTHMh8b86WmjRUqbrnvdyR2yd +# I5l1OqcMBjkpPpIV6wcc+KY/RH2xvVuuoHjlUjwq2bHiNoX+W1scCpnA8YTs2d50 +# jDHUgwUo+ciwpffH0Riq132NFmrH3r67VaN3TuBxjI8SIZM58WEDkbeoriDk3hxU +# 8ZWV7b8AW6oyVBGfM06UgkfMb58h+tJPrFx8VI/WLq1dTqMfZOm5cuclMnUHs2uq +# rRNtnV8UfidPBL4ZHkTcClQbCoz0UbLhkiDvIS00Dn+BBcxw/TKqVL4Oaz3bkMSs +# M46LciTeucHY9ExRVt3zy7i149sd+F4QozPqn7FrSVHXmem3r7bjyHTxOgqxRCVa +# 18Vtx7P/8bYSBeS+WHCKcliFCecspusCDSlnRUjZwyPdP0VHxaZg2unjHY3rMYIa +# tjCCGrICAQEwfTBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIElu +# Yy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgQ29kZSBTaWduaW5nIFJT +# QTQwOTYgU0hBMzg0IDIwMjEgQ0ExAhAHHxQbizANJfMU6yMM0NHdMA0GCWCGSAFl +# AwQCAQUAoIHIMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcC +# AQsxDjAMBgorBgEEAYI3AgEVMC8GCSqGSIb3DQEJBDEiBCBnAZ6P7YvTwq0fbF62 +# o7E75R0LxsW5OtyYiFESQckLhjBcBgorBgEEAYI3AgEMMU4wTKBGgEQAQgB1AGkA +# bAB0ADoAIABSAGUAbABlAGEAcwBlAF8AdgAzAC4AMQAyAC4ANgBfADIAMAAyADQA +# MAA5ADAANgAuADAAMqECgAAwDQYJKoZIhvcNAQEBBQAEggIAhen5GN03SF9I96DT +# rrWEsN7FAyx8BHoRf9WFBqoBXpFkBwlE6OWj/rxohuwB/b+3vcBGWaP497ACku4l +# lgrWCrmYOVMKTjeHtDDkvgmygvGAtWB5drf56553na9RYjTxRqxto5LBMsHtPZy6 +# 1D+touyLSHx+QXzqXO4ssUq7oHtsmjDCKMLdcTuoqNGtpxaIwwlOAK+0DaLLUpkX +# VRUUzMWBb+2FlmJ2wWtXXs6OtlACm4By2hHmKhd6OYwnHPe6fDVdrhGa0BcDAIIO +# +elm895ddmfX2KqHWrKpgZ/0DM46pbEiYX4GVwY+kmrK9p8XF7c50c331vPPuImL +# URRShtCM9F/5e522nQm0NxQ0Pz+thMD+qGBA8WuSoD+RRG+JKOXgM8sMX46goR8P +# 1IJLeUnEKSOgMNcP0EUeWthrqXRjVgNcazIDgPFpPGMyo4Pp0D8SPvp/RzP3CPVo +# uVj6r0OnhyoDuDEX4KCyo/+TCSm+2T+hv+cPWQaukovXF1TmahWb/8j1+K1RkCVd +# UQ5v07AHYoHmJ2gxEgtM9qaVDx4woVVCpUrOhiAP/K1WSRw710oTqECG+4y+g67D +# P2UuOxxaxhPk0pITFj9pZQcVsrCk5QbW3Yj/I3fISZgjVfYK1IDKzaWQQuBhOuim +# j2/Tfcg+cLDbY4XEs5vpbKSYsCWhghc/MIIXOwYKKwYBBAGCNwMDATGCFyswghcn +# BgkqhkiG9w0BBwKgghcYMIIXFAIBAzEPMA0GCWCGSAFlAwQCAQUAMHcGCyqGSIb3 +# DQEJEAEEoGgEZjBkAgEBBglghkgBhv1sBwEwMTANBglghkgBZQMEAgEFAAQgS2eq +# 9RcYET/J2twNl3zStqvYDUBOrSdHvMcFbSu+C2sCEGHEWhqgAhMA1D+QZOB9TC4Y +# DzIwMjQwOTA2MjAyNzExWqCCEwkwggbCMIIEqqADAgECAhAFRK/zlJ0IOaa/2z9f +# 5WEWMA0GCSqGSIb3DQEBCwUAMGMxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdp +# Q2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2 +# IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0EwHhcNMjMwNzE0MDAwMDAwWhcNMzQxMDEz +# MjM1OTU5WjBIMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4x +# IDAeBgNVBAMTF0RpZ2lDZXJ0IFRpbWVzdGFtcCAyMDIzMIICIjANBgkqhkiG9w0B +# AQEFAAOCAg8AMIICCgKCAgEAo1NFhx2DjlusPlSzI+DPn9fl0uddoQ4J3C9Io5d6 +# OyqcZ9xiFVjBqZMRp82qsmrdECmKHmJjadNYnDVxvzqX65RQjxwg6seaOy+WZuNp +# 52n+W8PWKyAcwZeUtKVQgfLPywemMGjKg0La/H8JJJSkghraarrYO8pd3hkYhftF +# 6g1hbJ3+cV7EBpo88MUueQ8bZlLjyNY+X9pD04T10Mf2SC1eRXWWdf7dEKEbg8G4 +# 5lKVtUfXeCk5a+B4WZfjRCtK1ZXO7wgX6oJkTf8j48qG7rSkIWRw69XloNpjsy7p +# Be6q9iT1HbybHLK3X9/w7nZ9MZllR1WdSiQvrCuXvp/k/XtzPjLuUjT71Lvr1KAs +# NJvj3m5kGQc3AZEPHLVRzapMZoOIaGK7vEEbeBlt5NkP4FhB+9ixLOFRr7StFQYU +# 6mIIE9NpHnxkTZ0P387RXoyqq1AVybPKvNfEO2hEo6U7Qv1zfe7dCv95NBB+plwK +# WEwAPoVpdceDZNZ1zY8SdlalJPrXxGshuugfNJgvOuprAbD3+yqG7HtSOKmYCaFx +# smxxrz64b5bV4RAT/mFHCoz+8LbH1cfebCTwv0KCyqBxPZySkwS0aXAnDU+3tTbR +# yV8IpHCj7ArxES5k4MsiK8rxKBMhSVF+BmbTO77665E42FEHypS34lCh8zrTioPL +# QHsCAwEAAaOCAYswggGHMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMBYG +# A1UdJQEB/wQMMAoGCCsGAQUFBwMIMCAGA1UdIAQZMBcwCAYGZ4EMAQQCMAsGCWCG +# SAGG/WwHATAfBgNVHSMEGDAWgBS6FtltTYUvcyl2mi91jGogj57IbzAdBgNVHQ4E +# FgQUpbbvE+fvzdBkodVWqWUxo97V40kwWgYDVR0fBFMwUTBPoE2gS4ZJaHR0cDov +# L2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0UlNBNDA5NlNIQTI1 +# NlRpbWVTdGFtcGluZ0NBLmNybDCBkAYIKwYBBQUHAQEEgYMwgYAwJAYIKwYBBQUH +# MAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBYBggrBgEFBQcwAoZMaHR0cDov +# L2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0UlNBNDA5NlNI +# QTI1NlRpbWVTdGFtcGluZ0NBLmNydDANBgkqhkiG9w0BAQsFAAOCAgEAgRrW3qCp +# tZgXvHCNT4o8aJzYJf/LLOTN6l0ikuyMIgKpuM+AqNnn48XtJoKKcS8Y3U623mzX +# 4WCcK+3tPUiOuGu6fF29wmE3aEl3o+uQqhLXJ4Xzjh6S2sJAOJ9dyKAuJXglnSoF +# eoQpmLZXeY/bJlYrsPOnvTcM2Jh2T1a5UsK2nTipgedtQVyMadG5K8TGe8+c+nji +# kxp2oml101DkRBK+IA2eqUTQ+OVJdwhaIcW0z5iVGlS6ubzBaRm6zxbygzc0brBB +# Jt3eWpdPM43UjXd9dUWhpVgmagNF3tlQtVCMr1a9TMXhRsUo063nQwBw3syYnhmJ +# A+rUkTfvTVLzyWAhxFZH7doRS4wyw4jmWOK22z75X7BC1o/jF5HRqsBV44a/rCcs +# QdCaM0qoNtS5cpZ+l3k4SF/Kwtw9Mt911jZnWon49qfH5U81PAC9vpwqbHkB3NpE +# 5jreODsHXjlY9HxzMVWggBHLFAx+rrz+pOt5Zapo1iLKO+uagjVXKBbLafIymrLS +# 2Dq4sUaGa7oX/cR3bBVsrquvczroSUa31X/MtjjA2Owc9bahuEMs305MfR5ocMB3 +# CtQC4Fxguyj/OOVSWtasFyIjTvTs0xf7UGv/B3cfcZdEQcm4RtNsMnxYL2dHZeUb +# c7aZ+WssBkbvQR7w8F/g29mtkIBEr4AQQYowggauMIIElqADAgECAhAHNje3JFR8 +# 2Ees/ShmKl5bMA0GCSqGSIb3DQEBCwUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK +# EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNV +# BAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0yMjAzMjMwMDAwMDBaFw0z +# NzAzMjIyMzU5NTlaMGMxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwg +# SW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1 +# NiBUaW1lU3RhbXBpbmcgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +# AQDGhjUGSbPBPXJJUVXHJQPE8pE3qZdRodbSg9GeTKJtoLDMg/la9hGhRBVCX6SI +# 82j6ffOciQt/nR+eDzMfUBMLJnOWbfhXqAJ9/UO0hNoR8XOxs+4rgISKIhjf69o9 +# xBd/qxkrPkLcZ47qUT3w1lbU5ygt69OxtXXnHwZljZQp09nsad/ZkIdGAHvbREGJ +# 3HxqV3rwN3mfXazL6IRktFLydkf3YYMZ3V+0VAshaG43IbtArF+y3kp9zvU5Emfv +# DqVjbOSmxR3NNg1c1eYbqMFkdECnwHLFuk4fsbVYTXn+149zk6wsOeKlSNbwsDET +# qVcplicu9Yemj052FVUmcJgmf6AaRyBD40NjgHt1biclkJg6OBGz9vae5jtb7IHe +# IhTZgirHkr+g3uM+onP65x9abJTyUpURK1h0QCirc0PO30qhHGs4xSnzyqqWc0Jo +# n7ZGs506o9UD4L/wojzKQtwYSH8UNM/STKvvmz3+DrhkKvp1KCRB7UK/BZxmSVJQ +# 9FHzNklNiyDSLFc1eSuo80VgvCONWPfcYd6T/jnA+bIwpUzX6ZhKWD7TA4j+s4/T +# Xkt2ElGTyYwMO1uKIqjBJgj5FBASA31fI7tk42PgpuE+9sJ0sj8eCXbsq11GdeJg +# o1gJASgADoRU7s7pXcheMBK9Rp6103a50g5rmQzSM7TNsQIDAQABo4IBXTCCAVkw +# EgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUuhbZbU2FL3MpdpovdYxqII+e +# yG8wHwYDVR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQD +# AgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMIMHcGCCsGAQUFBwEBBGswaTAkBggrBgEF +# BQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRw +# Oi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNy +# dDBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGln +# aUNlcnRUcnVzdGVkUm9vdEc0LmNybDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglg +# hkgBhv1sBwEwDQYJKoZIhvcNAQELBQADggIBAH1ZjsCTtm+YqUQiAX5m1tghQuGw +# GC4QTRPPMFPOvxj7x1Bd4ksp+3CKDaopafxpwc8dB+k+YMjYC+VcW9dth/qEICU0 +# MWfNthKWb8RQTGIdDAiCqBa9qVbPFXONASIlzpVpP0d3+3J0FNf/q0+KLHqrhc1D +# X+1gtqpPkWaeLJ7giqzl/Yy8ZCaHbJK9nXzQcAp876i8dU+6WvepELJd6f8oVInw +# 1YpxdmXazPByoyP6wCeCRK6ZJxurJB4mwbfeKuv2nrF5mYGjVoarCkXJ38SNoOeY +# +/umnXKvxMfBwWpx2cYTgAnEtp/Nh4cku0+jSbl3ZpHxcpzpSwJSpzd+k1OsOx0I +# SQ+UzTl63f8lY5knLD0/a6fxZsNBzU+2QJshIUDQtxMkzdwdeDrknq3lNHGS1yZr +# 5Dhzq6YBT70/O3itTK37xJV77QpfMzmHQXh6OOmc4d0j/R0o08f56PGYX/sr2H7y +# Rp11LB4nLCbbbxV7HhmLNriT1ObyF5lZynDwN7+YAN8gFk8n+2BnFqFmut1VwDop +# hrCYoCvtlUG3OtUVmDG0YgkPCr2B2RP+v6TR81fZvAT6gt4y3wSJ8ADNXcL50CN/ +# AAvkdgIm2fBldkKmKYcJRyvmfxqkhQ/8mJb2VVQrH4D6wPIOK+XW+6kvRBVK5xMO +# Hds3OBqhK/bt1nz8MIIFjTCCBHWgAwIBAgIQDpsYjvnQLefv21DiCEAYWjANBgkq +# hkiG9w0BAQwFADBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5j +# MRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBB +# c3N1cmVkIElEIFJvb3QgQ0EwHhcNMjIwODAxMDAwMDAwWhcNMzExMTA5MjM1OTU5 +# WjBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL +# ExB3d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJv +# b3QgRzQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1K +# PDAiMGkz7MKnJS7JIT3yithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2r +# snnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C +# 8weE5nQ7bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBf +# sXpm7nfISKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGY +# QJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8 +# rhsDdV14Ztk6MUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaY +# dj1ZXUJ2h4mXaXpI8OCiEhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+ +# wJS00mFt6zPZxd9LBADMfRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw +# ++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+N +# P8m800ERElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7F +# wI+isX4KJpn15GkvmB0t9dmpsh3lGwIDAQABo4IBOjCCATYwDwYDVR0TAQH/BAUw +# AwEB/zAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wHwYDVR0jBBgwFoAU +# Reuir/SSy4IxLVGLp6chnfNtyA8wDgYDVR0PAQH/BAQDAgGGMHkGCCsGAQUFBwEB +# BG0wazAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEMGCCsG +# AQUFBzAChjdodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1 +# cmVkSURSb290Q0EuY3J0MEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly9jcmwzLmRp +# Z2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwEQYDVR0gBAow +# CDAGBgRVHSAAMA0GCSqGSIb3DQEBDAUAA4IBAQBwoL9DXFXnOF+go3QbPbYW1/e/ +# Vwe9mqyhhyzshV6pGrsi+IcaaVQi7aSId229GhT0E0p6Ly23OO/0/4C5+KH38nLe +# JLxSA8hO0Cre+i1Wz/n096wwepqLsl7Uz9FDRJtDIeuWcqFItJnLnU+nBgMTdydE +# 1Od/6Fmo8L8vC6bp8jQ87PcDx4eo0kxAGTVGamlUsLihVo7spNU96LHc/RzY9Hda +# XFSMb++hUD38dglohJ9vytsgjTVgHAIDyyCwrFigDkBjxZgiwbJZ9VVrzyerbHbO +# byMt9H5xaiNrIv8SuFQtJ37YOtnwtoeW/VvRXKwYw02fc7cBqZ9Xql4o4rmUMYID +# djCCA3ICAQEwdzBjMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIElu +# Yy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBTSEEyNTYg +# VGltZVN0YW1waW5nIENBAhAFRK/zlJ0IOaa/2z9f5WEWMA0GCWCGSAFlAwQCAQUA +# oIHRMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAcBgkqhkiG9w0BCQUxDxcN +# MjQwOTA2MjAyNzExWjArBgsqhkiG9w0BCRACDDEcMBowGDAWBBRm8CsywsLJD4Jd +# zqqKycZPGZzPQDAvBgkqhkiG9w0BCQQxIgQgXSdFKsIxhS4gvdZFC5i8csELx4EN +# gje4K7DDRX8dz3AwNwYLKoZIhvcNAQkQAi8xKDAmMCQwIgQg0vbkbe10IszR1EBX +# aEE2b4KK2lWarjMWr00amtQMeCgwDQYJKoZIhvcNAQEBBQAEggIAYX9aC647tWiS +# rGwjsC+5s2CosHEwRzUG9YNI58OJgUfCwsfgMkgKWkSi/K7mumf5RHkU+P+HCwoy +# kvIOZ7viK9fcAkK9zS3eKPUA6mGQS11yEnEhRUZbrrsG1uHQO+gSO2SgyLs8+3vX +# /8+YEl1IkGbw4/oeLavq79jULQqZ6/00n0E0nFDmbprjFK4wUX4CoIqt8AAWCt4F +# Az8XwvYxa63A2JQmeDzDAWR4lfNbREQaC3MdnqbnvQIBQUspJsn3t7zxU+ubzCez +# kCkk+7Tt5FFCP9OJvc/BEv3HcXrTAoZ4VFfAwL9K1DQ4A3hbsvKlwV0OxZlhouMd +# fGq+R8IGMsy7mGxeHx67nzKIr6Rjd426YsGskp5D3gE9shvH8i3GOTBi2Y9JUnaU +# /KX+IMzKbvR0Y9echgTb17v3D/+fYzDD/kSGJcuQEIbJEyYsCDBF53xoKd6K0Pgz +# 2drucT9otwOLUgGfR1N6lRwDtkMHYB25OMIKLYtcfHjQZn+Howq/TVUbp9ohhW1N +# jim3nJfNvmRe2zN5476SOn86GzzrqxfAMCTtbZeim2ltOHxlnPUE8EJLdRFesKMK +# 6izgaxptlT+MO0R8jx1VoOn+qbQPbNn2GCOUvh/yFkjwDLtFb/rNdoWMNrSMZDhV +# mRCM17SwjW6qRmsrC7VSaSAgPsokYM0= +# SIG # End signature block diff --git a/.venv/Scripts/activate b/.venv/Scripts/activate new file mode 100644 index 0000000000000000000000000000000000000000..9487807efbdb62360b6aa05f1995cf9e6f27c79c --- /dev/null +++ b/.venv/Scripts/activate @@ -0,0 +1,70 @@ +# This file must be used with "source bin/activate" *from bash* +# You cannot run it directly + +deactivate () { + # reset old environment variables + if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then + PATH="${_OLD_VIRTUAL_PATH:-}" + export PATH + unset _OLD_VIRTUAL_PATH + fi + if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then + PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" + export PYTHONHOME + unset _OLD_VIRTUAL_PYTHONHOME + fi + + # Call hash to forget past commands. Without forgetting + # past commands the $PATH changes we made may not be respected + hash -r 2> /dev/null + + if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then + PS1="${_OLD_VIRTUAL_PS1:-}" + export PS1 + unset _OLD_VIRTUAL_PS1 + fi + + unset VIRTUAL_ENV + unset VIRTUAL_ENV_PROMPT + if [ ! "${1:-}" = "nondestructive" ] ; then + # Self destruct! + unset -f deactivate + fi +} + +# unset irrelevant variables +deactivate nondestructive + +# on Windows, a path can contain colons and backslashes and has to be converted: +if [ "${OSTYPE:-}" = "cygwin" ] || [ "${OSTYPE:-}" = "msys" ] ; then + # transform D:\path\to\venv to /d/path/to/venv on MSYS + # and to /cygdrive/d/path/to/venv on Cygwin + export VIRTUAL_ENV=$(cygpath "C:\Users\adity\OneDrive\Documents\AI challenge for HEALTHY Brain Aging\neurosaarthi-ad\.venv") +else + # use the path as-is + export VIRTUAL_ENV="C:\Users\adity\OneDrive\Documents\AI challenge for HEALTHY Brain Aging\neurosaarthi-ad\.venv" +fi + +_OLD_VIRTUAL_PATH="$PATH" +PATH="$VIRTUAL_ENV/Scripts:$PATH" +export PATH + +# unset PYTHONHOME if set +# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) +# could use `if (set -u; : $PYTHONHOME) ;` in bash +if [ -n "${PYTHONHOME:-}" ] ; then + _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" + unset PYTHONHOME +fi + +if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then + _OLD_VIRTUAL_PS1="${PS1:-}" + PS1="(.venv) ${PS1:-}" + export PS1 + VIRTUAL_ENV_PROMPT="(.venv) " + export VIRTUAL_ENV_PROMPT +fi + +# Call hash to forget past commands. Without forgetting +# past commands the $PATH changes we made may not be respected +hash -r 2> /dev/null diff --git a/.venv/Scripts/activate.bat b/.venv/Scripts/activate.bat new file mode 100644 index 0000000000000000000000000000000000000000..64088e3165981bf56603be98f14f5dfb8f032727 --- /dev/null +++ b/.venv/Scripts/activate.bat @@ -0,0 +1,34 @@ +@echo off + +rem This file is UTF-8 encoded, so we need to update the current code page while executing it +for /f "tokens=2 delims=:." %%a in ('"%SystemRoot%\System32\chcp.com"') do ( + set _OLD_CODEPAGE=%%a +) +if defined _OLD_CODEPAGE ( + "%SystemRoot%\System32\chcp.com" 65001 > nul +) + +set VIRTUAL_ENV=C:\Users\adity\OneDrive\Documents\AI challenge for HEALTHY Brain Aging\neurosaarthi-ad\.venv + +if not defined PROMPT set PROMPT=$P$G + +if defined _OLD_VIRTUAL_PROMPT set PROMPT=%_OLD_VIRTUAL_PROMPT% +if defined _OLD_VIRTUAL_PYTHONHOME set PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME% + +set _OLD_VIRTUAL_PROMPT=%PROMPT% +set PROMPT=(.venv) %PROMPT% + +if defined PYTHONHOME set _OLD_VIRTUAL_PYTHONHOME=%PYTHONHOME% +set PYTHONHOME= + +if defined _OLD_VIRTUAL_PATH set PATH=%_OLD_VIRTUAL_PATH% +if not defined _OLD_VIRTUAL_PATH set _OLD_VIRTUAL_PATH=%PATH% + +set PATH=%VIRTUAL_ENV%\Scripts;%PATH% +set VIRTUAL_ENV_PROMPT=(.venv) + +:END +if defined _OLD_CODEPAGE ( + "%SystemRoot%\System32\chcp.com" %_OLD_CODEPAGE% > nul + set _OLD_CODEPAGE= +) diff --git a/.venv/Scripts/deactivate.bat b/.venv/Scripts/deactivate.bat new file mode 100644 index 0000000000000000000000000000000000000000..44dae49537073789b536689bb940456e65929b99 --- /dev/null +++ b/.venv/Scripts/deactivate.bat @@ -0,0 +1,22 @@ +@echo off + +if defined _OLD_VIRTUAL_PROMPT ( + set "PROMPT=%_OLD_VIRTUAL_PROMPT%" +) +set _OLD_VIRTUAL_PROMPT= + +if defined _OLD_VIRTUAL_PYTHONHOME ( + set "PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%" + set _OLD_VIRTUAL_PYTHONHOME= +) + +if defined _OLD_VIRTUAL_PATH ( + set "PATH=%_OLD_VIRTUAL_PATH%" +) + +set _OLD_VIRTUAL_PATH= + +set VIRTUAL_ENV= +set VIRTUAL_ENV_PROMPT= + +:END diff --git a/.venv/Scripts/f2py.exe b/.venv/Scripts/f2py.exe new file mode 100644 index 0000000000000000000000000000000000000000..ee04bbbea4d7ff837f1c27e187bd57eb0261719f --- /dev/null +++ b/.venv/Scripts/f2py.exe @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:57c2c75b040d9ee4b7edb0c0fb3fa675a69b9879ad94eb6c868a899742218d17 +size 108467 diff --git a/.venv/Scripts/hf.exe b/.venv/Scripts/hf.exe new file mode 100644 index 0000000000000000000000000000000000000000..318581d32b66437ce867663b91e66b65e54184fe --- /dev/null +++ b/.venv/Scripts/hf.exe @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4e2f5c2d0c8a4fd39abde19c88774ac70d37082a777a42a9c41aa863a2368da +size 108472 diff --git a/.venv/Scripts/httpx.exe b/.venv/Scripts/httpx.exe new file mode 100644 index 0000000000000000000000000000000000000000..1b9efe56e7f21c31b68cc667139efceea87e905b --- /dev/null +++ b/.venv/Scripts/httpx.exe @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:42bb135bc153d829979f0aa0c984da93c1e2493c7e943e5b45911e00e1c3daef +size 108455 diff --git a/.venv/Scripts/huggingface-cli.exe b/.venv/Scripts/huggingface-cli.exe new file mode 100644 index 0000000000000000000000000000000000000000..db6cbeb4b21b3b6af6b02a08070d9c1b6070654b --- /dev/null +++ b/.venv/Scripts/huggingface-cli.exe @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3f136bf4f4b1bb61630140308e33da5b46a927db4ce5cd8316700e3e1426f8f9 +size 108484 diff --git a/.venv/Scripts/idna.exe b/.venv/Scripts/idna.exe new file mode 100644 index 0000000000000000000000000000000000000000..b608e539e59e1df2cc3d05cf549aa498de652e92 --- /dev/null +++ b/.venv/Scripts/idna.exe @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:45f1d6988caabb15455379e4b09849b1e7b3f39e1a540efe9d8b37b2fb2510d0 +size 108458 diff --git a/.venv/Scripts/jsonschema.exe b/.venv/Scripts/jsonschema.exe new file mode 100644 index 0000000000000000000000000000000000000000..07d8dfe3aff51256512e000cd2be2ef5e5fe6f96 --- /dev/null +++ b/.venv/Scripts/jsonschema.exe @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:80f00bf4384b095d42c88bd6dd116da6a05f72b4f250647c0c744102643a4488 +size 108464 diff --git a/.venv/Scripts/normalizer.exe b/.venv/Scripts/normalizer.exe new file mode 100644 index 0000000000000000000000000000000000000000..1e213139d12c10b97c4a14b60021e3be2a10f0aa --- /dev/null +++ b/.venv/Scripts/normalizer.exe @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b047956aaf641a521f41c3caedca4c7c1a10d28da38e1382eb9607a46aa017f8 +size 108484 diff --git a/.venv/Scripts/numpy-config.exe b/.venv/Scripts/numpy-config.exe new file mode 100644 index 0000000000000000000000000000000000000000..59d6827e029800b79754b83122180647e70b7bc1 --- /dev/null +++ b/.venv/Scripts/numpy-config.exe @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4ddefa7c161b7aff5aa44526d6de5eba9520676ca3ddcac4f14989e465b186e0 +size 108467 diff --git a/.venv/Scripts/pip.exe b/.venv/Scripts/pip.exe new file mode 100644 index 0000000000000000000000000000000000000000..c7ce8d72d5797e65d696c68801e5a464c38537e8 --- /dev/null +++ b/.venv/Scripts/pip.exe @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5bdd03d796ce9397add7306802cb2e5b4fd59ad3ada2f8ad6ff49fe903959d4c +size 108472 diff --git a/.venv/Scripts/pip3.12.exe b/.venv/Scripts/pip3.12.exe new file mode 100644 index 0000000000000000000000000000000000000000..c7ce8d72d5797e65d696c68801e5a464c38537e8 --- /dev/null +++ b/.venv/Scripts/pip3.12.exe @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5bdd03d796ce9397add7306802cb2e5b4fd59ad3ada2f8ad6ff49fe903959d4c +size 108472 diff --git a/.venv/Scripts/pip3.exe b/.venv/Scripts/pip3.exe new file mode 100644 index 0000000000000000000000000000000000000000..c7ce8d72d5797e65d696c68801e5a464c38537e8 --- /dev/null +++ b/.venv/Scripts/pip3.exe @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5bdd03d796ce9397add7306802cb2e5b4fd59ad3ada2f8ad6ff49fe903959d4c +size 108472 diff --git a/.venv/Scripts/py.test.exe b/.venv/Scripts/py.test.exe new file mode 100644 index 0000000000000000000000000000000000000000..99c57bc6eda855057c2af0d8af09cba0ade5be8a --- /dev/null +++ b/.venv/Scripts/py.test.exe @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:96e225c0fae3a4ce5e8479c17cf619d2f5ec4603ae594f23831793021656fdc2 +size 108482 diff --git a/.venv/Scripts/pygmentize.exe b/.venv/Scripts/pygmentize.exe new file mode 100644 index 0000000000000000000000000000000000000000..71ff59d2434c8047e3665293777a6c62359d3805 --- /dev/null +++ b/.venv/Scripts/pygmentize.exe @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:da08931c176f2616c301d551ac5e96c385c6ea24302306d0eb90e40b92013f2d +size 108466 diff --git a/.venv/Scripts/pytest.exe b/.venv/Scripts/pytest.exe new file mode 100644 index 0000000000000000000000000000000000000000..99c57bc6eda855057c2af0d8af09cba0ade5be8a --- /dev/null +++ b/.venv/Scripts/pytest.exe @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:96e225c0fae3a4ce5e8479c17cf619d2f5ec4603ae594f23831793021656fdc2 +size 108482 diff --git a/.venv/Scripts/python.exe b/.venv/Scripts/python.exe new file mode 100644 index 0000000000000000000000000000000000000000..8c193884f934b38c1da52ad0a1d39b341027d5b0 --- /dev/null +++ b/.venv/Scripts/python.exe @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3470f7919170d235d7e6079691462c4b217745ec67ee612e745730e46d98f238 +size 270104 diff --git a/.venv/Scripts/pythonw.exe b/.venv/Scripts/pythonw.exe new file mode 100644 index 0000000000000000000000000000000000000000..5daeb007300a1407860cd3c3f00732e98e29f9c9 --- /dev/null +++ b/.venv/Scripts/pythonw.exe @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dbb5bf39746dadaf2d2513da6746ed61a04b493289272dbed72923eabfd552f8 +size 258840 diff --git a/.venv/Scripts/streamlit.exe b/.venv/Scripts/streamlit.exe new file mode 100644 index 0000000000000000000000000000000000000000..b035270a2e00ab824f82d46851fd216a773fd8ef --- /dev/null +++ b/.venv/Scripts/streamlit.exe @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7c9041d18203ed202f7f925082f97eb4c4fb8805c12d54928f5df1e8356d4120 +size 108467 diff --git a/.venv/Scripts/tiny-agents.exe b/.venv/Scripts/tiny-agents.exe new file mode 100644 index 0000000000000000000000000000000000000000..1db58941f07ac49d81ee9fb951b09a99f4eec9e6 --- /dev/null +++ b/.venv/Scripts/tiny-agents.exe @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:655fb5e3f7f3152a731b6ed05a6adb311b675249053096b44a52d72e99ecdec5 +size 108482 diff --git a/.venv/Scripts/tqdm.exe b/.venv/Scripts/tqdm.exe new file mode 100644 index 0000000000000000000000000000000000000000..cb2689ac988b2bdb152e5a121afffc47d737fb11 --- /dev/null +++ b/.venv/Scripts/tqdm.exe @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cd1a956fd3ef8879c7ade2f4404a260ada531be72a4966a93193d2d09fb75970 +size 108458 diff --git a/.venv/Scripts/uvicorn.exe b/.venv/Scripts/uvicorn.exe new file mode 100644 index 0000000000000000000000000000000000000000..0fcbd2e87ece4d19ecfb6207dbfab71139aa154f --- /dev/null +++ b/.venv/Scripts/uvicorn.exe @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f923e15649a82a89b23769bf700011ef3f87be85864ca6e26b3e252b2ec169c5 +size 108462 diff --git a/.venv/Scripts/watchmedo.exe b/.venv/Scripts/watchmedo.exe new file mode 100644 index 0000000000000000000000000000000000000000..3e8bf6efd8b396cd942458ef61ea99908d68d5cc --- /dev/null +++ b/.venv/Scripts/watchmedo.exe @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:11431a8abbb4a5f73b610ea1649026638c5ae66686a41dccc7c92d54484787a0 +size 108468 diff --git a/.venv/Scripts/websockets.exe b/.venv/Scripts/websockets.exe new file mode 100644 index 0000000000000000000000000000000000000000..afbe4060d9638db3fb538d4444c88168013e59a0 --- /dev/null +++ b/.venv/Scripts/websockets.exe @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1e22f03a79f8bf03b79dacee682f0d7fc53a5ebb3697ec16db824d98a4ec87b0 +size 108464 diff --git a/.venv/pyvenv.cfg b/.venv/pyvenv.cfg new file mode 100644 index 0000000000000000000000000000000000000000..d4649803e7c54dbdc55d102cfd63dd2c530c9037 --- /dev/null +++ b/.venv/pyvenv.cfg @@ -0,0 +1,5 @@ +home = C:\Python312 +include-system-site-packages = false +version = 3.12.6 +executable = C:\Python312\python.exe +command = C:\Python312\python.exe -m venv C:\Users\adity\OneDrive\Documents\AI challenge for HEALTHY Brain Aging\neurosaarthi-ad\.venv diff --git a/.venv/share/jupyter/nbextensions/pydeck/extensionRequires.js b/.venv/share/jupyter/nbextensions/pydeck/extensionRequires.js new file mode 100644 index 0000000000000000000000000000000000000000..f663cc192edcb23360ed281390a083352c743434 --- /dev/null +++ b/.venv/share/jupyter/nbextensions/pydeck/extensionRequires.js @@ -0,0 +1,15 @@ +/* eslint-disable */ +define(function() { + 'use strict'; + requirejs.config({ + map: { + '*': { + '@deck.gl/jupyter-widget': 'nbextensions/pydeck/index' + } + } + }); + // Export the required load_ipython_extension function + return { + load_ipython_extension: function() {} + }; +}); diff --git a/.venv/share/jupyter/nbextensions/pydeck/index.js b/.venv/share/jupyter/nbextensions/pydeck/index.js new file mode 100644 index 0000000000000000000000000000000000000000..5349da7e58a49446ce2ee4fcd6ccf440fd6922c4 --- /dev/null +++ b/.venv/share/jupyter/nbextensions/pydeck/index.js @@ -0,0 +1,8929 @@ +(function webpackUniversalModuleDefinition(root, factory) { + if (typeof exports === 'object' && typeof module === 'object') + module.exports = factory(); + else if (typeof define === 'function' && define.amd) define([], factory); + else { + var a = factory(); + for (var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i]; +}})(globalThis, function () { +"use strict";var __exports__=(()=>{var BTe=Object.create;var bI=Object.defineProperty;var LTe=Object.getOwnPropertyDescriptor;var DTe=Object.getOwnPropertyNames;var OTe=Object.getPrototypeOf,FTe=Object.prototype.hasOwnProperty;var kTe=(t,e,r)=>e in t?bI(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r;var lQ=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,r)=>(typeof require<"u"?require:e)[r]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw new Error('Dynamic require of "'+t+'" is not supported')});var Nt=(t,e)=>()=>(t&&(e=t(t=0)),e);var Vi=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),Ua=(t,e)=>{for(var r in e)bI(t,r,{get:e[r],enumerable:!0})},cQ=(t,e,r,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of DTe(e))!FTe.call(t,n)&&n!==r&&bI(t,n,{get:()=>e[n],enumerable:!(i=LTe(e,n))||i.enumerable});return t};var If=(t,e,r)=>(r=t!=null?BTe(OTe(t)):{},cQ(e||!t||!t.__esModule?bI(r,"default",{value:t,enumerable:!0}):r,t)),uQ=t=>cQ(bI({},"__esModule",{value:!0}),t);var Qi=(t,e,r)=>(kTe(t,typeof e!="symbol"?e+"":e,r),r);var yD,HTe,vD,GTe,fQ,k8=Nt(()=>{yD=globalThis,HTe=globalThis.document||{},vD=globalThis.process||{},GTe=globalThis.console,fQ=globalThis.navigator||{}});function xD(t){if(typeof window<"u"&&window.process?.type==="renderer"||typeof process<"u"&&Boolean(process.versions?.electron))return!0;let e=typeof navigator<"u"&&navigator.userAgent,r=t||e;return Boolean(r&&r.indexOf("Electron")>=0)}var N8=Nt(()=>{});function rp(){return!(typeof process=="object"&&String(process)==="[object process]"&&!process?.browser)||xD()}var z8=Nt(()=>{N8()});function U8(t){return!t&&!rp()?"Node":xD(t)?"Electron":(t||fQ.userAgent||"").indexOf("Edge")>-1?"Edge":globalThis.chrome?"Chrome":globalThis.safari?"Safari":globalThis.mozInnerScreenX?"Firefox":"Unknown"}var dQ=Nt(()=>{z8();N8();k8()});var V8,Iv=Nt(()=>{k8();z8();dQ();V8="4.1.1"});function G2(t,e){if(!t)throw new Error(e||"Assertion failed")}var j8=Nt(()=>{});function H8(t){if(!t)return 0;let e;switch(typeof t){case"number":e=t;break;case"object":e=t.logLevel||t.priority||0;break;default:return 0}return G2(Number.isFinite(e)&&e>=0),e}function pQ(t){let{logLevel:e,message:r}=t;t.logLevel=H8(e);let i=t.args?Array.from(t.args):[];for(;i.length&&i.shift()!==r;);switch(typeof e){case"string":case"function":r!==void 0&&i.unshift(r),t.message=e;break;case"object":Object.assign(t,e);break;default:}typeof t.message=="function"&&(t.message=t.message());let n=typeof t.message;return G2(n==="string"||n==="object"),Object.assign(t,{args:i},t.opts)}var mQ=Nt(()=>{j8()});var Bb,bD,gQ=Nt(()=>{mQ();Bb=()=>{},bD=class{constructor({level:e=0}={}){this.userData={},this._onceCache=new Set,this._level=e}set level(e){this.setLevel(e)}get level(){return this.getLevel()}setLevel(e){return this._level=e,this}getLevel(){return this._level}warn(e,...r){return this._log("warn",0,e,r,{once:!0})}error(e,...r){return this._log("error",0,e,r)}log(e,r,...i){return this._log("log",e,r,i)}info(e,r,...i){return this._log("info",e,r,i)}once(e,r,...i){return this._log("once",e,r,i,{once:!0})}_log(e,r,i,n,o={}){let s=pQ({logLevel:r,message:i,args:this._buildArgs(r,i,n),opts:o});return this._createLogFunction(e,s,o)}_buildArgs(e,r,i){return[e,r,...i]}_createLogFunction(e,r,i){if(!this._shouldLog(r.logLevel))return Bb;let n=this._getOnceTag(i.tag??r.tag??r.message);if((i.once||r.once)&&n!==void 0){if(this._onceCache.has(n))return Bb;this._onceCache.add(n)}return this._emit(e,r)}_shouldLog(e){return this.getLevel()>=H8(e)}_getOnceTag(e){if(e!==void 0)try{return typeof e=="string"?e:String(e)}catch{return}}}});function qTe(t){try{let e=window[t],r="__storage_test__";return e.setItem(r,r),e.removeItem(r),e}catch{return null}}var wD,AQ=Nt(()=>{wD=class{constructor(e,r,i="sessionStorage"){this.storage=qTe(i),this.id=e,this.config=r,this._loadConfiguration()}getConfiguration(){return this.config}setConfiguration(e){if(Object.assign(this.config,e),this.storage){let r=JSON.stringify(this.config);this.storage.setItem(this.id,r)}}_loadConfiguration(){let e={};if(this.storage){let r=this.storage.getItem(this.id);e=r?JSON.parse(r):{}}return Object.assign(this.config,e),this}}});function _Q(t){let e;return t<10?e=`${t.toFixed(2)}ms`:t<100?e=`${t.toFixed(1)}ms`:t<1e3?e=`${t.toFixed(0)}ms`:e=`${(t/1e3).toFixed(2)}s`,e}function yQ(t,e=8){let r=Math.max(e-t.length,0);return`${" ".repeat(r)}${t}`}var vQ=Nt(()=>{});function xQ(t){return typeof t!="string"?t:(t=t.toUpperCase(),TD[t]||TD.WHITE)}function bQ(t,e,r){return!rp&&typeof t=="string"&&(e&&(t=`\x1B[${xQ(e)}m${t}\x1B[39m`),r&&(t=`\x1B[${xQ(r)+$Te}m${t}\x1B[49m`)),t}var TD,$Te,wQ=Nt(()=>{Iv();(function(t){t[t.BLACK=30]="BLACK",t[t.RED=31]="RED",t[t.GREEN=32]="GREEN",t[t.YELLOW=33]="YELLOW",t[t.BLUE=34]="BLUE",t[t.MAGENTA=35]="MAGENTA",t[t.CYAN=36]="CYAN",t[t.WHITE=37]="WHITE",t[t.BRIGHT_BLACK=90]="BRIGHT_BLACK",t[t.BRIGHT_RED=91]="BRIGHT_RED",t[t.BRIGHT_GREEN=92]="BRIGHT_GREEN",t[t.BRIGHT_YELLOW=93]="BRIGHT_YELLOW",t[t.BRIGHT_BLUE=94]="BRIGHT_BLUE",t[t.BRIGHT_MAGENTA=95]="BRIGHT_MAGENTA",t[t.BRIGHT_CYAN=96]="BRIGHT_CYAN",t[t.BRIGHT_WHITE=97]="BRIGHT_WHITE"})(TD||(TD={}));$Te=10});function TQ(t,e=["constructor"]){let r=Object.getPrototypeOf(t),i=Object.getOwnPropertyNames(r),n=t;for(let o of i){let s=n[o];typeof s=="function"&&(e.find(c=>o===c)||(n[o]=s.bind(t)))}}var SQ=Nt(()=>{});function W2(){let t;if(rp()&&yD.performance)t=yD?.performance?.now?.();else if("hrtime"in vD){let e=vD?.hrtime?.();t=e[0]*1e3+e[1]/1e6}else t=Date.now();return t}var EQ=Nt(()=>{Iv()});function XTe(t,e,r){if(typeof e=="string"){let i=r.time?yQ(_Q(r.total)):"";e=r.time?`${t}: ${i} ${e}`:`${t}: ${e}`,e=bQ(e,r.color,r.background)}return e}function ZTe(t){for(let e in t)for(let r in t[e])return r||"untitled";return"empty"}var q2,G8,sf,W8=Nt(()=>{Iv();gQ();AQ();vQ();wQ();SQ();j8();EQ();q2={debug:rp()&&console.debug||console.log,log:console.log,info:console.info,warn:console.warn,error:console.error},G8={enabled:!0,level:0},sf=class extends bD{constructor({id:e}={id:""}){super({level:0}),this.VERSION=V8,this._startTs=W2(),this._deltaTs=W2(),this.userData={},this.LOG_THROTTLE_TIMEOUT=0,this.id=e,this.userData={},this._storage=new wD(`__probe-${this.id}__`,{[this.id]:G8}),this.timeStamp(`${this.id} started`),TQ(this),Object.seal(this)}isEnabled(){return this._getConfiguration().enabled}getLevel(){return this._getConfiguration().level}getTotal(){return Number((W2()-this._startTs).toPrecision(10))}getDelta(){return Number((W2()-this._deltaTs).toPrecision(10))}set priority(e){this.level=e}get priority(){return this.level}getPriority(){return this.level}enable(e=!0){return this._updateConfiguration({enabled:e}),this}setLevel(e){return this._updateConfiguration({level:e}),this}get(e){return this._getConfiguration()[e]}set(e,r){this._updateConfiguration({[e]:r})}settings(){console.table?console.table(this._storage.config):console.log(this._storage.config)}assert(e,r){if(!e)throw new Error(r||"Assertion failed")}warn(e,...r){return this._log("warn",0,e,r,{method:q2.warn,once:!0})}error(e,...r){return this._log("error",0,e,r,{method:q2.error})}deprecated(e,r){return this.warn(`\`${e}\` is deprecated and will be removed in a later version. Use \`${r}\` instead`)}removed(e,r){return this.error(`\`${e}\` has been removed. Use \`${r}\` instead`)}probe(e,r,...i){return this._log("log",e,r,i,{method:q2.log,time:!0,once:!0})}log(e,r,...i){return this._log("log",e,r,i,{method:q2.debug})}info(e,r,...i){return this._log("info",e,r,i,{method:console.info})}once(e,r,...i){return this._log("once",e,r,i,{method:q2.debug||q2.info,once:!0})}table(e,r,i){return r?this._log("table",e,r,i&&[i]||[],{method:console.table||Bb,tag:ZTe(r)}):Bb}time(e,r){return this._log("time",e,r,[],{method:console.time?console.time:console.info})}timeEnd(e,r){return this._log("time",e,r,[],{method:console.timeEnd?console.timeEnd:console.info})}timeStamp(e,r){return this._log("time",e,r,[],{method:console.timeStamp||Bb})}group(e,r,i={collapsed:!1}){let n=(i.collapsed?console.groupCollapsed:console.group)||console.info;return this._log("group",e,r,[],{method:n})}groupCollapsed(e,r,i={}){return this.group(e,r,Object.assign({},i,{collapsed:!0}))}groupEnd(e){return this._log("groupEnd",e,"",[],{method:console.groupEnd||Bb})}withGroup(e,r,i){this.group(e,r)();try{i()}finally{this.groupEnd(e)()}}trace(){console.trace&&console.trace()}_shouldLog(e){return this.isEnabled()&&super._shouldLog(e)}_emit(e,r){let i=r.method;G2(i),r.total=this.getTotal(),r.delta=this.getDelta(),this._deltaTs=W2();let n=XTe(this.id,r.message,r);return i.bind(console,n,...r.args)}_getConfiguration(){return this._storage.config[this.id]||this._updateConfiguration(G8),this._storage.config[this.id]}_updateConfiguration(e){let r=this._storage.config[this.id]||{...G8};this._storage.setConfiguration({[this.id]:{...r,...e}})}};sf.VERSION=V8});var CQ=Nt(()=>{globalThis.probe={}});var q8,Mv=Nt(()=>{W8();W8();CQ();q8=new sf({id:"@probe.gl/log"})});function RI(){let t;if(typeof window<"u"&&window.performance)t=window.performance.now();else if(typeof process<"u"&&process.hrtime){let e=process.hrtime();t=e[0]*1e3+e[1]/1e6}else t=Date.now();return t}var fV=Nt(()=>{});var kb,dV=Nt(()=>{fV();kb=class{constructor(e,r){this.sampleSize=1,this.time=0,this.count=0,this.samples=0,this.lastTiming=0,this.lastSampleTime=0,this.lastSampleCount=0,this._count=0,this._time=0,this._samples=0,this._startTime=0,this._timerPending=!1,this.name=e,this.type=r,this.reset()}reset(){return this.time=0,this.count=0,this.samples=0,this.lastTiming=0,this.lastSampleTime=0,this.lastSampleCount=0,this._count=0,this._time=0,this._samples=0,this._startTime=0,this._timerPending=!1,this}setSampleSize(e){return this.sampleSize=e,this}incrementCount(){return this.addCount(1),this}decrementCount(){return this.subtractCount(1),this}addCount(e){return this._count+=e,this._samples++,this._checkSampling(),this}subtractCount(e){return this._count-=e,this._samples++,this._checkSampling(),this}addTime(e){return this._time+=e,this.lastTiming=e,this._samples++,this._checkSampling(),this}timeStart(){return this._startTime=RI(),this._timerPending=!0,this}timeEnd(){return this._timerPending?(this.addTime(RI()-this._startTime),this._timerPending=!1,this._checkSampling(),this):this}getSampleAverageCount(){return this.sampleSize>0?this.lastSampleCount/this.sampleSize:0}getSampleAverageTime(){return this.sampleSize>0?this.lastSampleTime/this.sampleSize:0}getSampleHz(){return this.lastSampleTime>0?this.sampleSize/(this.lastSampleTime/1e3):0}getAverageCount(){return this.samples>0?this.count/this.samples:0}getAverageTime(){return this.samples>0?this.time/this.samples:0}getHz(){return this.time>0?this.samples/(this.time/1e3):0}_checkSampling(){this._samples===this.sampleSize&&(this.lastSampleTime=this._time,this.lastSampleCount=this._count,this.count+=this._count,this.time+=this._time,this.samples+=this._samples,this._time=0,this._count=0,this._samples=0)}}});var Ed,HQ=Nt(()=>{dV();Ed=class{constructor(e){this.stats={},this.id=e.id,this.stats={},this._initializeStats(e.stats),Object.seal(this)}get(e,r="count"){return this._getOrCreate({name:e,type:r})}get size(){return Object.keys(this.stats).length}reset(){for(let e of Object.values(this.stats))e.reset();return this}forEach(e){for(let r of Object.values(this.stats))e(r)}getTable(){let e={};return this.forEach(r=>{e[r.name]={time:r.time||0,count:r.count||0,average:r.getAverageTime()||0,hz:r.getHz()||0}}),e}_initializeStats(e=[]){e.forEach(r=>this._getOrCreate(r))}_getOrCreate(e){let{name:r,type:i}=e,n=this.stats[r];return n||(e instanceof kb?n=e:n=new kb(r,i),this.stats[r]=n),n}}});var Nb=Nt(()=>{HQ();dV();fV()});var WA,ute=Nt(()=>{(function(t){t[t.DEPTH_BUFFER_BIT=256]="DEPTH_BUFFER_BIT",t[t.STENCIL_BUFFER_BIT=1024]="STENCIL_BUFFER_BIT",t[t.COLOR_BUFFER_BIT=16384]="COLOR_BUFFER_BIT",t[t.POINTS=0]="POINTS",t[t.LINES=1]="LINES",t[t.LINE_LOOP=2]="LINE_LOOP",t[t.LINE_STRIP=3]="LINE_STRIP",t[t.TRIANGLES=4]="TRIANGLES",t[t.TRIANGLE_STRIP=5]="TRIANGLE_STRIP",t[t.TRIANGLE_FAN=6]="TRIANGLE_FAN",t[t.ZERO=0]="ZERO",t[t.ONE=1]="ONE",t[t.SRC_COLOR=768]="SRC_COLOR",t[t.ONE_MINUS_SRC_COLOR=769]="ONE_MINUS_SRC_COLOR",t[t.SRC_ALPHA=770]="SRC_ALPHA",t[t.ONE_MINUS_SRC_ALPHA=771]="ONE_MINUS_SRC_ALPHA",t[t.DST_ALPHA=772]="DST_ALPHA",t[t.ONE_MINUS_DST_ALPHA=773]="ONE_MINUS_DST_ALPHA",t[t.DST_COLOR=774]="DST_COLOR",t[t.ONE_MINUS_DST_COLOR=775]="ONE_MINUS_DST_COLOR",t[t.SRC_ALPHA_SATURATE=776]="SRC_ALPHA_SATURATE",t[t.CONSTANT_COLOR=32769]="CONSTANT_COLOR",t[t.ONE_MINUS_CONSTANT_COLOR=32770]="ONE_MINUS_CONSTANT_COLOR",t[t.CONSTANT_ALPHA=32771]="CONSTANT_ALPHA",t[t.ONE_MINUS_CONSTANT_ALPHA=32772]="ONE_MINUS_CONSTANT_ALPHA",t[t.FUNC_ADD=32774]="FUNC_ADD",t[t.FUNC_SUBTRACT=32778]="FUNC_SUBTRACT",t[t.FUNC_REVERSE_SUBTRACT=32779]="FUNC_REVERSE_SUBTRACT",t[t.BLEND_EQUATION=32777]="BLEND_EQUATION",t[t.BLEND_EQUATION_RGB=32777]="BLEND_EQUATION_RGB",t[t.BLEND_EQUATION_ALPHA=34877]="BLEND_EQUATION_ALPHA",t[t.BLEND_DST_RGB=32968]="BLEND_DST_RGB",t[t.BLEND_SRC_RGB=32969]="BLEND_SRC_RGB",t[t.BLEND_DST_ALPHA=32970]="BLEND_DST_ALPHA",t[t.BLEND_SRC_ALPHA=32971]="BLEND_SRC_ALPHA",t[t.BLEND_COLOR=32773]="BLEND_COLOR",t[t.ARRAY_BUFFER_BINDING=34964]="ARRAY_BUFFER_BINDING",t[t.ELEMENT_ARRAY_BUFFER_BINDING=34965]="ELEMENT_ARRAY_BUFFER_BINDING",t[t.LINE_WIDTH=2849]="LINE_WIDTH",t[t.ALIASED_POINT_SIZE_RANGE=33901]="ALIASED_POINT_SIZE_RANGE",t[t.ALIASED_LINE_WIDTH_RANGE=33902]="ALIASED_LINE_WIDTH_RANGE",t[t.CULL_FACE_MODE=2885]="CULL_FACE_MODE",t[t.FRONT_FACE=2886]="FRONT_FACE",t[t.DEPTH_RANGE=2928]="DEPTH_RANGE",t[t.DEPTH_WRITEMASK=2930]="DEPTH_WRITEMASK",t[t.DEPTH_CLEAR_VALUE=2931]="DEPTH_CLEAR_VALUE",t[t.DEPTH_FUNC=2932]="DEPTH_FUNC",t[t.STENCIL_CLEAR_VALUE=2961]="STENCIL_CLEAR_VALUE",t[t.STENCIL_FUNC=2962]="STENCIL_FUNC",t[t.STENCIL_FAIL=2964]="STENCIL_FAIL",t[t.STENCIL_PASS_DEPTH_FAIL=2965]="STENCIL_PASS_DEPTH_FAIL",t[t.STENCIL_PASS_DEPTH_PASS=2966]="STENCIL_PASS_DEPTH_PASS",t[t.STENCIL_REF=2967]="STENCIL_REF",t[t.STENCIL_VALUE_MASK=2963]="STENCIL_VALUE_MASK",t[t.STENCIL_WRITEMASK=2968]="STENCIL_WRITEMASK",t[t.STENCIL_BACK_FUNC=34816]="STENCIL_BACK_FUNC",t[t.STENCIL_BACK_FAIL=34817]="STENCIL_BACK_FAIL",t[t.STENCIL_BACK_PASS_DEPTH_FAIL=34818]="STENCIL_BACK_PASS_DEPTH_FAIL",t[t.STENCIL_BACK_PASS_DEPTH_PASS=34819]="STENCIL_BACK_PASS_DEPTH_PASS",t[t.STENCIL_BACK_REF=36003]="STENCIL_BACK_REF",t[t.STENCIL_BACK_VALUE_MASK=36004]="STENCIL_BACK_VALUE_MASK",t[t.STENCIL_BACK_WRITEMASK=36005]="STENCIL_BACK_WRITEMASK",t[t.VIEWPORT=2978]="VIEWPORT",t[t.SCISSOR_BOX=3088]="SCISSOR_BOX",t[t.COLOR_CLEAR_VALUE=3106]="COLOR_CLEAR_VALUE",t[t.COLOR_WRITEMASK=3107]="COLOR_WRITEMASK",t[t.UNPACK_ALIGNMENT=3317]="UNPACK_ALIGNMENT",t[t.PACK_ALIGNMENT=3333]="PACK_ALIGNMENT",t[t.MAX_TEXTURE_SIZE=3379]="MAX_TEXTURE_SIZE",t[t.MAX_VIEWPORT_DIMS=3386]="MAX_VIEWPORT_DIMS",t[t.SUBPIXEL_BITS=3408]="SUBPIXEL_BITS",t[t.RED_BITS=3410]="RED_BITS",t[t.GREEN_BITS=3411]="GREEN_BITS",t[t.BLUE_BITS=3412]="BLUE_BITS",t[t.ALPHA_BITS=3413]="ALPHA_BITS",t[t.DEPTH_BITS=3414]="DEPTH_BITS",t[t.STENCIL_BITS=3415]="STENCIL_BITS",t[t.POLYGON_OFFSET_UNITS=10752]="POLYGON_OFFSET_UNITS",t[t.POLYGON_OFFSET_FACTOR=32824]="POLYGON_OFFSET_FACTOR",t[t.TEXTURE_BINDING_2D=32873]="TEXTURE_BINDING_2D",t[t.SAMPLE_BUFFERS=32936]="SAMPLE_BUFFERS",t[t.SAMPLES=32937]="SAMPLES",t[t.SAMPLE_COVERAGE_VALUE=32938]="SAMPLE_COVERAGE_VALUE",t[t.SAMPLE_COVERAGE_INVERT=32939]="SAMPLE_COVERAGE_INVERT",t[t.COMPRESSED_TEXTURE_FORMATS=34467]="COMPRESSED_TEXTURE_FORMATS",t[t.VENDOR=7936]="VENDOR",t[t.RENDERER=7937]="RENDERER",t[t.VERSION=7938]="VERSION",t[t.IMPLEMENTATION_COLOR_READ_TYPE=35738]="IMPLEMENTATION_COLOR_READ_TYPE",t[t.IMPLEMENTATION_COLOR_READ_FORMAT=35739]="IMPLEMENTATION_COLOR_READ_FORMAT",t[t.BROWSER_DEFAULT_WEBGL=37444]="BROWSER_DEFAULT_WEBGL",t[t.STATIC_DRAW=35044]="STATIC_DRAW",t[t.STREAM_DRAW=35040]="STREAM_DRAW",t[t.DYNAMIC_DRAW=35048]="DYNAMIC_DRAW",t[t.ARRAY_BUFFER=34962]="ARRAY_BUFFER",t[t.ELEMENT_ARRAY_BUFFER=34963]="ELEMENT_ARRAY_BUFFER",t[t.BUFFER_SIZE=34660]="BUFFER_SIZE",t[t.BUFFER_USAGE=34661]="BUFFER_USAGE",t[t.CURRENT_VERTEX_ATTRIB=34342]="CURRENT_VERTEX_ATTRIB",t[t.VERTEX_ATTRIB_ARRAY_ENABLED=34338]="VERTEX_ATTRIB_ARRAY_ENABLED",t[t.VERTEX_ATTRIB_ARRAY_SIZE=34339]="VERTEX_ATTRIB_ARRAY_SIZE",t[t.VERTEX_ATTRIB_ARRAY_STRIDE=34340]="VERTEX_ATTRIB_ARRAY_STRIDE",t[t.VERTEX_ATTRIB_ARRAY_TYPE=34341]="VERTEX_ATTRIB_ARRAY_TYPE",t[t.VERTEX_ATTRIB_ARRAY_NORMALIZED=34922]="VERTEX_ATTRIB_ARRAY_NORMALIZED",t[t.VERTEX_ATTRIB_ARRAY_POINTER=34373]="VERTEX_ATTRIB_ARRAY_POINTER",t[t.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING=34975]="VERTEX_ATTRIB_ARRAY_BUFFER_BINDING",t[t.CULL_FACE=2884]="CULL_FACE",t[t.FRONT=1028]="FRONT",t[t.BACK=1029]="BACK",t[t.FRONT_AND_BACK=1032]="FRONT_AND_BACK",t[t.BLEND=3042]="BLEND",t[t.DEPTH_TEST=2929]="DEPTH_TEST",t[t.DITHER=3024]="DITHER",t[t.POLYGON_OFFSET_FILL=32823]="POLYGON_OFFSET_FILL",t[t.SAMPLE_ALPHA_TO_COVERAGE=32926]="SAMPLE_ALPHA_TO_COVERAGE",t[t.SAMPLE_COVERAGE=32928]="SAMPLE_COVERAGE",t[t.SCISSOR_TEST=3089]="SCISSOR_TEST",t[t.STENCIL_TEST=2960]="STENCIL_TEST",t[t.NO_ERROR=0]="NO_ERROR",t[t.INVALID_ENUM=1280]="INVALID_ENUM",t[t.INVALID_VALUE=1281]="INVALID_VALUE",t[t.INVALID_OPERATION=1282]="INVALID_OPERATION",t[t.OUT_OF_MEMORY=1285]="OUT_OF_MEMORY",t[t.CONTEXT_LOST_WEBGL=37442]="CONTEXT_LOST_WEBGL",t[t.CW=2304]="CW",t[t.CCW=2305]="CCW",t[t.DONT_CARE=4352]="DONT_CARE",t[t.FASTEST=4353]="FASTEST",t[t.NICEST=4354]="NICEST",t[t.GENERATE_MIPMAP_HINT=33170]="GENERATE_MIPMAP_HINT",t[t.BYTE=5120]="BYTE",t[t.UNSIGNED_BYTE=5121]="UNSIGNED_BYTE",t[t.SHORT=5122]="SHORT",t[t.UNSIGNED_SHORT=5123]="UNSIGNED_SHORT",t[t.INT=5124]="INT",t[t.UNSIGNED_INT=5125]="UNSIGNED_INT",t[t.FLOAT=5126]="FLOAT",t[t.DOUBLE=5130]="DOUBLE",t[t.DEPTH_COMPONENT=6402]="DEPTH_COMPONENT",t[t.ALPHA=6406]="ALPHA",t[t.RGB=6407]="RGB",t[t.RGBA=6408]="RGBA",t[t.LUMINANCE=6409]="LUMINANCE",t[t.LUMINANCE_ALPHA=6410]="LUMINANCE_ALPHA",t[t.UNSIGNED_SHORT_4_4_4_4=32819]="UNSIGNED_SHORT_4_4_4_4",t[t.UNSIGNED_SHORT_5_5_5_1=32820]="UNSIGNED_SHORT_5_5_5_1",t[t.UNSIGNED_SHORT_5_6_5=33635]="UNSIGNED_SHORT_5_6_5",t[t.FRAGMENT_SHADER=35632]="FRAGMENT_SHADER",t[t.VERTEX_SHADER=35633]="VERTEX_SHADER",t[t.COMPILE_STATUS=35713]="COMPILE_STATUS",t[t.DELETE_STATUS=35712]="DELETE_STATUS",t[t.LINK_STATUS=35714]="LINK_STATUS",t[t.VALIDATE_STATUS=35715]="VALIDATE_STATUS",t[t.ATTACHED_SHADERS=35717]="ATTACHED_SHADERS",t[t.ACTIVE_ATTRIBUTES=35721]="ACTIVE_ATTRIBUTES",t[t.ACTIVE_UNIFORMS=35718]="ACTIVE_UNIFORMS",t[t.MAX_VERTEX_ATTRIBS=34921]="MAX_VERTEX_ATTRIBS",t[t.MAX_VERTEX_UNIFORM_VECTORS=36347]="MAX_VERTEX_UNIFORM_VECTORS",t[t.MAX_VARYING_VECTORS=36348]="MAX_VARYING_VECTORS",t[t.MAX_COMBINED_TEXTURE_IMAGE_UNITS=35661]="MAX_COMBINED_TEXTURE_IMAGE_UNITS",t[t.MAX_VERTEX_TEXTURE_IMAGE_UNITS=35660]="MAX_VERTEX_TEXTURE_IMAGE_UNITS",t[t.MAX_TEXTURE_IMAGE_UNITS=34930]="MAX_TEXTURE_IMAGE_UNITS",t[t.MAX_FRAGMENT_UNIFORM_VECTORS=36349]="MAX_FRAGMENT_UNIFORM_VECTORS",t[t.SHADER_TYPE=35663]="SHADER_TYPE",t[t.SHADING_LANGUAGE_VERSION=35724]="SHADING_LANGUAGE_VERSION",t[t.CURRENT_PROGRAM=35725]="CURRENT_PROGRAM",t[t.NEVER=512]="NEVER",t[t.LESS=513]="LESS",t[t.EQUAL=514]="EQUAL",t[t.LEQUAL=515]="LEQUAL",t[t.GREATER=516]="GREATER",t[t.NOTEQUAL=517]="NOTEQUAL",t[t.GEQUAL=518]="GEQUAL",t[t.ALWAYS=519]="ALWAYS",t[t.KEEP=7680]="KEEP",t[t.REPLACE=7681]="REPLACE",t[t.INCR=7682]="INCR",t[t.DECR=7683]="DECR",t[t.INVERT=5386]="INVERT",t[t.INCR_WRAP=34055]="INCR_WRAP",t[t.DECR_WRAP=34056]="DECR_WRAP",t[t.NEAREST=9728]="NEAREST",t[t.LINEAR=9729]="LINEAR",t[t.NEAREST_MIPMAP_NEAREST=9984]="NEAREST_MIPMAP_NEAREST",t[t.LINEAR_MIPMAP_NEAREST=9985]="LINEAR_MIPMAP_NEAREST",t[t.NEAREST_MIPMAP_LINEAR=9986]="NEAREST_MIPMAP_LINEAR",t[t.LINEAR_MIPMAP_LINEAR=9987]="LINEAR_MIPMAP_LINEAR",t[t.TEXTURE_MAG_FILTER=10240]="TEXTURE_MAG_FILTER",t[t.TEXTURE_MIN_FILTER=10241]="TEXTURE_MIN_FILTER",t[t.TEXTURE_WRAP_S=10242]="TEXTURE_WRAP_S",t[t.TEXTURE_WRAP_T=10243]="TEXTURE_WRAP_T",t[t.TEXTURE_2D=3553]="TEXTURE_2D",t[t.TEXTURE=5890]="TEXTURE",t[t.TEXTURE_CUBE_MAP=34067]="TEXTURE_CUBE_MAP",t[t.TEXTURE_BINDING_CUBE_MAP=34068]="TEXTURE_BINDING_CUBE_MAP",t[t.TEXTURE_CUBE_MAP_POSITIVE_X=34069]="TEXTURE_CUBE_MAP_POSITIVE_X",t[t.TEXTURE_CUBE_MAP_NEGATIVE_X=34070]="TEXTURE_CUBE_MAP_NEGATIVE_X",t[t.TEXTURE_CUBE_MAP_POSITIVE_Y=34071]="TEXTURE_CUBE_MAP_POSITIVE_Y",t[t.TEXTURE_CUBE_MAP_NEGATIVE_Y=34072]="TEXTURE_CUBE_MAP_NEGATIVE_Y",t[t.TEXTURE_CUBE_MAP_POSITIVE_Z=34073]="TEXTURE_CUBE_MAP_POSITIVE_Z",t[t.TEXTURE_CUBE_MAP_NEGATIVE_Z=34074]="TEXTURE_CUBE_MAP_NEGATIVE_Z",t[t.MAX_CUBE_MAP_TEXTURE_SIZE=34076]="MAX_CUBE_MAP_TEXTURE_SIZE",t[t.TEXTURE0=33984]="TEXTURE0",t[t.ACTIVE_TEXTURE=34016]="ACTIVE_TEXTURE",t[t.REPEAT=10497]="REPEAT",t[t.CLAMP_TO_EDGE=33071]="CLAMP_TO_EDGE",t[t.MIRRORED_REPEAT=33648]="MIRRORED_REPEAT",t[t.TEXTURE_WIDTH=4096]="TEXTURE_WIDTH",t[t.TEXTURE_HEIGHT=4097]="TEXTURE_HEIGHT",t[t.FLOAT_VEC2=35664]="FLOAT_VEC2",t[t.FLOAT_VEC3=35665]="FLOAT_VEC3",t[t.FLOAT_VEC4=35666]="FLOAT_VEC4",t[t.INT_VEC2=35667]="INT_VEC2",t[t.INT_VEC3=35668]="INT_VEC3",t[t.INT_VEC4=35669]="INT_VEC4",t[t.BOOL=35670]="BOOL",t[t.BOOL_VEC2=35671]="BOOL_VEC2",t[t.BOOL_VEC3=35672]="BOOL_VEC3",t[t.BOOL_VEC4=35673]="BOOL_VEC4",t[t.FLOAT_MAT2=35674]="FLOAT_MAT2",t[t.FLOAT_MAT3=35675]="FLOAT_MAT3",t[t.FLOAT_MAT4=35676]="FLOAT_MAT4",t[t.SAMPLER_2D=35678]="SAMPLER_2D",t[t.SAMPLER_CUBE=35680]="SAMPLER_CUBE",t[t.LOW_FLOAT=36336]="LOW_FLOAT",t[t.MEDIUM_FLOAT=36337]="MEDIUM_FLOAT",t[t.HIGH_FLOAT=36338]="HIGH_FLOAT",t[t.LOW_INT=36339]="LOW_INT",t[t.MEDIUM_INT=36340]="MEDIUM_INT",t[t.HIGH_INT=36341]="HIGH_INT",t[t.FRAMEBUFFER=36160]="FRAMEBUFFER",t[t.RENDERBUFFER=36161]="RENDERBUFFER",t[t.RGBA4=32854]="RGBA4",t[t.RGB5_A1=32855]="RGB5_A1",t[t.RGB565=36194]="RGB565",t[t.DEPTH_COMPONENT16=33189]="DEPTH_COMPONENT16",t[t.STENCIL_INDEX=6401]="STENCIL_INDEX",t[t.STENCIL_INDEX8=36168]="STENCIL_INDEX8",t[t.DEPTH_STENCIL=34041]="DEPTH_STENCIL",t[t.RENDERBUFFER_WIDTH=36162]="RENDERBUFFER_WIDTH",t[t.RENDERBUFFER_HEIGHT=36163]="RENDERBUFFER_HEIGHT",t[t.RENDERBUFFER_INTERNAL_FORMAT=36164]="RENDERBUFFER_INTERNAL_FORMAT",t[t.RENDERBUFFER_RED_SIZE=36176]="RENDERBUFFER_RED_SIZE",t[t.RENDERBUFFER_GREEN_SIZE=36177]="RENDERBUFFER_GREEN_SIZE",t[t.RENDERBUFFER_BLUE_SIZE=36178]="RENDERBUFFER_BLUE_SIZE",t[t.RENDERBUFFER_ALPHA_SIZE=36179]="RENDERBUFFER_ALPHA_SIZE",t[t.RENDERBUFFER_DEPTH_SIZE=36180]="RENDERBUFFER_DEPTH_SIZE",t[t.RENDERBUFFER_STENCIL_SIZE=36181]="RENDERBUFFER_STENCIL_SIZE",t[t.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE=36048]="FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE",t[t.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME=36049]="FRAMEBUFFER_ATTACHMENT_OBJECT_NAME",t[t.FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL=36050]="FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL",t[t.FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE=36051]="FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE",t[t.COLOR_ATTACHMENT0=36064]="COLOR_ATTACHMENT0",t[t.DEPTH_ATTACHMENT=36096]="DEPTH_ATTACHMENT",t[t.STENCIL_ATTACHMENT=36128]="STENCIL_ATTACHMENT",t[t.DEPTH_STENCIL_ATTACHMENT=33306]="DEPTH_STENCIL_ATTACHMENT",t[t.NONE=0]="NONE",t[t.FRAMEBUFFER_COMPLETE=36053]="FRAMEBUFFER_COMPLETE",t[t.FRAMEBUFFER_INCOMPLETE_ATTACHMENT=36054]="FRAMEBUFFER_INCOMPLETE_ATTACHMENT",t[t.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT=36055]="FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT",t[t.FRAMEBUFFER_INCOMPLETE_DIMENSIONS=36057]="FRAMEBUFFER_INCOMPLETE_DIMENSIONS",t[t.FRAMEBUFFER_UNSUPPORTED=36061]="FRAMEBUFFER_UNSUPPORTED",t[t.FRAMEBUFFER_BINDING=36006]="FRAMEBUFFER_BINDING",t[t.RENDERBUFFER_BINDING=36007]="RENDERBUFFER_BINDING",t[t.READ_FRAMEBUFFER=36008]="READ_FRAMEBUFFER",t[t.DRAW_FRAMEBUFFER=36009]="DRAW_FRAMEBUFFER",t[t.MAX_RENDERBUFFER_SIZE=34024]="MAX_RENDERBUFFER_SIZE",t[t.INVALID_FRAMEBUFFER_OPERATION=1286]="INVALID_FRAMEBUFFER_OPERATION",t[t.UNPACK_FLIP_Y_WEBGL=37440]="UNPACK_FLIP_Y_WEBGL",t[t.UNPACK_PREMULTIPLY_ALPHA_WEBGL=37441]="UNPACK_PREMULTIPLY_ALPHA_WEBGL",t[t.UNPACK_COLORSPACE_CONVERSION_WEBGL=37443]="UNPACK_COLORSPACE_CONVERSION_WEBGL",t[t.READ_BUFFER=3074]="READ_BUFFER",t[t.UNPACK_ROW_LENGTH=3314]="UNPACK_ROW_LENGTH",t[t.UNPACK_SKIP_ROWS=3315]="UNPACK_SKIP_ROWS",t[t.UNPACK_SKIP_PIXELS=3316]="UNPACK_SKIP_PIXELS",t[t.PACK_ROW_LENGTH=3330]="PACK_ROW_LENGTH",t[t.PACK_SKIP_ROWS=3331]="PACK_SKIP_ROWS",t[t.PACK_SKIP_PIXELS=3332]="PACK_SKIP_PIXELS",t[t.TEXTURE_BINDING_3D=32874]="TEXTURE_BINDING_3D",t[t.UNPACK_SKIP_IMAGES=32877]="UNPACK_SKIP_IMAGES",t[t.UNPACK_IMAGE_HEIGHT=32878]="UNPACK_IMAGE_HEIGHT",t[t.MAX_3D_TEXTURE_SIZE=32883]="MAX_3D_TEXTURE_SIZE",t[t.MAX_ELEMENTS_VERTICES=33e3]="MAX_ELEMENTS_VERTICES",t[t.MAX_ELEMENTS_INDICES=33001]="MAX_ELEMENTS_INDICES",t[t.MAX_TEXTURE_LOD_BIAS=34045]="MAX_TEXTURE_LOD_BIAS",t[t.MAX_FRAGMENT_UNIFORM_COMPONENTS=35657]="MAX_FRAGMENT_UNIFORM_COMPONENTS",t[t.MAX_VERTEX_UNIFORM_COMPONENTS=35658]="MAX_VERTEX_UNIFORM_COMPONENTS",t[t.MAX_ARRAY_TEXTURE_LAYERS=35071]="MAX_ARRAY_TEXTURE_LAYERS",t[t.MIN_PROGRAM_TEXEL_OFFSET=35076]="MIN_PROGRAM_TEXEL_OFFSET",t[t.MAX_PROGRAM_TEXEL_OFFSET=35077]="MAX_PROGRAM_TEXEL_OFFSET",t[t.MAX_VARYING_COMPONENTS=35659]="MAX_VARYING_COMPONENTS",t[t.FRAGMENT_SHADER_DERIVATIVE_HINT=35723]="FRAGMENT_SHADER_DERIVATIVE_HINT",t[t.RASTERIZER_DISCARD=35977]="RASTERIZER_DISCARD",t[t.VERTEX_ARRAY_BINDING=34229]="VERTEX_ARRAY_BINDING",t[t.MAX_VERTEX_OUTPUT_COMPONENTS=37154]="MAX_VERTEX_OUTPUT_COMPONENTS",t[t.MAX_FRAGMENT_INPUT_COMPONENTS=37157]="MAX_FRAGMENT_INPUT_COMPONENTS",t[t.MAX_SERVER_WAIT_TIMEOUT=37137]="MAX_SERVER_WAIT_TIMEOUT",t[t.MAX_ELEMENT_INDEX=36203]="MAX_ELEMENT_INDEX",t[t.RED=6403]="RED",t[t.RGB8=32849]="RGB8",t[t.RGBA8=32856]="RGBA8",t[t.RGB10_A2=32857]="RGB10_A2",t[t.TEXTURE_3D=32879]="TEXTURE_3D",t[t.TEXTURE_WRAP_R=32882]="TEXTURE_WRAP_R",t[t.TEXTURE_MIN_LOD=33082]="TEXTURE_MIN_LOD",t[t.TEXTURE_MAX_LOD=33083]="TEXTURE_MAX_LOD",t[t.TEXTURE_BASE_LEVEL=33084]="TEXTURE_BASE_LEVEL",t[t.TEXTURE_MAX_LEVEL=33085]="TEXTURE_MAX_LEVEL",t[t.TEXTURE_COMPARE_MODE=34892]="TEXTURE_COMPARE_MODE",t[t.TEXTURE_COMPARE_FUNC=34893]="TEXTURE_COMPARE_FUNC",t[t.SRGB=35904]="SRGB",t[t.SRGB8=35905]="SRGB8",t[t.SRGB8_ALPHA8=35907]="SRGB8_ALPHA8",t[t.COMPARE_REF_TO_TEXTURE=34894]="COMPARE_REF_TO_TEXTURE",t[t.RGBA32F=34836]="RGBA32F",t[t.RGB32F=34837]="RGB32F",t[t.RGBA16F=34842]="RGBA16F",t[t.RGB16F=34843]="RGB16F",t[t.TEXTURE_2D_ARRAY=35866]="TEXTURE_2D_ARRAY",t[t.TEXTURE_BINDING_2D_ARRAY=35869]="TEXTURE_BINDING_2D_ARRAY",t[t.R11F_G11F_B10F=35898]="R11F_G11F_B10F",t[t.RGB9_E5=35901]="RGB9_E5",t[t.RGBA32UI=36208]="RGBA32UI",t[t.RGB32UI=36209]="RGB32UI",t[t.RGBA16UI=36214]="RGBA16UI",t[t.RGB16UI=36215]="RGB16UI",t[t.RGBA8UI=36220]="RGBA8UI",t[t.RGB8UI=36221]="RGB8UI",t[t.RGBA32I=36226]="RGBA32I",t[t.RGB32I=36227]="RGB32I",t[t.RGBA16I=36232]="RGBA16I",t[t.RGB16I=36233]="RGB16I",t[t.RGBA8I=36238]="RGBA8I",t[t.RGB8I=36239]="RGB8I",t[t.RED_INTEGER=36244]="RED_INTEGER",t[t.RGB_INTEGER=36248]="RGB_INTEGER",t[t.RGBA_INTEGER=36249]="RGBA_INTEGER",t[t.R8=33321]="R8",t[t.RG8=33323]="RG8",t[t.R16F=33325]="R16F",t[t.R32F=33326]="R32F",t[t.RG16F=33327]="RG16F",t[t.RG32F=33328]="RG32F",t[t.R8I=33329]="R8I",t[t.R8UI=33330]="R8UI",t[t.R16I=33331]="R16I",t[t.R16UI=33332]="R16UI",t[t.R32I=33333]="R32I",t[t.R32UI=33334]="R32UI",t[t.RG8I=33335]="RG8I",t[t.RG8UI=33336]="RG8UI",t[t.RG16I=33337]="RG16I",t[t.RG16UI=33338]="RG16UI",t[t.RG32I=33339]="RG32I",t[t.RG32UI=33340]="RG32UI",t[t.R8_SNORM=36756]="R8_SNORM",t[t.RG8_SNORM=36757]="RG8_SNORM",t[t.RGB8_SNORM=36758]="RGB8_SNORM",t[t.RGBA8_SNORM=36759]="RGBA8_SNORM",t[t.RGB10_A2UI=36975]="RGB10_A2UI",t[t.TEXTURE_IMMUTABLE_FORMAT=37167]="TEXTURE_IMMUTABLE_FORMAT",t[t.TEXTURE_IMMUTABLE_LEVELS=33503]="TEXTURE_IMMUTABLE_LEVELS",t[t.UNSIGNED_INT_2_10_10_10_REV=33640]="UNSIGNED_INT_2_10_10_10_REV",t[t.UNSIGNED_INT_10F_11F_11F_REV=35899]="UNSIGNED_INT_10F_11F_11F_REV",t[t.UNSIGNED_INT_5_9_9_9_REV=35902]="UNSIGNED_INT_5_9_9_9_REV",t[t.FLOAT_32_UNSIGNED_INT_24_8_REV=36269]="FLOAT_32_UNSIGNED_INT_24_8_REV",t[t.UNSIGNED_INT_24_8=34042]="UNSIGNED_INT_24_8",t[t.HALF_FLOAT=5131]="HALF_FLOAT",t[t.RG=33319]="RG",t[t.RG_INTEGER=33320]="RG_INTEGER",t[t.INT_2_10_10_10_REV=36255]="INT_2_10_10_10_REV",t[t.CURRENT_QUERY=34917]="CURRENT_QUERY",t[t.QUERY_RESULT=34918]="QUERY_RESULT",t[t.QUERY_RESULT_AVAILABLE=34919]="QUERY_RESULT_AVAILABLE",t[t.ANY_SAMPLES_PASSED=35887]="ANY_SAMPLES_PASSED",t[t.ANY_SAMPLES_PASSED_CONSERVATIVE=36202]="ANY_SAMPLES_PASSED_CONSERVATIVE",t[t.MAX_DRAW_BUFFERS=34852]="MAX_DRAW_BUFFERS",t[t.DRAW_BUFFER0=34853]="DRAW_BUFFER0",t[t.DRAW_BUFFER1=34854]="DRAW_BUFFER1",t[t.DRAW_BUFFER2=34855]="DRAW_BUFFER2",t[t.DRAW_BUFFER3=34856]="DRAW_BUFFER3",t[t.DRAW_BUFFER4=34857]="DRAW_BUFFER4",t[t.DRAW_BUFFER5=34858]="DRAW_BUFFER5",t[t.DRAW_BUFFER6=34859]="DRAW_BUFFER6",t[t.DRAW_BUFFER7=34860]="DRAW_BUFFER7",t[t.DRAW_BUFFER8=34861]="DRAW_BUFFER8",t[t.DRAW_BUFFER9=34862]="DRAW_BUFFER9",t[t.DRAW_BUFFER10=34863]="DRAW_BUFFER10",t[t.DRAW_BUFFER11=34864]="DRAW_BUFFER11",t[t.DRAW_BUFFER12=34865]="DRAW_BUFFER12",t[t.DRAW_BUFFER13=34866]="DRAW_BUFFER13",t[t.DRAW_BUFFER14=34867]="DRAW_BUFFER14",t[t.DRAW_BUFFER15=34868]="DRAW_BUFFER15",t[t.MAX_COLOR_ATTACHMENTS=36063]="MAX_COLOR_ATTACHMENTS",t[t.COLOR_ATTACHMENT1=36065]="COLOR_ATTACHMENT1",t[t.COLOR_ATTACHMENT2=36066]="COLOR_ATTACHMENT2",t[t.COLOR_ATTACHMENT3=36067]="COLOR_ATTACHMENT3",t[t.COLOR_ATTACHMENT4=36068]="COLOR_ATTACHMENT4",t[t.COLOR_ATTACHMENT5=36069]="COLOR_ATTACHMENT5",t[t.COLOR_ATTACHMENT6=36070]="COLOR_ATTACHMENT6",t[t.COLOR_ATTACHMENT7=36071]="COLOR_ATTACHMENT7",t[t.COLOR_ATTACHMENT8=36072]="COLOR_ATTACHMENT8",t[t.COLOR_ATTACHMENT9=36073]="COLOR_ATTACHMENT9",t[t.COLOR_ATTACHMENT10=36074]="COLOR_ATTACHMENT10",t[t.COLOR_ATTACHMENT11=36075]="COLOR_ATTACHMENT11",t[t.COLOR_ATTACHMENT12=36076]="COLOR_ATTACHMENT12",t[t.COLOR_ATTACHMENT13=36077]="COLOR_ATTACHMENT13",t[t.COLOR_ATTACHMENT14=36078]="COLOR_ATTACHMENT14",t[t.COLOR_ATTACHMENT15=36079]="COLOR_ATTACHMENT15",t[t.SAMPLER_3D=35679]="SAMPLER_3D",t[t.SAMPLER_2D_SHADOW=35682]="SAMPLER_2D_SHADOW",t[t.SAMPLER_2D_ARRAY=36289]="SAMPLER_2D_ARRAY",t[t.SAMPLER_2D_ARRAY_SHADOW=36292]="SAMPLER_2D_ARRAY_SHADOW",t[t.SAMPLER_CUBE_SHADOW=36293]="SAMPLER_CUBE_SHADOW",t[t.INT_SAMPLER_2D=36298]="INT_SAMPLER_2D",t[t.INT_SAMPLER_3D=36299]="INT_SAMPLER_3D",t[t.INT_SAMPLER_CUBE=36300]="INT_SAMPLER_CUBE",t[t.INT_SAMPLER_2D_ARRAY=36303]="INT_SAMPLER_2D_ARRAY",t[t.UNSIGNED_INT_SAMPLER_2D=36306]="UNSIGNED_INT_SAMPLER_2D",t[t.UNSIGNED_INT_SAMPLER_3D=36307]="UNSIGNED_INT_SAMPLER_3D",t[t.UNSIGNED_INT_SAMPLER_CUBE=36308]="UNSIGNED_INT_SAMPLER_CUBE",t[t.UNSIGNED_INT_SAMPLER_2D_ARRAY=36311]="UNSIGNED_INT_SAMPLER_2D_ARRAY",t[t.MAX_SAMPLES=36183]="MAX_SAMPLES",t[t.SAMPLER_BINDING=35097]="SAMPLER_BINDING",t[t.PIXEL_PACK_BUFFER=35051]="PIXEL_PACK_BUFFER",t[t.PIXEL_UNPACK_BUFFER=35052]="PIXEL_UNPACK_BUFFER",t[t.PIXEL_PACK_BUFFER_BINDING=35053]="PIXEL_PACK_BUFFER_BINDING",t[t.PIXEL_UNPACK_BUFFER_BINDING=35055]="PIXEL_UNPACK_BUFFER_BINDING",t[t.COPY_READ_BUFFER=36662]="COPY_READ_BUFFER",t[t.COPY_WRITE_BUFFER=36663]="COPY_WRITE_BUFFER",t[t.COPY_READ_BUFFER_BINDING=36662]="COPY_READ_BUFFER_BINDING",t[t.COPY_WRITE_BUFFER_BINDING=36663]="COPY_WRITE_BUFFER_BINDING",t[t.FLOAT_MAT2x3=35685]="FLOAT_MAT2x3",t[t.FLOAT_MAT2x4=35686]="FLOAT_MAT2x4",t[t.FLOAT_MAT3x2=35687]="FLOAT_MAT3x2",t[t.FLOAT_MAT3x4=35688]="FLOAT_MAT3x4",t[t.FLOAT_MAT4x2=35689]="FLOAT_MAT4x2",t[t.FLOAT_MAT4x3=35690]="FLOAT_MAT4x3",t[t.UNSIGNED_INT_VEC2=36294]="UNSIGNED_INT_VEC2",t[t.UNSIGNED_INT_VEC3=36295]="UNSIGNED_INT_VEC3",t[t.UNSIGNED_INT_VEC4=36296]="UNSIGNED_INT_VEC4",t[t.UNSIGNED_NORMALIZED=35863]="UNSIGNED_NORMALIZED",t[t.SIGNED_NORMALIZED=36764]="SIGNED_NORMALIZED",t[t.VERTEX_ATTRIB_ARRAY_INTEGER=35069]="VERTEX_ATTRIB_ARRAY_INTEGER",t[t.VERTEX_ATTRIB_ARRAY_DIVISOR=35070]="VERTEX_ATTRIB_ARRAY_DIVISOR",t[t.TRANSFORM_FEEDBACK_BUFFER_MODE=35967]="TRANSFORM_FEEDBACK_BUFFER_MODE",t[t.MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS=35968]="MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS",t[t.TRANSFORM_FEEDBACK_VARYINGS=35971]="TRANSFORM_FEEDBACK_VARYINGS",t[t.TRANSFORM_FEEDBACK_BUFFER_START=35972]="TRANSFORM_FEEDBACK_BUFFER_START",t[t.TRANSFORM_FEEDBACK_BUFFER_SIZE=35973]="TRANSFORM_FEEDBACK_BUFFER_SIZE",t[t.TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN=35976]="TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN",t[t.MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS=35978]="MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS",t[t.MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS=35979]="MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS",t[t.INTERLEAVED_ATTRIBS=35980]="INTERLEAVED_ATTRIBS",t[t.SEPARATE_ATTRIBS=35981]="SEPARATE_ATTRIBS",t[t.TRANSFORM_FEEDBACK_BUFFER=35982]="TRANSFORM_FEEDBACK_BUFFER",t[t.TRANSFORM_FEEDBACK_BUFFER_BINDING=35983]="TRANSFORM_FEEDBACK_BUFFER_BINDING",t[t.TRANSFORM_FEEDBACK=36386]="TRANSFORM_FEEDBACK",t[t.TRANSFORM_FEEDBACK_PAUSED=36387]="TRANSFORM_FEEDBACK_PAUSED",t[t.TRANSFORM_FEEDBACK_ACTIVE=36388]="TRANSFORM_FEEDBACK_ACTIVE",t[t.TRANSFORM_FEEDBACK_BINDING=36389]="TRANSFORM_FEEDBACK_BINDING",t[t.FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING=33296]="FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING",t[t.FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE=33297]="FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE",t[t.FRAMEBUFFER_ATTACHMENT_RED_SIZE=33298]="FRAMEBUFFER_ATTACHMENT_RED_SIZE",t[t.FRAMEBUFFER_ATTACHMENT_GREEN_SIZE=33299]="FRAMEBUFFER_ATTACHMENT_GREEN_SIZE",t[t.FRAMEBUFFER_ATTACHMENT_BLUE_SIZE=33300]="FRAMEBUFFER_ATTACHMENT_BLUE_SIZE",t[t.FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE=33301]="FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE",t[t.FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE=33302]="FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE",t[t.FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE=33303]="FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE",t[t.FRAMEBUFFER_DEFAULT=33304]="FRAMEBUFFER_DEFAULT",t[t.DEPTH24_STENCIL8=35056]="DEPTH24_STENCIL8",t[t.DRAW_FRAMEBUFFER_BINDING=36006]="DRAW_FRAMEBUFFER_BINDING",t[t.READ_FRAMEBUFFER_BINDING=36010]="READ_FRAMEBUFFER_BINDING",t[t.RENDERBUFFER_SAMPLES=36011]="RENDERBUFFER_SAMPLES",t[t.FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER=36052]="FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER",t[t.FRAMEBUFFER_INCOMPLETE_MULTISAMPLE=36182]="FRAMEBUFFER_INCOMPLETE_MULTISAMPLE",t[t.UNIFORM_BUFFER=35345]="UNIFORM_BUFFER",t[t.UNIFORM_BUFFER_BINDING=35368]="UNIFORM_BUFFER_BINDING",t[t.UNIFORM_BUFFER_START=35369]="UNIFORM_BUFFER_START",t[t.UNIFORM_BUFFER_SIZE=35370]="UNIFORM_BUFFER_SIZE",t[t.MAX_VERTEX_UNIFORM_BLOCKS=35371]="MAX_VERTEX_UNIFORM_BLOCKS",t[t.MAX_FRAGMENT_UNIFORM_BLOCKS=35373]="MAX_FRAGMENT_UNIFORM_BLOCKS",t[t.MAX_COMBINED_UNIFORM_BLOCKS=35374]="MAX_COMBINED_UNIFORM_BLOCKS",t[t.MAX_UNIFORM_BUFFER_BINDINGS=35375]="MAX_UNIFORM_BUFFER_BINDINGS",t[t.MAX_UNIFORM_BLOCK_SIZE=35376]="MAX_UNIFORM_BLOCK_SIZE",t[t.MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS=35377]="MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS",t[t.MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS=35379]="MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS",t[t.UNIFORM_BUFFER_OFFSET_ALIGNMENT=35380]="UNIFORM_BUFFER_OFFSET_ALIGNMENT",t[t.ACTIVE_UNIFORM_BLOCKS=35382]="ACTIVE_UNIFORM_BLOCKS",t[t.UNIFORM_TYPE=35383]="UNIFORM_TYPE",t[t.UNIFORM_SIZE=35384]="UNIFORM_SIZE",t[t.UNIFORM_BLOCK_INDEX=35386]="UNIFORM_BLOCK_INDEX",t[t.UNIFORM_OFFSET=35387]="UNIFORM_OFFSET",t[t.UNIFORM_ARRAY_STRIDE=35388]="UNIFORM_ARRAY_STRIDE",t[t.UNIFORM_MATRIX_STRIDE=35389]="UNIFORM_MATRIX_STRIDE",t[t.UNIFORM_IS_ROW_MAJOR=35390]="UNIFORM_IS_ROW_MAJOR",t[t.UNIFORM_BLOCK_BINDING=35391]="UNIFORM_BLOCK_BINDING",t[t.UNIFORM_BLOCK_DATA_SIZE=35392]="UNIFORM_BLOCK_DATA_SIZE",t[t.UNIFORM_BLOCK_ACTIVE_UNIFORMS=35394]="UNIFORM_BLOCK_ACTIVE_UNIFORMS",t[t.UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES=35395]="UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES",t[t.UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER=35396]="UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER",t[t.UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER=35398]="UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER",t[t.OBJECT_TYPE=37138]="OBJECT_TYPE",t[t.SYNC_CONDITION=37139]="SYNC_CONDITION",t[t.SYNC_STATUS=37140]="SYNC_STATUS",t[t.SYNC_FLAGS=37141]="SYNC_FLAGS",t[t.SYNC_FENCE=37142]="SYNC_FENCE",t[t.SYNC_GPU_COMMANDS_COMPLETE=37143]="SYNC_GPU_COMMANDS_COMPLETE",t[t.UNSIGNALED=37144]="UNSIGNALED",t[t.SIGNALED=37145]="SIGNALED",t[t.ALREADY_SIGNALED=37146]="ALREADY_SIGNALED",t[t.TIMEOUT_EXPIRED=37147]="TIMEOUT_EXPIRED",t[t.CONDITION_SATISFIED=37148]="CONDITION_SATISFIED",t[t.WAIT_FAILED=37149]="WAIT_FAILED",t[t.SYNC_FLUSH_COMMANDS_BIT=1]="SYNC_FLUSH_COMMANDS_BIT",t[t.COLOR=6144]="COLOR",t[t.DEPTH=6145]="DEPTH",t[t.STENCIL=6146]="STENCIL",t[t.MIN=32775]="MIN",t[t.MAX=32776]="MAX",t[t.DEPTH_COMPONENT24=33190]="DEPTH_COMPONENT24",t[t.STREAM_READ=35041]="STREAM_READ",t[t.STREAM_COPY=35042]="STREAM_COPY",t[t.STATIC_READ=35045]="STATIC_READ",t[t.STATIC_COPY=35046]="STATIC_COPY",t[t.DYNAMIC_READ=35049]="DYNAMIC_READ",t[t.DYNAMIC_COPY=35050]="DYNAMIC_COPY",t[t.DEPTH_COMPONENT32F=36012]="DEPTH_COMPONENT32F",t[t.DEPTH32F_STENCIL8=36013]="DEPTH32F_STENCIL8",t[t.INVALID_INDEX=4294967295]="INVALID_INDEX",t[t.TIMEOUT_IGNORED=-1]="TIMEOUT_IGNORED",t[t.MAX_CLIENT_WAIT_TIMEOUT_WEBGL=37447]="MAX_CLIENT_WAIT_TIMEOUT_WEBGL",t[t.UNMASKED_VENDOR_WEBGL=37445]="UNMASKED_VENDOR_WEBGL",t[t.UNMASKED_RENDERER_WEBGL=37446]="UNMASKED_RENDERER_WEBGL",t[t.MAX_TEXTURE_MAX_ANISOTROPY_EXT=34047]="MAX_TEXTURE_MAX_ANISOTROPY_EXT",t[t.TEXTURE_MAX_ANISOTROPY_EXT=34046]="TEXTURE_MAX_ANISOTROPY_EXT",t[t.R16_EXT=33322]="R16_EXT",t[t.RG16_EXT=33324]="RG16_EXT",t[t.RGB16_EXT=32852]="RGB16_EXT",t[t.RGBA16_EXT=32859]="RGBA16_EXT",t[t.R16_SNORM_EXT=36760]="R16_SNORM_EXT",t[t.RG16_SNORM_EXT=36761]="RG16_SNORM_EXT",t[t.RGB16_SNORM_EXT=36762]="RGB16_SNORM_EXT",t[t.RGBA16_SNORM_EXT=36763]="RGBA16_SNORM_EXT",t[t.COMPRESSED_RGB_S3TC_DXT1_EXT=33776]="COMPRESSED_RGB_S3TC_DXT1_EXT",t[t.COMPRESSED_RGBA_S3TC_DXT1_EXT=33777]="COMPRESSED_RGBA_S3TC_DXT1_EXT",t[t.COMPRESSED_RGBA_S3TC_DXT3_EXT=33778]="COMPRESSED_RGBA_S3TC_DXT3_EXT",t[t.COMPRESSED_RGBA_S3TC_DXT5_EXT=33779]="COMPRESSED_RGBA_S3TC_DXT5_EXT",t[t.COMPRESSED_SRGB_S3TC_DXT1_EXT=35916]="COMPRESSED_SRGB_S3TC_DXT1_EXT",t[t.COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT=35917]="COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT",t[t.COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT=35918]="COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT",t[t.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT=35919]="COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT",t[t.COMPRESSED_RED_RGTC1_EXT=36283]="COMPRESSED_RED_RGTC1_EXT",t[t.COMPRESSED_SIGNED_RED_RGTC1_EXT=36284]="COMPRESSED_SIGNED_RED_RGTC1_EXT",t[t.COMPRESSED_RED_GREEN_RGTC2_EXT=36285]="COMPRESSED_RED_GREEN_RGTC2_EXT",t[t.COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT=36286]="COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT",t[t.COMPRESSED_RGBA_BPTC_UNORM_EXT=36492]="COMPRESSED_RGBA_BPTC_UNORM_EXT",t[t.COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT=36493]="COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT",t[t.COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT=36494]="COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT",t[t.COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT=36495]="COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT",t[t.COMPRESSED_R11_EAC=37488]="COMPRESSED_R11_EAC",t[t.COMPRESSED_SIGNED_R11_EAC=37489]="COMPRESSED_SIGNED_R11_EAC",t[t.COMPRESSED_RG11_EAC=37490]="COMPRESSED_RG11_EAC",t[t.COMPRESSED_SIGNED_RG11_EAC=37491]="COMPRESSED_SIGNED_RG11_EAC",t[t.COMPRESSED_RGB8_ETC2=37492]="COMPRESSED_RGB8_ETC2",t[t.COMPRESSED_RGBA8_ETC2_EAC=37493]="COMPRESSED_RGBA8_ETC2_EAC",t[t.COMPRESSED_SRGB8_ETC2=37494]="COMPRESSED_SRGB8_ETC2",t[t.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC=37495]="COMPRESSED_SRGB8_ALPHA8_ETC2_EAC",t[t.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2=37496]="COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2",t[t.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2=37497]="COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2",t[t.COMPRESSED_RGB_PVRTC_4BPPV1_IMG=35840]="COMPRESSED_RGB_PVRTC_4BPPV1_IMG",t[t.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG=35842]="COMPRESSED_RGBA_PVRTC_4BPPV1_IMG",t[t.COMPRESSED_RGB_PVRTC_2BPPV1_IMG=35841]="COMPRESSED_RGB_PVRTC_2BPPV1_IMG",t[t.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG=35843]="COMPRESSED_RGBA_PVRTC_2BPPV1_IMG",t[t.COMPRESSED_RGB_ETC1_WEBGL=36196]="COMPRESSED_RGB_ETC1_WEBGL",t[t.COMPRESSED_RGB_ATC_WEBGL=35986]="COMPRESSED_RGB_ATC_WEBGL",t[t.COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL=35986]="COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL",t[t.COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL=34798]="COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL",t[t.COMPRESSED_RGBA_ASTC_4x4_KHR=37808]="COMPRESSED_RGBA_ASTC_4x4_KHR",t[t.COMPRESSED_RGBA_ASTC_5x4_KHR=37809]="COMPRESSED_RGBA_ASTC_5x4_KHR",t[t.COMPRESSED_RGBA_ASTC_5x5_KHR=37810]="COMPRESSED_RGBA_ASTC_5x5_KHR",t[t.COMPRESSED_RGBA_ASTC_6x5_KHR=37811]="COMPRESSED_RGBA_ASTC_6x5_KHR",t[t.COMPRESSED_RGBA_ASTC_6x6_KHR=37812]="COMPRESSED_RGBA_ASTC_6x6_KHR",t[t.COMPRESSED_RGBA_ASTC_8x5_KHR=37813]="COMPRESSED_RGBA_ASTC_8x5_KHR",t[t.COMPRESSED_RGBA_ASTC_8x6_KHR=37814]="COMPRESSED_RGBA_ASTC_8x6_KHR",t[t.COMPRESSED_RGBA_ASTC_8x8_KHR=37815]="COMPRESSED_RGBA_ASTC_8x8_KHR",t[t.COMPRESSED_RGBA_ASTC_10x5_KHR=37816]="COMPRESSED_RGBA_ASTC_10x5_KHR",t[t.COMPRESSED_RGBA_ASTC_10x6_KHR=37817]="COMPRESSED_RGBA_ASTC_10x6_KHR",t[t.COMPRESSED_RGBA_ASTC_10x8_KHR=37818]="COMPRESSED_RGBA_ASTC_10x8_KHR",t[t.COMPRESSED_RGBA_ASTC_10x10_KHR=37819]="COMPRESSED_RGBA_ASTC_10x10_KHR",t[t.COMPRESSED_RGBA_ASTC_12x10_KHR=37820]="COMPRESSED_RGBA_ASTC_12x10_KHR",t[t.COMPRESSED_RGBA_ASTC_12x12_KHR=37821]="COMPRESSED_RGBA_ASTC_12x12_KHR",t[t.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR=37840]="COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR",t[t.COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR=37841]="COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR",t[t.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR=37842]="COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR",t[t.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR=37843]="COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR",t[t.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR=37844]="COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR",t[t.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR=37845]="COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR",t[t.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR=37846]="COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR",t[t.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR=37847]="COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR",t[t.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR=37848]="COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR",t[t.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR=37849]="COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR",t[t.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR=37850]="COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR",t[t.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR=37851]="COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR",t[t.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR=37852]="COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR",t[t.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR=37853]="COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR",t[t.QUERY_COUNTER_BITS_EXT=34916]="QUERY_COUNTER_BITS_EXT",t[t.CURRENT_QUERY_EXT=34917]="CURRENT_QUERY_EXT",t[t.QUERY_RESULT_EXT=34918]="QUERY_RESULT_EXT",t[t.QUERY_RESULT_AVAILABLE_EXT=34919]="QUERY_RESULT_AVAILABLE_EXT",t[t.TIME_ELAPSED_EXT=35007]="TIME_ELAPSED_EXT",t[t.TIMESTAMP_EXT=36392]="TIMESTAMP_EXT",t[t.GPU_DISJOINT_EXT=36795]="GPU_DISJOINT_EXT",t[t.COMPLETION_STATUS_KHR=37297]="COMPLETION_STATUS_KHR",t[t.DEPTH_CLAMP_EXT=34383]="DEPTH_CLAMP_EXT",t[t.FIRST_VERTEX_CONVENTION_WEBGL=36429]="FIRST_VERTEX_CONVENTION_WEBGL",t[t.LAST_VERTEX_CONVENTION_WEBGL=36430]="LAST_VERTEX_CONVENTION_WEBGL",t[t.PROVOKING_VERTEX_WEBL=36431]="PROVOKING_VERTEX_WEBL",t[t.POLYGON_MODE_WEBGL=2880]="POLYGON_MODE_WEBGL",t[t.POLYGON_OFFSET_LINE_WEBGL=10754]="POLYGON_OFFSET_LINE_WEBGL",t[t.LINE_WEBGL=6913]="LINE_WEBGL",t[t.FILL_WEBGL=6914]="FILL_WEBGL",t[t.MAX_CLIP_DISTANCES_WEBGL=3378]="MAX_CLIP_DISTANCES_WEBGL",t[t.MAX_CULL_DISTANCES_WEBGL=33529]="MAX_CULL_DISTANCES_WEBGL",t[t.MAX_COMBINED_CLIP_AND_CULL_DISTANCES_WEBGL=33530]="MAX_COMBINED_CLIP_AND_CULL_DISTANCES_WEBGL",t[t.CLIP_DISTANCE0_WEBGL=12288]="CLIP_DISTANCE0_WEBGL",t[t.CLIP_DISTANCE1_WEBGL=12289]="CLIP_DISTANCE1_WEBGL",t[t.CLIP_DISTANCE2_WEBGL=12290]="CLIP_DISTANCE2_WEBGL",t[t.CLIP_DISTANCE3_WEBGL=12291]="CLIP_DISTANCE3_WEBGL",t[t.CLIP_DISTANCE4_WEBGL=12292]="CLIP_DISTANCE4_WEBGL",t[t.CLIP_DISTANCE5_WEBGL=12293]="CLIP_DISTANCE5_WEBGL",t[t.CLIP_DISTANCE6_WEBGL=12294]="CLIP_DISTANCE6_WEBGL",t[t.CLIP_DISTANCE7_WEBGL=12295]="CLIP_DISTANCE7_WEBGL",t[t.POLYGON_OFFSET_CLAMP_EXT=36379]="POLYGON_OFFSET_CLAMP_EXT",t[t.LOWER_LEFT_EXT=36001]="LOWER_LEFT_EXT",t[t.UPPER_LEFT_EXT=36002]="UPPER_LEFT_EXT",t[t.NEGATIVE_ONE_TO_ONE_EXT=37726]="NEGATIVE_ONE_TO_ONE_EXT",t[t.ZERO_TO_ONE_EXT=37727]="ZERO_TO_ONE_EXT",t[t.CLIP_ORIGIN_EXT=37724]="CLIP_ORIGIN_EXT",t[t.CLIP_DEPTH_MODE_EXT=37725]="CLIP_DEPTH_MODE_EXT",t[t.SRC1_COLOR_WEBGL=35065]="SRC1_COLOR_WEBGL",t[t.SRC1_ALPHA_WEBGL=34185]="SRC1_ALPHA_WEBGL",t[t.ONE_MINUS_SRC1_COLOR_WEBGL=35066]="ONE_MINUS_SRC1_COLOR_WEBGL",t[t.ONE_MINUS_SRC1_ALPHA_WEBGL=35067]="ONE_MINUS_SRC1_ALPHA_WEBGL",t[t.MAX_DUAL_SOURCE_DRAW_BUFFERS_WEBGL=35068]="MAX_DUAL_SOURCE_DRAW_BUFFERS_WEBGL",t[t.MIRROR_CLAMP_TO_EDGE_EXT=34627]="MIRROR_CLAMP_TO_EDGE_EXT"})(WA||(WA={}))});var Mj=Nt(()=>{ute()});var Ate=Vi((Rj,Bj)=>{(function(t,e){typeof Rj=="object"&&typeof Bj<"u"?Bj.exports=e():typeof define=="function"&&define.amd?define(e):(t=t||self,t.mapboxgl=e())})(Rj,function(){"use strict";var t,e,r;function i(n,o){if(!t)t=o;else if(!e)e=o;else{var s="var sharedChunk = {}; ("+t+")(sharedChunk); ("+e+")(sharedChunk);",c={};t(c),r=o(c),typeof window<"u"&&(r.workerUrl=window.URL.createObjectURL(new Blob([s],{type:"text/javascript"})))}}return i(["exports"],function(n){"use strict";function o(u,p){return u(p={exports:{}},p.exports),p.exports}var s=c;function c(u,p,_,R){this.cx=3*u,this.bx=3*(_-u)-this.cx,this.ax=1-this.cx-this.bx,this.cy=3*p,this.by=3*(R-p)-this.cy,this.ay=1-this.cy-this.by,this.p1x=u,this.p1y=R,this.p2x=_,this.p2y=R}c.prototype.sampleCurveX=function(u){return((this.ax*u+this.bx)*u+this.cx)*u},c.prototype.sampleCurveY=function(u){return((this.ay*u+this.by)*u+this.cy)*u},c.prototype.sampleCurveDerivativeX=function(u){return(3*this.ax*u+2*this.bx)*u+this.cx},c.prototype.solveCurveX=function(u,p){var _,R,j,$,J;for(p===void 0&&(p=1e-6),j=u,J=0;J<8;J++){if($=this.sampleCurveX(j)-u,Math.abs($)(R=1))return R;for(;_$?_=j:R=j,j=.5*(R-_)+_}return j},c.prototype.solve=function(u,p){return this.sampleCurveY(this.solveCurveX(u,p))};var f=g;function g(u,p){this.x=u,this.y=p}g.prototype={clone:function(){return new g(this.x,this.y)},add:function(u){return this.clone()._add(u)},sub:function(u){return this.clone()._sub(u)},multByPoint:function(u){return this.clone()._multByPoint(u)},divByPoint:function(u){return this.clone()._divByPoint(u)},mult:function(u){return this.clone()._mult(u)},div:function(u){return this.clone()._div(u)},rotate:function(u){return this.clone()._rotate(u)},rotateAround:function(u,p){return this.clone()._rotateAround(u,p)},matMult:function(u){return this.clone()._matMult(u)},unit:function(){return this.clone()._unit()},perp:function(){return this.clone()._perp()},round:function(){return this.clone()._round()},mag:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},equals:function(u){return this.x===u.x&&this.y===u.y},dist:function(u){return Math.sqrt(this.distSqr(u))},distSqr:function(u){var p=u.x-this.x,_=u.y-this.y;return p*p+_*_},angle:function(){return Math.atan2(this.y,this.x)},angleTo:function(u){return Math.atan2(this.y-u.y,this.x-u.x)},angleWith:function(u){return this.angleWithSep(u.x,u.y)},angleWithSep:function(u,p){return Math.atan2(this.x*p-this.y*u,this.x*u+this.y*p)},_matMult:function(u){var p=u[2]*this.x+u[3]*this.y;return this.x=u[0]*this.x+u[1]*this.y,this.y=p,this},_add:function(u){return this.x+=u.x,this.y+=u.y,this},_sub:function(u){return this.x-=u.x,this.y-=u.y,this},_mult:function(u){return this.x*=u,this.y*=u,this},_div:function(u){return this.x/=u,this.y/=u,this},_multByPoint:function(u){return this.x*=u.x,this.y*=u.y,this},_divByPoint:function(u){return this.x/=u.x,this.y/=u.y,this},_unit:function(){return this._div(this.mag()),this},_perp:function(){var u=this.y;return this.y=this.x,this.x=-u,this},_rotate:function(u){var p=Math.cos(u),_=Math.sin(u),R=_*this.x+p*this.y;return this.x=p*this.x-_*this.y,this.y=R,this},_rotateAround:function(u,p){var _=Math.cos(u),R=Math.sin(u),j=p.y+R*(this.x-p.x)+_*(this.y-p.y);return this.x=p.x+_*(this.x-p.x)-R*(this.y-p.y),this.y=j,this},_round:function(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this}},g.convert=function(u){return u instanceof g?u:Array.isArray(u)?new g(u[0],u[1]):u};var y=typeof self<"u"?self:{},I=Math.pow(2,53)-1;function F(u,p,_,R){var j=new s(u,p,_,R);return function($){return j.solve($)}}var k=F(.25,.1,.25,1);function U(u,p,_){return Math.min(_,Math.max(p,u))}function K(u,p,_){var R=_-p,j=((u-p)%R+R)%R+p;return j===p?_:j}function ee(u){for(var p=[],_=arguments.length-1;_-- >0;)p[_]=arguments[_+1];for(var R=0,j=p;R>p/4).toString(16):([1e7]+-[1e3]+-4e3+-8e3+-1e11).replace(/[018]/g,u)}()}function Se(u){return!!u&&/^[0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(u)}function Oe(u,p){u.forEach(function(_){p[_]&&(p[_]=p[_].bind(p))})}function ne(u,p){return u.indexOf(p,u.length-p.length)!==-1}function Ge(u,p,_){var R={};for(var j in u)R[j]=p.call(_||this,u[j],j,u);return R}function Xe(u,p,_){var R={};for(var j in u)p.call(_||this,u[j],j,u)&&(R[j]=u[j]);return R}function Ce(u){return Array.isArray(u)?u.map(Ce):typeof u=="object"&&u?Ge(u,Ce):u}var _e={};function Je(u){_e[u]||(typeof console<"u"&&console.warn(u),_e[u]=!0)}function Et(u,p,_){return(_.y-u.y)*(p.x-u.x)>(p.y-u.y)*(_.x-u.x)}function Ze(u){for(var p=0,_=0,R=u.length,j=R-1,$=void 0,J=void 0;_@\,;\:\\"\/\[\]\?\=\{\}\x7F]+)(?:\=(?:([^\x00-\x20\(\)<>@\,;\:\\"\/\[\]\?\=\{\}\x7F]+)|(?:\"((?:[^"\\]|\\.)*)\")))?/g,function(R,j,$,J){var le=$||J;return p[j]=!le||le.toLowerCase(),""}),p["max-age"]){var _=parseInt(p["max-age"],10);isNaN(_)?delete p["max-age"]:p["max-age"]=_}return p}var Mr=null;function hr(u){if(Mr==null){var p=u.navigator?u.navigator.userAgent:null;Mr=!!u.safari||!(!p||!(/\b(iPad|iPhone|iPod)\b/.test(p)||p.match("Safari")&&!p.match("Chrome")))}return Mr}function mi(u){try{var p=y[u];return p.setItem("_mapbox_test_",1),p.removeItem("_mapbox_test_"),!0}catch{return!1}}var bi,un,Yr,Xi,xi=y.performance&&y.performance.now?y.performance.now.bind(y.performance):Date.now.bind(Date),ii=y.requestAnimationFrame||y.mozRequestAnimationFrame||y.webkitRequestAnimationFrame||y.msRequestAnimationFrame,Gn=y.cancelAnimationFrame||y.mozCancelAnimationFrame||y.webkitCancelAnimationFrame||y.msCancelAnimationFrame,Ve={now:xi,frame:function(u){var p=ii(u);return{cancel:function(){return Gn(p)}}},getImageData:function(u,p){p===void 0&&(p=0);var _=y.document.createElement("canvas"),R=_.getContext("2d");if(!R)throw new Error("failed to create canvas 2d context");return _.width=u.width,_.height=u.height,R.drawImage(u,0,0,u.width,u.height),R.getImageData(-p,-p,u.width+2*p,u.height+2*p)},resolveURL:function(u){return bi||(bi=y.document.createElement("a")),bi.href=u,bi.href},hardwareConcurrency:y.navigator&&y.navigator.hardwareConcurrency||4,get devicePixelRatio(){return y.devicePixelRatio},get prefersReducedMotion(){return!!y.matchMedia&&(un==null&&(un=y.matchMedia("(prefers-reduced-motion: reduce)")),un.matches)}},nt={API_URL:"https://api.mapbox.com",get EVENTS_URL(){return this.API_URL?this.API_URL.indexOf("https://api.mapbox.cn")===0?"https://events.mapbox.cn/events/v2":this.API_URL.indexOf("https://api.mapbox.com")===0?"https://events.mapbox.com/events/v2":null:null},FEEDBACK_URL:"https://apps.mapbox.com/feedback",REQUIRE_ACCESS_TOKEN:!0,ACCESS_TOKEN:null,MAX_PARALLEL_IMAGE_REQUESTS:16},Ft={supported:!1,testSupport:function(u){!mr&&Xi&&(Xr?zr(u):Yr=u)}},mr=!1,Xr=!1;function zr(u){var p=u.createTexture();u.bindTexture(u.TEXTURE_2D,p);try{if(u.texImage2D(u.TEXTURE_2D,0,u.RGBA,u.RGBA,u.UNSIGNED_BYTE,Xi),u.isContextLost())return;Ft.supported=!0}catch{}u.deleteTexture(p),mr=!0}y.document&&((Xi=y.document.createElement("img")).onload=function(){Yr&&zr(Yr),Yr=null,Xr=!0},Xi.onerror=function(){mr=!0,Yr=null},Xi.src="data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAQAAAAfQ//73v/+BiOh/AAA=");var ln="01",Nn=function(u,p){this._transformRequestFn=u,this._customAccessToken=p,this._createSkuToken()};function Co(u){return u.indexOf("mapbox:")===0}Nn.prototype._createSkuToken=function(){var u=function(){for(var p="",_=0;_<10;_++)p+="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"[Math.floor(62*Math.random())];return{token:["1",ln,p].join(""),tokenExpiresAt:Date.now()+432e5}}();this._skuToken=u.token,this._skuTokenExpiresAt=u.tokenExpiresAt},Nn.prototype._isSkuTokenExpired=function(){return Date.now()>this._skuTokenExpiresAt},Nn.prototype.transformRequest=function(u,p){return this._transformRequestFn&&this._transformRequestFn(u,p)||{url:u}},Nn.prototype.normalizeStyleURL=function(u,p){if(!Co(u))return u;var _=zs(u);return _.path="/styles/v1"+_.path,this._makeAPIURL(_,this._customAccessToken||p)},Nn.prototype.normalizeGlyphsURL=function(u,p){if(!Co(u))return u;var _=zs(u);return _.path="/fonts/v1"+_.path,this._makeAPIURL(_,this._customAccessToken||p)},Nn.prototype.normalizeSourceURL=function(u,p){if(!Co(u))return u;var _=zs(u);return _.path="/v4/"+_.authority+".json",_.params.push("secure"),this._makeAPIURL(_,this._customAccessToken||p)},Nn.prototype.normalizeSpriteURL=function(u,p,_,R){var j=zs(u);return Co(u)?(j.path="/styles/v1"+j.path+"/sprite"+p+_,this._makeAPIURL(j,this._customAccessToken||R)):(j.path+=""+p+_,Ba(j))},Nn.prototype.normalizeTileURL=function(u,p){if(this._isSkuTokenExpired()&&this._createSkuToken(),u&&!Co(u))return u;var _=zs(u);_.path=_.path.replace(/(\.(png|jpg)\d*)(?=$)/,(Ve.devicePixelRatio>=2||p===512?"@2x":"")+(Ft.supported?".webp":"$1")),_.path=_.path.replace(/^.+\/v4\//,"/"),_.path="/v4"+_.path;var R=this._customAccessToken||function(j){for(var $=0,J=j;$=0&&u.params.splice(j,1)}if(R.path!=="/"&&(u.path=""+R.path+u.path),!nt.REQUIRE_ACCESS_TOKEN)return Ba(u);if(!(p=p||nt.ACCESS_TOKEN))throw new Error("An API access token is required to use Mapbox GL. "+_);if(p[0]==="s")throw new Error("Use a public access token (pk.*) with Mapbox GL, not a secret access token (sk.*). "+_);return u.params=u.params.filter(function($){return $.indexOf("access_token")===-1}),u.params.push("access_token="+p),Ba(u)};var Ho=/^((https?:)?\/\/)?([^\/]+\.)?mapbox\.c(n|om)(\/|\?|$)/i;function is(u){return Ho.test(u)}var mo=/^(\w+):\/\/([^/?]*)(\/[^?]+)?\??(.+)?/;function zs(u){var p=u.match(mo);if(!p)throw new Error("Unable to parse URL object");return{protocol:p[1],authority:p[2],path:p[3]||"/",params:p[4]?p[4].split("&"):[]}}function Ba(u){var p=u.params.length?"?"+u.params.join("&"):"";return u.protocol+"://"+u.authority+u.path+p}function ds(u){if(!u)return null;var p=u.split(".");if(!p||p.length!==3)return null;try{return JSON.parse(decodeURIComponent(y.atob(p[1]).split("").map(function(_){return"%"+("00"+_.charCodeAt(0).toString(16)).slice(-2)}).join("")))}catch{return null}}var so=function(u){this.type=u,this.anonId=null,this.eventData={},this.queue=[],this.pendingRequest=null};so.prototype.getStorageKey=function(u){var p,_=ds(nt.ACCESS_TOKEN);return p=_&&_.u?y.btoa(encodeURIComponent(_.u).replace(/%([0-9A-F]{2})/g,function(R,j){return String.fromCharCode(Number("0x"+j))})):nt.ACCESS_TOKEN||"",u?"mapbox.eventData."+u+":"+p:"mapbox.eventData:"+p},so.prototype.fetchEventData=function(){var u=mi("localStorage"),p=this.getStorageKey(),_=this.getStorageKey("uuid");if(u)try{var R=y.localStorage.getItem(p);R&&(this.eventData=JSON.parse(R));var j=y.localStorage.getItem(_);j&&(this.anonId=j)}catch{Je("Unable to read from LocalStorage")}},so.prototype.saveEventData=function(){var u=mi("localStorage"),p=this.getStorageKey(),_=this.getStorageKey("uuid");if(u)try{y.localStorage.setItem(_,this.anonId),Object.keys(this.eventData).length>=1&&y.localStorage.setItem(p,JSON.stringify(this.eventData))}catch{Je("Unable to write to LocalStorage")}},so.prototype.processRequests=function(u){},so.prototype.postEvent=function(u,p,_,R){var j=this;if(nt.EVENTS_URL){var $=zs(nt.EVENTS_URL);$.params.push("access_token="+(R||nt.ACCESS_TOKEN||""));var J={event:this.type,created:new Date(u).toISOString(),sdkIdentifier:"mapbox-gl-js",sdkVersion:"1.13.3",skuId:ln,userId:this.anonId},le=p?ee(J,p):J,ve={url:Ba($),headers:{"Content-Type":"text/plain"},body:JSON.stringify([le])};this.pendingRequest=ns(ve,function(Ie){j.pendingRequest=null,_(Ie),j.saveEventData(),j.processRequests(R)})}},so.prototype.queueRequest=function(u,p){this.queue.push(u),this.processRequests(p)};var ps,ws,Yt=function(u){function p(){u.call(this,"map.load"),this.success={},this.skuToken=""}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype.postMapLoadEvent=function(_,R,j,$){this.skuToken=j;var J=!(!$&&!nt.ACCESS_TOKEN),le=Array.isArray(_)&&_.some(function(ve){return Co(ve)||is(ve)});nt.EVENTS_URL&&J&&le&&this.queueRequest({id:R,timestamp:Date.now()},$)},p.prototype.processRequests=function(_){var R=this;if(!this.pendingRequest&&this.queue.length!==0){var j=this.queue.shift(),$=j.id,J=j.timestamp;$&&this.success[$]||(this.anonId||this.fetchEventData(),Se(this.anonId)||(this.anonId=me()),this.postEvent(J,{skuToken:this.skuToken},function(le){le||$&&(R.success[$]=!0)},_))}},p}(so),Fe=new(function(u){function p(_){u.call(this,"appUserTurnstile"),this._customAccessToken=_}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype.postTurnstileEvent=function(_,R){nt.EVENTS_URL&&nt.ACCESS_TOKEN&&Array.isArray(_)&&_.some(function(j){return Co(j)||is(j)})&&this.queueRequest(Date.now(),R)},p.prototype.processRequests=function(_){var R=this;if(!this.pendingRequest&&this.queue.length!==0){this.anonId&&this.eventData.lastSuccess&&this.eventData.tokenU||this.fetchEventData();var j=ds(nt.ACCESS_TOKEN),$=j?j.u:nt.ACCESS_TOKEN,J=$!==this.eventData.tokenU;Se(this.anonId)||(this.anonId=me(),J=!0);var le=this.queue.shift();if(this.eventData.lastSuccess){var ve=new Date(this.eventData.lastSuccess),Ie=new Date(le),Le=(le-this.eventData.lastSuccess)/864e5;J=J||Le>=1||Le<-1||ve.getDate()!==Ie.getDate()}else J=!0;if(!J)return this.processRequests();this.postEvent(le,{"enabled.telemetry":!1},function(ze){ze||(R.eventData.lastSuccess=le,R.eventData.tokenU=$)},_)}},p}(so)),Ne=Fe.postTurnstileEvent.bind(Fe),rt=new Yt,Vt=rt.postMapLoadEvent.bind(rt),Gt=500,yr=50;function fr(){y.caches&&!ps&&(ps=y.caches.open("mapbox-tiles"))}function nr(u){var p=u.indexOf("?");return p<0?u:u.slice(0,p)}var xr,ti=1/0;function Jr(){return xr==null&&(xr=y.OffscreenCanvas&&new y.OffscreenCanvas(1,1).getContext("2d")&&typeof y.createImageBitmap=="function"),xr}var Wi={Unknown:"Unknown",Style:"Style",Source:"Source",Tile:"Tile",Glyphs:"Glyphs",SpriteImage:"SpriteImage",SpriteJSON:"SpriteJSON",Image:"Image"};typeof Object.freeze=="function"&&Object.freeze(Wi);var fn=function(u){function p(_,R,j){R===401&&is(j)&&(_+=": you may have provided an invalid Mapbox access token. See https://www.mapbox.com/api-documentation/#access-tokens-and-token-scopes"),u.call(this,_),this.status=R,this.url=j,this.name=this.constructor.name,this.message=_}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype.toString=function(){return this.name+": "+this.message+" ("+this.status+"): "+this.url},p}(Error),Wn=xt()?function(){return self.worker&&self.worker.referrer}:function(){return(y.location.protocol==="blob:"?y.parent:y).location.href},bs,go,wr=function(u,p){if(!(/^file:/.test(_=u.url)||/^file:/.test(Wn())&&!/^\w+:/.test(_))){if(y.fetch&&y.Request&&y.AbortController&&y.Request.prototype.hasOwnProperty("signal"))return function(R,j){var $,J=new y.AbortController,le=new y.Request(R.url,{method:R.method||"GET",body:R.body,credentials:R.credentials,headers:R.headers,referrer:Wn(),signal:J.signal}),ve=!1,Ie=!1,Le=($=le.url).indexOf("sku=")>0&&is($);R.type==="json"&&le.headers.set("Accept","application/json");var ze=function(lt,Mt,Dt){if(!Ie){if(lt&<.message!=="SecurityError"&&Je(lt),Mt&&Dt)return Ke(Mt);var tr=Date.now();y.fetch(le).then(function(qt){if(qt.ok){var ur=Le?qt.clone():null;return Ke(qt,ur,tr)}return j(new fn(qt.statusText,qt.status,R.url))}).catch(function(qt){qt.code!==20&&j(new Error(qt.message))})}},Ke=function(lt,Mt,Dt){(R.type==="arrayBuffer"?lt.arrayBuffer():R.type==="json"?lt.json():lt.text()).then(function(tr){Ie||(Mt&&Dt&&function(qt,ur,Tr){if(fr(),ps){var Nr={status:ur.status,statusText:ur.statusText,headers:new y.Headers};ur.headers.forEach(function(ri,Ei){return Nr.headers.set(Ei,ri)});var Vr=sr(ur.headers.get("Cache-Control")||"");Vr["no-store"]||(Vr["max-age"]&&Nr.headers.set("Expires",new Date(Tr+1e3*Vr["max-age"]).toUTCString()),new Date(Nr.headers.get("Expires")).getTime()-Tr<42e4||function(ri,Ei){if(ws===void 0)try{new Response(new ReadableStream),ws=!0}catch{ws=!1}ws?Ei(ri.body):ri.blob().then(Ei)}(ur,function(ri){var Ei=new y.Response(ri,Nr);fr(),ps&&ps.then(function(Ui){return Ui.put(nr(qt.url),Ei)}).catch(function(Ui){return Je(Ui.message)})}))}}(le,Mt,Dt),ve=!0,j(null,tr,lt.headers.get("Cache-Control"),lt.headers.get("Expires")))}).catch(function(tr){Ie||j(new Error(tr.message))})};return Le?function(lt,Mt){if(fr(),!ps)return Mt(null);var Dt=nr(lt.url);ps.then(function(tr){tr.match(Dt).then(function(qt){var ur=function(Tr){if(!Tr)return!1;var Nr=new Date(Tr.headers.get("Expires")||0),Vr=sr(Tr.headers.get("Cache-Control")||"");return Nr>Date.now()&&!Vr["no-cache"]}(qt);tr.delete(Dt),ur&&tr.put(Dt,qt.clone()),Mt(null,qt,ur)}).catch(Mt)}).catch(Mt)}(le,ze):ze(null,null),{cancel:function(){Ie=!0,ve||J.abort()}}}(u,p);if(xt()&&self.worker&&self.worker.actor)return self.worker.actor.send("getResource",u,p,void 0,!0)}var _;return function(R,j){var $=new y.XMLHttpRequest;for(var J in $.open(R.method||"GET",R.url,!0),R.type==="arrayBuffer"&&($.responseType="arraybuffer"),R.headers)$.setRequestHeader(J,R.headers[J]);return R.type==="json"&&($.responseType="text",$.setRequestHeader("Accept","application/json")),$.withCredentials=R.credentials==="include",$.onerror=function(){j(new Error($.statusText))},$.onload=function(){if(($.status>=200&&$.status<300||$.status===0)&&$.response!==null){var le=$.response;if(R.type==="json")try{le=JSON.parse($.response)}catch(ve){return j(ve)}j(null,le,$.getResponseHeader("Cache-Control"),$.getResponseHeader("Expires"))}else j(new fn($.statusText,$.status,R.url))},$.send(R.body),{cancel:function(){return $.abort()}}}(u,p)},Us=function(u,p){return wr(ee(u,{type:"arrayBuffer"}),p)},ns=function(u,p){return wr(ee(u,{method:"POST"}),p)},Be="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQYV2NgAAIAAAUAAarVyFEAAAAASUVORK5CYII=";bs=[],go=0;var $e=function(u,p){if(Ft.supported&&(u.headers||(u.headers={}),u.headers.accept="image/webp,*/*"),go>=nt.MAX_PARALLEL_IMAGE_REQUESTS){var _={requestParameters:u,callback:p,cancelled:!1,cancel:function(){this.cancelled=!0}};return bs.push(_),_}go++;var R=!1,j=function(){if(!R)for(R=!0,go--;bs.length&&go0||this._oneTimeListeners&&this._oneTimeListeners[u]&&this._oneTimeListeners[u].length>0||this._eventedParent&&this._eventedParent.listens(u)},Jt.prototype.setEventedParent=function(u,p){return this._eventedParent=u,this._eventedParentData=p,this};var ht={$version:8,$root:{version:{required:!0,type:"enum",values:[8]},name:{type:"string"},metadata:{type:"*"},center:{type:"array",value:"number"},zoom:{type:"number"},bearing:{type:"number",default:0,period:360,units:"degrees"},pitch:{type:"number",default:0,units:"degrees"},light:{type:"light"},sources:{required:!0,type:"sources"},sprite:{type:"string"},glyphs:{type:"string"},transition:{type:"transition"},layers:{required:!0,type:"array",value:"layer"}},sources:{"*":{type:"source"}},source:["source_vector","source_raster","source_raster_dem","source_geojson","source_video","source_image"],source_vector:{type:{required:!0,type:"enum",values:{vector:{}}},url:{type:"string"},tiles:{type:"array",value:"string"},bounds:{type:"array",value:"number",length:4,default:[-180,-85.051129,180,85.051129]},scheme:{type:"enum",values:{xyz:{},tms:{}},default:"xyz"},minzoom:{type:"number",default:0},maxzoom:{type:"number",default:22},attribution:{type:"string"},promoteId:{type:"promoteId"},volatile:{type:"boolean",default:!1},"*":{type:"*"}},source_raster:{type:{required:!0,type:"enum",values:{raster:{}}},url:{type:"string"},tiles:{type:"array",value:"string"},bounds:{type:"array",value:"number",length:4,default:[-180,-85.051129,180,85.051129]},minzoom:{type:"number",default:0},maxzoom:{type:"number",default:22},tileSize:{type:"number",default:512,units:"pixels"},scheme:{type:"enum",values:{xyz:{},tms:{}},default:"xyz"},attribution:{type:"string"},volatile:{type:"boolean",default:!1},"*":{type:"*"}},source_raster_dem:{type:{required:!0,type:"enum",values:{"raster-dem":{}}},url:{type:"string"},tiles:{type:"array",value:"string"},bounds:{type:"array",value:"number",length:4,default:[-180,-85.051129,180,85.051129]},minzoom:{type:"number",default:0},maxzoom:{type:"number",default:22},tileSize:{type:"number",default:512,units:"pixels"},attribution:{type:"string"},encoding:{type:"enum",values:{terrarium:{},mapbox:{}},default:"mapbox"},volatile:{type:"boolean",default:!1},"*":{type:"*"}},source_geojson:{type:{required:!0,type:"enum",values:{geojson:{}}},data:{type:"*"},maxzoom:{type:"number",default:18},attribution:{type:"string"},buffer:{type:"number",default:128,maximum:512,minimum:0},filter:{type:"*"},tolerance:{type:"number",default:.375},cluster:{type:"boolean",default:!1},clusterRadius:{type:"number",default:50,minimum:0},clusterMaxZoom:{type:"number"},clusterMinPoints:{type:"number"},clusterProperties:{type:"*"},lineMetrics:{type:"boolean",default:!1},generateId:{type:"boolean",default:!1},promoteId:{type:"promoteId"}},source_video:{type:{required:!0,type:"enum",values:{video:{}}},urls:{required:!0,type:"array",value:"string"},coordinates:{required:!0,type:"array",length:4,value:{type:"array",length:2,value:"number"}}},source_image:{type:{required:!0,type:"enum",values:{image:{}}},url:{required:!0,type:"string"},coordinates:{required:!0,type:"array",length:4,value:{type:"array",length:2,value:"number"}}},layer:{id:{type:"string",required:!0},type:{type:"enum",values:{fill:{},line:{},symbol:{},circle:{},heatmap:{},"fill-extrusion":{},raster:{},hillshade:{},background:{}},required:!0},metadata:{type:"*"},source:{type:"string"},"source-layer":{type:"string"},minzoom:{type:"number",minimum:0,maximum:24},maxzoom:{type:"number",minimum:0,maximum:24},filter:{type:"filter"},layout:{type:"layout"},paint:{type:"paint"}},layout:["layout_fill","layout_line","layout_circle","layout_heatmap","layout_fill-extrusion","layout_symbol","layout_raster","layout_hillshade","layout_background"],layout_background:{visibility:{type:"enum",values:{visible:{},none:{}},default:"visible","property-type":"constant"}},layout_fill:{"fill-sort-key":{type:"number",expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"data-driven"},visibility:{type:"enum",values:{visible:{},none:{}},default:"visible","property-type":"constant"}},layout_circle:{"circle-sort-key":{type:"number",expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"data-driven"},visibility:{type:"enum",values:{visible:{},none:{}},default:"visible","property-type":"constant"}},layout_heatmap:{visibility:{type:"enum",values:{visible:{},none:{}},default:"visible","property-type":"constant"}},"layout_fill-extrusion":{visibility:{type:"enum",values:{visible:{},none:{}},default:"visible","property-type":"constant"}},layout_line:{"line-cap":{type:"enum",values:{butt:{},round:{},square:{}},default:"butt",expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"line-join":{type:"enum",values:{bevel:{},round:{},miter:{}},default:"miter",expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"data-driven"},"line-miter-limit":{type:"number",default:2,requires:[{"line-join":"miter"}],expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"line-round-limit":{type:"number",default:1.05,requires:[{"line-join":"round"}],expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"line-sort-key":{type:"number",expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"data-driven"},visibility:{type:"enum",values:{visible:{},none:{}},default:"visible","property-type":"constant"}},layout_symbol:{"symbol-placement":{type:"enum",values:{point:{},line:{},"line-center":{}},default:"point",expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"symbol-spacing":{type:"number",default:250,minimum:1,units:"pixels",requires:[{"symbol-placement":"line"}],expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"symbol-avoid-edges":{type:"boolean",default:!1,expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"symbol-sort-key":{type:"number",expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"data-driven"},"symbol-z-order":{type:"enum",values:{auto:{},"viewport-y":{},source:{}},default:"auto",expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"icon-allow-overlap":{type:"boolean",default:!1,requires:["icon-image"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"icon-ignore-placement":{type:"boolean",default:!1,requires:["icon-image"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"icon-optional":{type:"boolean",default:!1,requires:["icon-image","text-field"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"icon-rotation-alignment":{type:"enum",values:{map:{},viewport:{},auto:{}},default:"auto",requires:["icon-image"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"icon-size":{type:"number",default:1,minimum:0,units:"factor of the original icon size",requires:["icon-image"],expression:{interpolated:!0,parameters:["zoom","feature"]},"property-type":"data-driven"},"icon-text-fit":{type:"enum",values:{none:{},width:{},height:{},both:{}},default:"none",requires:["icon-image","text-field"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"icon-text-fit-padding":{type:"array",value:"number",length:4,default:[0,0,0,0],units:"pixels",requires:["icon-image","text-field",{"icon-text-fit":["both","width","height"]}],expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"icon-image":{type:"resolvedImage",tokens:!0,expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"data-driven"},"icon-rotate":{type:"number",default:0,period:360,units:"degrees",requires:["icon-image"],expression:{interpolated:!0,parameters:["zoom","feature"]},"property-type":"data-driven"},"icon-padding":{type:"number",default:2,minimum:0,units:"pixels",requires:["icon-image"],expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"icon-keep-upright":{type:"boolean",default:!1,requires:["icon-image",{"icon-rotation-alignment":"map"},{"symbol-placement":["line","line-center"]}],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"icon-offset":{type:"array",value:"number",length:2,default:[0,0],requires:["icon-image"],expression:{interpolated:!0,parameters:["zoom","feature"]},"property-type":"data-driven"},"icon-anchor":{type:"enum",values:{center:{},left:{},right:{},top:{},bottom:{},"top-left":{},"top-right":{},"bottom-left":{},"bottom-right":{}},default:"center",requires:["icon-image"],expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"data-driven"},"icon-pitch-alignment":{type:"enum",values:{map:{},viewport:{},auto:{}},default:"auto",requires:["icon-image"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"text-pitch-alignment":{type:"enum",values:{map:{},viewport:{},auto:{}},default:"auto",requires:["text-field"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"text-rotation-alignment":{type:"enum",values:{map:{},viewport:{},auto:{}},default:"auto",requires:["text-field"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"text-field":{type:"formatted",default:"",tokens:!0,expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"data-driven"},"text-font":{type:"array",value:"string",default:["Open Sans Regular","Arial Unicode MS Regular"],requires:["text-field"],expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"data-driven"},"text-size":{type:"number",default:16,minimum:0,units:"pixels",requires:["text-field"],expression:{interpolated:!0,parameters:["zoom","feature"]},"property-type":"data-driven"},"text-max-width":{type:"number",default:10,minimum:0,units:"ems",requires:["text-field"],expression:{interpolated:!0,parameters:["zoom","feature"]},"property-type":"data-driven"},"text-line-height":{type:"number",default:1.2,units:"ems",requires:["text-field"],expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"text-letter-spacing":{type:"number",default:0,units:"ems",requires:["text-field"],expression:{interpolated:!0,parameters:["zoom","feature"]},"property-type":"data-driven"},"text-justify":{type:"enum",values:{auto:{},left:{},center:{},right:{}},default:"center",requires:["text-field"],expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"data-driven"},"text-radial-offset":{type:"number",units:"ems",default:0,requires:["text-field"],"property-type":"data-driven",expression:{interpolated:!0,parameters:["zoom","feature"]}},"text-variable-anchor":{type:"array",value:"enum",values:{center:{},left:{},right:{},top:{},bottom:{},"top-left":{},"top-right":{},"bottom-left":{},"bottom-right":{}},requires:["text-field",{"symbol-placement":["point"]}],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"text-anchor":{type:"enum",values:{center:{},left:{},right:{},top:{},bottom:{},"top-left":{},"top-right":{},"bottom-left":{},"bottom-right":{}},default:"center",requires:["text-field",{"!":"text-variable-anchor"}],expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"data-driven"},"text-max-angle":{type:"number",default:45,units:"degrees",requires:["text-field",{"symbol-placement":["line","line-center"]}],expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"text-writing-mode":{type:"array",value:"enum",values:{horizontal:{},vertical:{}},requires:["text-field",{"symbol-placement":["point"]}],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"text-rotate":{type:"number",default:0,period:360,units:"degrees",requires:["text-field"],expression:{interpolated:!0,parameters:["zoom","feature"]},"property-type":"data-driven"},"text-padding":{type:"number",default:2,minimum:0,units:"pixels",requires:["text-field"],expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"text-keep-upright":{type:"boolean",default:!0,requires:["text-field",{"text-rotation-alignment":"map"},{"symbol-placement":["line","line-center"]}],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"text-transform":{type:"enum",values:{none:{},uppercase:{},lowercase:{}},default:"none",requires:["text-field"],expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"data-driven"},"text-offset":{type:"array",value:"number",units:"ems",length:2,default:[0,0],requires:["text-field",{"!":"text-radial-offset"}],expression:{interpolated:!0,parameters:["zoom","feature"]},"property-type":"data-driven"},"text-allow-overlap":{type:"boolean",default:!1,requires:["text-field"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"text-ignore-placement":{type:"boolean",default:!1,requires:["text-field"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"text-optional":{type:"boolean",default:!1,requires:["text-field","icon-image"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},visibility:{type:"enum",values:{visible:{},none:{}},default:"visible","property-type":"constant"}},layout_raster:{visibility:{type:"enum",values:{visible:{},none:{}},default:"visible","property-type":"constant"}},layout_hillshade:{visibility:{type:"enum",values:{visible:{},none:{}},default:"visible","property-type":"constant"}},filter:{type:"array",value:"*"},filter_operator:{type:"enum",values:{"==":{},"!=":{},">":{},">=":{},"<":{},"<=":{},in:{},"!in":{},all:{},any:{},none:{},has:{},"!has":{},within:{}}},geometry_type:{type:"enum",values:{Point:{},LineString:{},Polygon:{}}},function:{expression:{type:"expression"},stops:{type:"array",value:"function_stop"},base:{type:"number",default:1,minimum:0},property:{type:"string",default:"$zoom"},type:{type:"enum",values:{identity:{},exponential:{},interval:{},categorical:{}},default:"exponential"},colorSpace:{type:"enum",values:{rgb:{},lab:{},hcl:{}},default:"rgb"},default:{type:"*",required:!1}},function_stop:{type:"array",minimum:0,maximum:24,value:["number","color"],length:2},expression:{type:"array",value:"*",minimum:1},light:{anchor:{type:"enum",default:"viewport",values:{map:{},viewport:{}},"property-type":"data-constant",transition:!1,expression:{interpolated:!1,parameters:["zoom"]}},position:{type:"array",default:[1.15,210,30],length:3,value:"number","property-type":"data-constant",transition:!0,expression:{interpolated:!0,parameters:["zoom"]}},color:{type:"color","property-type":"data-constant",default:"#ffffff",expression:{interpolated:!0,parameters:["zoom"]},transition:!0},intensity:{type:"number","property-type":"data-constant",default:.5,minimum:0,maximum:1,expression:{interpolated:!0,parameters:["zoom"]},transition:!0}},paint:["paint_fill","paint_line","paint_circle","paint_heatmap","paint_fill-extrusion","paint_symbol","paint_raster","paint_hillshade","paint_background"],paint_fill:{"fill-antialias":{type:"boolean",default:!0,expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"fill-opacity":{type:"number",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"fill-color":{type:"color",default:"#000000",transition:!0,requires:[{"!":"fill-pattern"}],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"fill-outline-color":{type:"color",transition:!0,requires:[{"!":"fill-pattern"},{"fill-antialias":!0}],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"fill-translate":{type:"array",value:"number",length:2,default:[0,0],transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"fill-translate-anchor":{type:"enum",values:{map:{},viewport:{}},default:"map",requires:["fill-translate"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"fill-pattern":{type:"resolvedImage",transition:!0,expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"cross-faded-data-driven"}},"paint_fill-extrusion":{"fill-extrusion-opacity":{type:"number",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"fill-extrusion-color":{type:"color",default:"#000000",transition:!0,requires:[{"!":"fill-extrusion-pattern"}],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"fill-extrusion-translate":{type:"array",value:"number",length:2,default:[0,0],transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"fill-extrusion-translate-anchor":{type:"enum",values:{map:{},viewport:{}},default:"map",requires:["fill-extrusion-translate"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"fill-extrusion-pattern":{type:"resolvedImage",transition:!0,expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"cross-faded-data-driven"},"fill-extrusion-height":{type:"number",default:0,minimum:0,units:"meters",transition:!0,expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"fill-extrusion-base":{type:"number",default:0,minimum:0,units:"meters",transition:!0,requires:["fill-extrusion-height"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"fill-extrusion-vertical-gradient":{type:"boolean",default:!0,transition:!1,expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"}},paint_line:{"line-opacity":{type:"number",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"line-color":{type:"color",default:"#000000",transition:!0,requires:[{"!":"line-pattern"}],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"line-translate":{type:"array",value:"number",length:2,default:[0,0],transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"line-translate-anchor":{type:"enum",values:{map:{},viewport:{}},default:"map",requires:["line-translate"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"line-width":{type:"number",default:1,minimum:0,transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"line-gap-width":{type:"number",default:0,minimum:0,transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"line-offset":{type:"number",default:0,transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"line-blur":{type:"number",default:0,minimum:0,transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"line-dasharray":{type:"array",value:"number",minimum:0,transition:!0,units:"line widths",requires:[{"!":"line-pattern"}],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"cross-faded"},"line-pattern":{type:"resolvedImage",transition:!0,expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"cross-faded-data-driven"},"line-gradient":{type:"color",transition:!1,requires:[{"!":"line-dasharray"},{"!":"line-pattern"},{source:"geojson",has:{lineMetrics:!0}}],expression:{interpolated:!0,parameters:["line-progress"]},"property-type":"color-ramp"}},paint_circle:{"circle-radius":{type:"number",default:5,minimum:0,transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"circle-color":{type:"color",default:"#000000",transition:!0,expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"circle-blur":{type:"number",default:0,transition:!0,expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"circle-opacity":{type:"number",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"circle-translate":{type:"array",value:"number",length:2,default:[0,0],transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"circle-translate-anchor":{type:"enum",values:{map:{},viewport:{}},default:"map",requires:["circle-translate"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"circle-pitch-scale":{type:"enum",values:{map:{},viewport:{}},default:"map",expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"circle-pitch-alignment":{type:"enum",values:{map:{},viewport:{}},default:"viewport",expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"circle-stroke-width":{type:"number",default:0,minimum:0,transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"circle-stroke-color":{type:"color",default:"#000000",transition:!0,expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"circle-stroke-opacity":{type:"number",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"}},paint_heatmap:{"heatmap-radius":{type:"number",default:30,minimum:1,transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"heatmap-weight":{type:"number",default:1,minimum:0,transition:!1,expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"heatmap-intensity":{type:"number",default:1,minimum:0,transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"heatmap-color":{type:"color",default:["interpolate",["linear"],["heatmap-density"],0,"rgba(0, 0, 255, 0)",.1,"royalblue",.3,"cyan",.5,"lime",.7,"yellow",1,"red"],transition:!1,expression:{interpolated:!0,parameters:["heatmap-density"]},"property-type":"color-ramp"},"heatmap-opacity":{type:"number",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"}},paint_symbol:{"icon-opacity":{type:"number",default:1,minimum:0,maximum:1,transition:!0,requires:["icon-image"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"icon-color":{type:"color",default:"#000000",transition:!0,requires:["icon-image"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"icon-halo-color":{type:"color",default:"rgba(0, 0, 0, 0)",transition:!0,requires:["icon-image"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"icon-halo-width":{type:"number",default:0,minimum:0,transition:!0,units:"pixels",requires:["icon-image"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"icon-halo-blur":{type:"number",default:0,minimum:0,transition:!0,units:"pixels",requires:["icon-image"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"icon-translate":{type:"array",value:"number",length:2,default:[0,0],transition:!0,units:"pixels",requires:["icon-image"],expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"icon-translate-anchor":{type:"enum",values:{map:{},viewport:{}},default:"map",requires:["icon-image","icon-translate"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"text-opacity":{type:"number",default:1,minimum:0,maximum:1,transition:!0,requires:["text-field"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"text-color":{type:"color",default:"#000000",transition:!0,overridable:!0,requires:["text-field"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"text-halo-color":{type:"color",default:"rgba(0, 0, 0, 0)",transition:!0,requires:["text-field"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"text-halo-width":{type:"number",default:0,minimum:0,transition:!0,units:"pixels",requires:["text-field"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"text-halo-blur":{type:"number",default:0,minimum:0,transition:!0,units:"pixels",requires:["text-field"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"text-translate":{type:"array",value:"number",length:2,default:[0,0],transition:!0,units:"pixels",requires:["text-field"],expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"text-translate-anchor":{type:"enum",values:{map:{},viewport:{}},default:"map",requires:["text-field","text-translate"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"}},paint_raster:{"raster-opacity":{type:"number",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"raster-hue-rotate":{type:"number",default:0,period:360,transition:!0,units:"degrees",expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"raster-brightness-min":{type:"number",default:0,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"raster-brightness-max":{type:"number",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"raster-saturation":{type:"number",default:0,minimum:-1,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"raster-contrast":{type:"number",default:0,minimum:-1,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"raster-resampling":{type:"enum",values:{linear:{},nearest:{}},default:"linear",expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"raster-fade-duration":{type:"number",default:300,minimum:0,transition:!1,units:"milliseconds",expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"}},paint_hillshade:{"hillshade-illumination-direction":{type:"number",default:335,minimum:0,maximum:359,transition:!1,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"hillshade-illumination-anchor":{type:"enum",values:{map:{},viewport:{}},default:"viewport",expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"hillshade-exaggeration":{type:"number",default:.5,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"hillshade-shadow-color":{type:"color",default:"#000000",transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"hillshade-highlight-color":{type:"color",default:"#FFFFFF",transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"hillshade-accent-color":{type:"color",default:"#000000",transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"}},paint_background:{"background-color":{type:"color",default:"#000000",transition:!0,requires:[{"!":"background-pattern"}],expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"background-pattern":{type:"resolvedImage",transition:!0,expression:{interpolated:!1,parameters:["zoom"]},"property-type":"cross-faded"},"background-opacity":{type:"number",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"}},transition:{duration:{type:"number",default:300,minimum:0,units:"milliseconds"},delay:{type:"number",default:0,minimum:0,units:"milliseconds"}},"property-type":{"data-driven":{type:"property-type"},"cross-faded":{type:"property-type"},"cross-faded-data-driven":{type:"property-type"},"color-ramp":{type:"property-type"},"data-constant":{type:"property-type"},constant:{type:"property-type"}},promoteId:{"*":{type:"string"}}},Ot=function(u,p,_,R){this.message=(u?u+": ":"")+_,R&&(this.identifier=R),p!=null&&p.__line__&&(this.line=p.__line__)};function Ct(u){var p=u.value;return p?[new Ot(u.key,p,"constants have been deprecated as of v8")]:[]}function ei(u){for(var p=[],_=arguments.length-1;_-- >0;)p[_]=arguments[_+1];for(var R=0,j=p;R":u.itemType.kind==="value"?"array":"array<"+p+">"}return u.kind}var Al=[fi,pr,Di,Ii,Mi,Ls,Ni,No(zi),co];function uo(u,p){if(p.kind==="error")return null;if(u.kind==="array"){if(p.kind==="array"&&(p.N===0&&p.itemType.kind==="value"||!uo(u.itemType,p.itemType))&&(typeof u.N!="number"||u.N===p.N))return null}else{if(u.kind===p.kind)return null;if(u.kind==="value"){for(var _=0,R=Al;_255?255:le}function j(le){return R(le[le.length-1]==="%"?parseFloat(le)/100*255:parseInt(le))}function $(le){return(ve=le[le.length-1]==="%"?parseFloat(le)/100:parseFloat(le))<0?0:ve>1?1:ve;var ve}function J(le,ve,Ie){return Ie<0?Ie+=1:Ie>1&&(Ie-=1),6*Ie<1?le+(ve-le)*Ie*6:2*Ie<1?ve:3*Ie<2?le+(ve-le)*(2/3-Ie)*6:le}try{p.parseCSSColor=function(le){var ve,Ie=le.replace(/ /g,"").toLowerCase();if(Ie in _)return _[Ie].slice();if(Ie[0]==="#")return Ie.length===4?(ve=parseInt(Ie.substr(1),16))>=0&&ve<=4095?[(3840&ve)>>4|(3840&ve)>>8,240&ve|(240&ve)>>4,15&ve|(15&ve)<<4,1]:null:Ie.length===7&&(ve=parseInt(Ie.substr(1),16))>=0&&ve<=16777215?[(16711680&ve)>>16,(65280&ve)>>8,255&ve,1]:null;var Le=Ie.indexOf("("),ze=Ie.indexOf(")");if(Le!==-1&&ze+1===Ie.length){var Ke=Ie.substr(0,Le),lt=Ie.substr(Le+1,ze-(Le+1)).split(","),Mt=1;switch(Ke){case"rgba":if(lt.length!==4)return null;Mt=$(lt.pop());case"rgb":return lt.length!==3?null:[j(lt[0]),j(lt[1]),j(lt[2]),Mt];case"hsla":if(lt.length!==4)return null;Mt=$(lt.pop());case"hsl":if(lt.length!==3)return null;var Dt=(parseFloat(lt[0])%360+360)%360/360,tr=$(lt[1]),qt=$(lt[2]),ur=qt<=.5?qt*(tr+1):qt+tr-qt*tr,Tr=2*qt-ur;return[R(255*J(Tr,ur,Dt+1/3)),R(255*J(Tr,ur,Dt)),R(255*J(Tr,ur,Dt-1/3)),Mt];default:return null}}return null}}catch{}}).parseCSSColor,cs=function(u,p,_,R){R===void 0&&(R=1),this.r=u,this.g=p,this.b=_,this.a=R};cs.parse=function(u){if(u){if(u instanceof cs)return u;if(typeof u=="string"){var p=ho(u);if(p)return new cs(p[0]/255*p[3],p[1]/255*p[3],p[2]/255*p[3],p[3])}}},cs.prototype.toString=function(){var u=this.toArray(),p=u[1],_=u[2],R=u[3];return"rgba("+Math.round(u[0])+","+Math.round(p)+","+Math.round(_)+","+R+")"},cs.prototype.toArray=function(){var u=this.a;return u===0?[0,0,0,0]:[255*this.r/u,255*this.g/u,255*this.b/u,u]},cs.black=new cs(0,0,0,1),cs.white=new cs(1,1,1,1),cs.transparent=new cs(0,0,0,0),cs.red=new cs(1,0,0,1);var _l=function(u,p,_){this.sensitivity=u?p?"variant":"case":p?"accent":"base",this.locale=_,this.collator=new Intl.Collator(this.locale?this.locale:[],{sensitivity:this.sensitivity,usage:"search"})};_l.prototype.compare=function(u,p){return this.collator.compare(u,p)},_l.prototype.resolvedLocale=function(){return new Intl.Collator(this.locale?this.locale:[]).resolvedOptions().locale};var zc=function(u,p,_,R,j){this.text=u,this.image=p,this.scale=_,this.fontStack=R,this.textColor=j},yl=function(u){this.sections=u};yl.fromString=function(u){return new yl([new zc(u,null,null,null,null)])},yl.prototype.isEmpty=function(){return this.sections.length===0||!this.sections.some(function(u){return u.text.length!==0||u.image&&u.image.name.length!==0})},yl.factory=function(u){return u instanceof yl?u:yl.fromString(u)},yl.prototype.toString=function(){return this.sections.length===0?"":this.sections.map(function(u){return u.text}).join("")},yl.prototype.serialize=function(){for(var u=["format"],p=0,_=this.sections;p<_.length;p+=1){var R=_[p];if(R.image)u.push(["image",R.image.name]);else{u.push(R.text);var j={};R.fontStack&&(j["text-font"]=["literal",R.fontStack.split(",")]),R.scale&&(j["font-scale"]=R.scale),R.textColor&&(j["text-color"]=["rgba"].concat(R.textColor.toArray())),u.push(j)}}return u};var Ya=function(u){this.name=u.name,this.available=u.available};function md(u,p,_,R){return typeof u=="number"&&u>=0&&u<=255&&typeof p=="number"&&p>=0&&p<=255&&typeof _=="number"&&_>=0&&_<=255?R===void 0||typeof R=="number"&&R>=0&&R<=1?null:"Invalid rgba value ["+[u,p,_,R].join(", ")+"]: 'a' must be between 0 and 1.":"Invalid rgba value ["+(typeof R=="number"?[u,p,_,R]:[u,p,_]).join(", ")+"]: 'r', 'g', and 'b' must be between 0 and 255."}function os(u){if(u===null||typeof u=="string"||typeof u=="boolean"||typeof u=="number"||u instanceof cs||u instanceof _l||u instanceof yl||u instanceof Ya)return!0;if(Array.isArray(u)){for(var p=0,_=u;p<_.length;p+=1)if(!os(_[p]))return!1;return!0}if(typeof u=="object"){for(var R in u)if(!os(u[R]))return!1;return!0}return!1}function ca(u){if(u===null)return fi;if(typeof u=="string")return Di;if(typeof u=="boolean")return Ii;if(typeof u=="number")return pr;if(u instanceof cs)return Mi;if(u instanceof _l)return po;if(u instanceof yl)return Ls;if(u instanceof Ya)return co;if(Array.isArray(u)){for(var p,_=u.length,R=0,j=u;R2){var le=u[1];if(typeof le!="string"||!(le in eu)||le==="object")return p.error('The item type argument of "array" must be one of string, number, boolean',1);$=eu[le],R++}else $=zi;if(u.length>3){if(u[2]!==null&&(typeof u[2]!="number"||u[2]<0||u[2]!==Math.floor(u[2])))return p.error('The length argument to "array" must be a positive integer literal',2);J=u[2],R++}_=No($,J)}else _=eu[j];for(var ve=[];R1)&&p.push(R)}}return p.concat(this.args.map(function(j){return j.serialize()}))};var Tc=function(u){this.type=Ls,this.sections=u};Tc.parse=function(u,p){if(u.length<2)return p.error("Expected at least one argument.");var _=u[1];if(!Array.isArray(_)&&typeof _=="object")return p.error("First argument must be an image or text section.");for(var R=[],j=!1,$=1;$<=u.length-1;++$){var J=u[$];if(j&&typeof J=="object"&&!Array.isArray(J)){j=!1;var le=null;if(J["font-scale"]&&!(le=p.parse(J["font-scale"],1,pr)))return null;var ve=null;if(J["text-font"]&&!(ve=p.parse(J["text-font"],1,No(Di))))return null;var Ie=null;if(J["text-color"]&&!(Ie=p.parse(J["text-color"],1,Mi)))return null;var Le=R[R.length-1];Le.scale=le,Le.font=ve,Le.textColor=Ie}else{var ze=p.parse(u[$],1,zi);if(!ze)return null;var Ke=ze.type.kind;if(Ke!=="string"&&Ke!=="value"&&Ke!=="null"&&Ke!=="resolvedImage")return p.error("Formatted text type must be 'string', 'value', 'image' or 'null'.");j=!0,R.push({content:ze,scale:null,font:null,textColor:null})}}return new Tc(R)},Tc.prototype.evaluate=function(u){return new yl(this.sections.map(function(p){var _=p.content.evaluate(u);return ca(_)===co?new zc("",_,null,null,null):new zc(mf(_),null,p.scale?p.scale.evaluate(u):null,p.font?p.font.evaluate(u).join(","):null,p.textColor?p.textColor.evaluate(u):null)}))},Tc.prototype.eachChild=function(u){for(var p=0,_=this.sections;p<_.length;p+=1){var R=_[p];u(R.content),R.scale&&u(R.scale),R.font&&u(R.font),R.textColor&&u(R.textColor)}},Tc.prototype.outputDefined=function(){return!1},Tc.prototype.serialize=function(){for(var u=["format"],p=0,_=this.sections;p<_.length;p+=1){var R=_[p];u.push(R.content.serialize());var j={};R.scale&&(j["font-scale"]=R.scale.serialize()),R.font&&(j["text-font"]=R.font.serialize()),R.textColor&&(j["text-color"]=R.textColor.serialize()),u.push(j)}return u};var Uc=function(u){this.type=co,this.input=u};Uc.parse=function(u,p){if(u.length!==2)return p.error("Expected two arguments.");var _=p.parse(u[1],1,Di);return _?new Uc(_):p.error("No image name provided.")},Uc.prototype.evaluate=function(u){var p=this.input.evaluate(u),_=Ya.fromString(p);return _&&u.availableImages&&(_.available=u.availableImages.indexOf(p)>-1),_},Uc.prototype.eachChild=function(u){u(this.input)},Uc.prototype.outputDefined=function(){return!1},Uc.prototype.serialize=function(){return["image",this.input.serialize()]};var pm={"to-boolean":Ii,"to-color":Mi,"to-number":pr,"to-string":Di},pu=function(u,p){this.type=u,this.args=p};pu.parse=function(u,p){if(u.length<2)return p.error("Expected at least one argument.");var _=u[0];if((_==="to-boolean"||_==="to-string")&&u.length!==2)return p.error("Expected one argument.");for(var R=pm[_],j=[],$=1;$4?"Invalid rbga value "+JSON.stringify(p)+": expected an array containing either three or four numeric values.":md(p[0],p[1],p[2],p[3])))return new cs(p[0]/255,p[1]/255,p[2]/255,p[3])}throw new Dl(_||"Could not parse color from value '"+(typeof p=="string"?p:String(JSON.stringify(p)))+"'")}if(this.type.kind==="number"){for(var J=null,le=0,ve=this.args;le=p[2]||u[1]<=p[1]||u[3]>=p[3])}function gf(u,p){var _=(180+u[0])/360,R=(180-180/Math.PI*Math.log(Math.tan(Math.PI/4+u[1]*Math.PI/360)))/360,j=Math.pow(2,p.z);return[Math.round(_*j*8192),Math.round(R*j*8192)]}function gd(u,p,_){return p[1]>u[1]!=_[1]>u[1]&&u[0]<(_[0]-p[0])*(u[1]-p[1])/(_[1]-p[1])+p[0]}function jh(u,p){for(var _,R,j,$,J,le,ve,Ie=!1,Le=0,ze=p.length;Le0&&le<0||J<0&&le>0}function Sp(u,p,_){for(var R=0,j=_;R_[2]){var j=.5*R,$=u[0]-_[0]>j?-R:_[0]-u[0]>j?R:0;$===0&&($=u[0]-_[2]>j?-R:_[2]-u[0]>j?R:0),u[0]+=$}Sc(p,u)}function Zn(u,p,_,R){for(var j=8192*Math.pow(2,R.z),$=[8192*R.x,8192*R.y],J=[],le=0,ve=u;le=0)return!1;var _=!0;return u.eachChild(function(R){_&&!vl(R,p)&&(_=!1)}),_}ec.parse=function(u,p){if(u.length!==2)return p.error("'within' expression requires exactly one argument, but found "+(u.length-1)+" instead.");if(os(u[1])){var _=u[1];if(_.type==="FeatureCollection")for(var R=0;R<_.features.length;++R){var j=_.features[R].geometry.type;if(j==="Polygon"||j==="MultiPolygon")return new ec(_,_.features[R].geometry)}else if(_.type==="Feature"){var $=_.geometry.type;if($==="Polygon"||$==="MultiPolygon")return new ec(_,_.geometry)}else if(_.type==="Polygon"||_.type==="MultiPolygon")return new ec(_,_)}return p.error("'within' expression requires valid geojson object that contains polygon geometry type.")},ec.prototype.evaluate=function(u){if(u.geometry()!=null&&u.canonicalID()!=null){if(u.geometryType()==="Point")return function(p,_){var R=[1/0,1/0,-1/0,-1/0],j=[1/0,1/0,-1/0,-1/0],$=p.canonicalID();if(_.type==="Polygon"){var J=Ql(_.coordinates,j,$),le=Zn(p.geometry(),R,j,$);if(!pc(R,j))return!1;for(var ve=0,Ie=le;vep))throw new Dl("Input is not a number.");$=J-1}return 0}tu.prototype.parse=function(u,p,_,R,j){return j===void 0&&(j={}),p?this.concat(p,_,R)._parse(u,j):this._parse(u,j)},tu.prototype._parse=function(u,p){function _(Ie,Le,ze){return ze==="assert"?new ua(Le,[Ie]):ze==="coerce"?new pu(Le,[Ie]):Ie}if(u!==null&&typeof u!="string"&&typeof u!="boolean"&&typeof u!="number"||(u=["literal",u]),Array.isArray(u)){if(u.length===0)return this.error('Expected an array with at least one element. If you wanted a literal array, use ["literal", []].');var R=u[0];if(typeof R!="string")return this.error("Expression name must be a string, but found "+typeof R+' instead. If you wanted a literal array, use ["literal", [...]].',0),null;var j=this.registry[R];if(j){var $=j.parse(u,this);if(!$)return null;if(this.expectedType){var J=this.expectedType,le=$.type;if(J.kind!=="string"&&J.kind!=="number"&&J.kind!=="boolean"&&J.kind!=="object"&&J.kind!=="array"||le.kind!=="value")if(J.kind!=="color"&&J.kind!=="formatted"&&J.kind!=="resolvedImage"||le.kind!=="value"&&le.kind!=="string"){if(this.checkSubtype(J,le))return null}else $=_($,J,p.typeAnnotation||"coerce");else $=_($,J,p.typeAnnotation||"assert")}if(!($ instanceof Ll)&&$.type.kind!=="resolvedImage"&&function Ie(Le){if(Le instanceof Pu)return Ie(Le.boundExpression);if(Le instanceof Ma&&Le.name==="error"||Le instanceof Mu||Le instanceof ec)return!1;var ze=Le instanceof pu||Le instanceof ua,Ke=!0;return Le.eachChild(function(lt){Ke=ze?Ke&&Ie(lt):Ke&< instanceof Ll}),!!Ke&&sl(Le)&&vl(Le,["zoom","heatmap-density","line-progress","accumulated","is-supported-script"])}($)){var ve=new Vh;try{$=new Ll($.type,$.evaluate(ve))}catch(Ie){return this.error(Ie.message),null}}return $}return this.error('Unknown expression "'+R+'". If you wanted a literal array, use ["literal", [...]].',0)}return this.error(u===void 0?"'undefined' value invalid. Use null instead.":typeof u=="object"?'Bare objects invalid. Use ["literal", {...}] instead.':"Expected an array, but found "+typeof u+" instead.")},tu.prototype.concat=function(u,p,_){var R=typeof u=="number"?this.path.concat(u):this.path,j=_?this.scope.concat(_):this.scope;return new tu(this.registry,R,p||null,j,this.errors)},tu.prototype.error=function(u){for(var p=[],_=arguments.length-1;_-- >0;)p[_]=arguments[_+1];var R=""+this.key+p.map(function(j){return"["+j+"]"}).join("");this.errors.push(new si(R,u))},tu.prototype.checkSubtype=function(u,p){var _=uo(u,p);return _&&this.error(_),_};var xl=function(u,p,_){this.type=u,this.input=p,this.labels=[],this.outputs=[];for(var R=0,j=_;R=J)return p.error('Input/output pairs for "step" expressions must be arranged with input values in strictly ascending order.',ve);var Le=p.parse(le,Ie,j);if(!Le)return null;j=j||Le.type,R.push([J,Le])}return new xl(j,_,R)},xl.prototype.evaluate=function(u){var p=this.labels,_=this.outputs;if(p.length===1)return _[0].evaluate(u);var R=this.input.evaluate(u);if(R<=p[0])return _[0].evaluate(u);var j=p.length;return R>=p[j-1]?_[j-1].evaluate(u):_[La(p,R)].evaluate(u)},xl.prototype.eachChild=function(u){u(this.input);for(var p=0,_=this.outputs;p<_.length;p+=1)u(_[p])},xl.prototype.outputDefined=function(){return this.outputs.every(function(u){return u.outputDefined()})},xl.prototype.serialize=function(){for(var u=["step",this.input.serialize()],p=0;p0&&u.push(this.labels[p]),u.push(this.outputs[p].serialize());return u};var Gh=Object.freeze({__proto__:null,number:Ws,color:function(u,p,_){return new cs(Ws(u.r,p.r,_),Ws(u.g,p.g,_),Ws(u.b,p.b,_),Ws(u.a,p.a,_))},array:function(u,p,_){return u.map(function(R,j){return Ws(R,p[j],_)})}}),Ec=6/29*3*(6/29),Gf=Math.PI/180,Wh=180/Math.PI;function Hd(u){return u>.008856451679035631?Math.pow(u,1/3):u/Ec+4/29}function Cp(u){return u>6/29?u*u*u:Ec*(u-4/29)}function Af(u){return 255*(u<=.0031308?12.92*u:1.055*Math.pow(u,1/2.4)-.055)}function ia(u){return(u/=255)<=.04045?u/12.92:Math.pow((u+.055)/1.055,2.4)}function mh(u){var p=ia(u.r),_=ia(u.g),R=ia(u.b),j=Hd((.4124564*p+.3575761*_+.1804375*R)/.95047),$=Hd((.2126729*p+.7151522*_+.072175*R)/1);return{l:116*$-16,a:500*(j-$),b:200*($-Hd((.0193339*p+.119192*_+.9503041*R)/1.08883)),alpha:u.a}}function ms(u){var p=(u.l+16)/116,_=isNaN(u.a)?p:p+u.a/500,R=isNaN(u.b)?p:p-u.b/200;return p=1*Cp(p),_=.95047*Cp(_),R=1.08883*Cp(R),new cs(Af(3.2404542*_-1.5371385*p-.4985314*R),Af(-.969266*_+1.8760108*p+.041556*R),Af(.0556434*_-.2040259*p+1.0572252*R),u.alpha)}function Ao(u,p,_){var R=p-u;return u+_*(R>180||R<-180?R-360*Math.round(R/360):R)}var qh={forward:mh,reverse:ms,interpolate:function(u,p,_){return{l:Ws(u.l,p.l,_),a:Ws(u.a,p.a,_),b:Ws(u.b,p.b,_),alpha:Ws(u.alpha,p.alpha,_)}}},us={forward:function(u){var p=mh(u),_=p.l,R=p.a,j=p.b,$=Math.atan2(j,R)*Wh;return{h:$<0?$+360:$,c:Math.sqrt(R*R+j*j),l:_,alpha:u.a}},reverse:function(u){var p=u.h*Gf,_=u.c;return ms({l:u.l,a:Math.cos(p)*_,b:Math.sin(p)*_,alpha:u.alpha})},interpolate:function(u,p,_){return{h:Ao(u.h,p.h,_),c:Ws(u.c,p.c,_),l:Ws(u.l,p.l,_),alpha:Ws(u.alpha,p.alpha,_)}}},Gd=Object.freeze({__proto__:null,lab:qh,hcl:us}),q=function(u,p,_,R,j){this.type=u,this.operator=p,this.interpolation=_,this.input=R,this.labels=[],this.outputs=[];for(var $=0,J=j;$1}))return p.error("Cubic bezier interpolation requires four numeric arguments with values between 0 and 1.",1);R={name:"cubic-bezier",controlPoints:le}}if(u.length-1<4)return p.error("Expected at least 4 arguments, but found only "+(u.length-1)+".");if((u.length-1)%2!=0)return p.error("Expected an even number of arguments.");if(!(j=p.parse(j,2,pr)))return null;var ve=[],Ie=null;_==="interpolate-hcl"||_==="interpolate-lab"?Ie=Mi:p.expectedType&&p.expectedType.kind!=="value"&&(Ie=p.expectedType);for(var Le=0;Le<$.length;Le+=2){var ze=$[Le],Ke=$[Le+1],lt=Le+3,Mt=Le+4;if(typeof ze!="number")return p.error('Input/output pairs for "interpolate" expressions must be defined using literal numeric values (not computed expressions) for the input values.',lt);if(ve.length&&ve[ve.length-1][0]>=ze)return p.error('Input/output pairs for "interpolate" expressions must be arranged with input values in strictly ascending order.',lt);var Dt=p.parse(Ke,Mt,Ie);if(!Dt)return null;Ie=Ie||Dt.type,ve.push([ze,Dt])}return Ie.kind==="number"||Ie.kind==="color"||Ie.kind==="array"&&Ie.itemType.kind==="number"&&typeof Ie.N=="number"?new q(Ie,_,R,j,ve):p.error("Type "+wo(Ie)+" is not interpolatable.")},q.prototype.evaluate=function(u){var p=this.labels,_=this.outputs;if(p.length===1)return _[0].evaluate(u);var R=this.input.evaluate(u);if(R<=p[0])return _[0].evaluate(u);var j=p.length;if(R>=p[j-1])return _[j-1].evaluate(u);var $=La(p,R),J=q.interpolationFactor(this.interpolation,R,p[$],p[$+1]),le=_[$].evaluate(u),ve=_[$+1].evaluate(u);return this.operator==="interpolate"?Gh[this.type.kind.toLowerCase()](le,ve,J):this.operator==="interpolate-hcl"?us.reverse(us.interpolate(us.forward(le),us.forward(ve),J)):qh.reverse(qh.interpolate(qh.forward(le),qh.forward(ve),J))},q.prototype.eachChild=function(u){u(this.input);for(var p=0,_=this.outputs;p<_.length;p+=1)u(_[p])},q.prototype.outputDefined=function(){return this.outputs.every(function(u){return u.outputDefined()})},q.prototype.serialize=function(){var u;u=this.interpolation.name==="linear"?["linear"]:this.interpolation.name==="exponential"?this.interpolation.base===1?["linear"]:["exponential",this.interpolation.base]:["cubic-bezier"].concat(this.interpolation.controlPoints);for(var p=[this.operator,u,this.input.serialize()],_=0;_=_.length)throw new Dl("Array index out of bounds: "+p+" > "+(_.length-1)+".");if(p!==Math.floor(p))throw new Dl("Array index must be an integer, but found "+p+" instead.");return _[p]},He.prototype.eachChild=function(u){u(this.index),u(this.input)},He.prototype.outputDefined=function(){return!1},He.prototype.serialize=function(){return["at",this.index.serialize(),this.input.serialize()]};var We=function(u,p){this.type=Ii,this.needle=u,this.haystack=p};We.parse=function(u,p){if(u.length!==3)return p.error("Expected 2 arguments, but found "+(u.length-1)+" instead.");var _=p.parse(u[1],1,zi),R=p.parse(u[2],2,zi);return _&&R?Qn(_.type,[Ii,Di,pr,fi,zi])?new We(_,R):p.error("Expected first argument to be of type boolean, string, number or null, but found "+wo(_.type)+" instead"):null},We.prototype.evaluate=function(u){var p=this.needle.evaluate(u),_=this.haystack.evaluate(u);if(!_)return!1;if(!Ds(p,["boolean","string","number","null"]))throw new Dl("Expected first argument to be of type boolean, string, number or null, but found "+wo(ca(p))+" instead.");if(!Ds(_,["string","array"]))throw new Dl("Expected second argument to be of type array or string, but found "+wo(ca(_))+" instead.");return _.indexOf(p)>=0},We.prototype.eachChild=function(u){u(this.needle),u(this.haystack)},We.prototype.outputDefined=function(){return!0},We.prototype.serialize=function(){return["in",this.needle.serialize(),this.haystack.serialize()]};var ot=function(u,p,_){this.type=pr,this.needle=u,this.haystack=p,this.fromIndex=_};ot.parse=function(u,p){if(u.length<=2||u.length>=5)return p.error("Expected 3 or 4 arguments, but found "+(u.length-1)+" instead.");var _=p.parse(u[1],1,zi),R=p.parse(u[2],2,zi);if(!_||!R)return null;if(!Qn(_.type,[Ii,Di,pr,fi,zi]))return p.error("Expected first argument to be of type boolean, string, number or null, but found "+wo(_.type)+" instead");if(u.length===4){var j=p.parse(u[3],3,pr);return j?new ot(_,R,j):null}return new ot(_,R)},ot.prototype.evaluate=function(u){var p=this.needle.evaluate(u),_=this.haystack.evaluate(u);if(!Ds(p,["boolean","string","number","null"]))throw new Dl("Expected first argument to be of type boolean, string, number or null, but found "+wo(ca(p))+" instead.");if(!Ds(_,["string","array"]))throw new Dl("Expected second argument to be of type array or string, but found "+wo(ca(_))+" instead.");if(this.fromIndex){var R=this.fromIndex.evaluate(u);return _.indexOf(p,R)}return _.indexOf(p)},ot.prototype.eachChild=function(u){u(this.needle),u(this.haystack),this.fromIndex&&u(this.fromIndex)},ot.prototype.outputDefined=function(){return!1},ot.prototype.serialize=function(){if(this.fromIndex!=null&&this.fromIndex!==void 0){var u=this.fromIndex.serialize();return["index-of",this.needle.serialize(),this.haystack.serialize(),u]}return["index-of",this.needle.serialize(),this.haystack.serialize()]};var rr=function(u,p,_,R,j,$){this.inputType=u,this.type=p,this.input=_,this.cases=R,this.outputs=j,this.otherwise=$};rr.parse=function(u,p){if(u.length<5)return p.error("Expected at least 4 arguments, but found only "+(u.length-1)+".");if(u.length%2!=1)return p.error("Expected an even number of arguments.");var _,R;p.expectedType&&p.expectedType.kind!=="value"&&(R=p.expectedType);for(var j={},$=[],J=2;JNumber.MAX_SAFE_INTEGER)return Ie.error("Branch labels must be integers no larger than "+Number.MAX_SAFE_INTEGER+".");if(typeof Ke=="number"&&Math.floor(Ke)!==Ke)return Ie.error("Numeric branch labels must be integer values.");if(_){if(Ie.checkSubtype(_,ca(Ke)))return null}else _=ca(Ke);if(j[String(Ke)]!==void 0)return Ie.error("Branch labels must be unique.");j[String(Ke)]=$.length}var lt=p.parse(ve,J,R);if(!lt)return null;R=R||lt.type,$.push(lt)}var Mt=p.parse(u[1],1,zi);if(!Mt)return null;var Dt=p.parse(u[u.length-1],u.length-1,R);return Dt?Mt.type.kind!=="value"&&p.concat(1).checkSubtype(_,Mt.type)?null:new rr(_,R,Mt,j,$,Dt):null},rr.prototype.evaluate=function(u){var p=this.input.evaluate(u);return(ca(p)===this.inputType&&this.outputs[this.cases[p]]||this.otherwise).evaluate(u)},rr.prototype.eachChild=function(u){u(this.input),this.outputs.forEach(u),u(this.otherwise)},rr.prototype.outputDefined=function(){return this.outputs.every(function(u){return u.outputDefined()})&&this.otherwise.outputDefined()},rr.prototype.serialize=function(){for(var u=this,p=["match",this.input.serialize()],_=[],R={},j=0,$=Object.keys(this.cases).sort();j<$.length;j+=1){var J=$[j];(ze=R[this.cases[J]])===void 0?(R[this.cases[J]]=_.length,_.push([this.cases[J],[J]])):_[ze][1].push(J)}for(var le=function(lt){return u.inputType.kind==="number"?Number(lt):lt},ve=0,Ie=_;ve=5)return p.error("Expected 3 or 4 arguments, but found "+(u.length-1)+" instead.");var _=p.parse(u[1],1,zi),R=p.parse(u[2],2,pr);if(!_||!R)return null;if(!Qn(_.type,[No(zi),Di,zi]))return p.error("Expected first argument to be of type array or string, but found "+wo(_.type)+" instead");if(u.length===4){var j=p.parse(u[3],3,pr);return j?new cr(_.type,_,R,j):null}return new cr(_.type,_,R)},cr.prototype.evaluate=function(u){var p=this.input.evaluate(u),_=this.beginIndex.evaluate(u);if(!Ds(p,["string","array"]))throw new Dl("Expected first argument to be of type array or string, but found "+wo(ca(p))+" instead.");if(this.endIndex){var R=this.endIndex.evaluate(u);return p.slice(_,R)}return p.slice(_)},cr.prototype.eachChild=function(u){u(this.input),u(this.beginIndex),this.endIndex&&u(this.endIndex)},cr.prototype.outputDefined=function(){return!1},cr.prototype.serialize=function(){if(this.endIndex!=null&&this.endIndex!==void 0){var u=this.endIndex.serialize();return["slice",this.input.serialize(),this.beginIndex.serialize(),u]}return["slice",this.input.serialize(),this.beginIndex.serialize()]};var Bi=vr("==",function(u,p,_){return p===_},li),gn=vr("!=",function(u,p,_){return p!==_},function(u,p,_,R){return!li(0,p,_,R)}),gs=vr("<",function(u,p,_){return p<_},function(u,p,_,R){return R.compare(p,_)<0}),Mo=vr(">",function(u,p,_){return p>_},function(u,p,_,R){return R.compare(p,_)>0}),bl=vr("<=",function(u,p,_){return p<=_},function(u,p,_,R){return R.compare(p,_)<=0}),al=vr(">=",function(u,p,_){return p>=_},function(u,p,_,R){return R.compare(p,_)>=0}),Da=function(u,p,_,R,j){this.type=Di,this.number=u,this.locale=p,this.currency=_,this.minFractionDigits=R,this.maxFractionDigits=j};Da.parse=function(u,p){if(u.length!==3)return p.error("Expected two arguments.");var _=p.parse(u[1],1,pr);if(!_)return null;var R=u[2];if(typeof R!="object"||Array.isArray(R))return p.error("NumberFormat options argument must be an object.");var j=null;if(R.locale&&!(j=p.parse(R.locale,1,Di)))return null;var $=null;if(R.currency&&!($=p.parse(R.currency,1,Di)))return null;var J=null;if(R["min-fraction-digits"]&&!(J=p.parse(R["min-fraction-digits"],1,pr)))return null;var le=null;return R["max-fraction-digits"]&&!(le=p.parse(R["max-fraction-digits"],1,pr))?null:new Da(_,j,$,J,le)},Da.prototype.evaluate=function(u){return new Intl.NumberFormat(this.locale?this.locale.evaluate(u):[],{style:this.currency?"currency":"decimal",currency:this.currency?this.currency.evaluate(u):void 0,minimumFractionDigits:this.minFractionDigits?this.minFractionDigits.evaluate(u):void 0,maximumFractionDigits:this.maxFractionDigits?this.maxFractionDigits.evaluate(u):void 0}).format(this.number.evaluate(u))},Da.prototype.eachChild=function(u){u(this.number),this.locale&&u(this.locale),this.currency&&u(this.currency),this.minFractionDigits&&u(this.minFractionDigits),this.maxFractionDigits&&u(this.maxFractionDigits)},Da.prototype.outputDefined=function(){return!1},Da.prototype.serialize=function(){var u={};return this.locale&&(u.locale=this.locale.serialize()),this.currency&&(u.currency=this.currency.serialize()),this.minFractionDigits&&(u["min-fraction-digits"]=this.minFractionDigits.serialize()),this.maxFractionDigits&&(u["max-fraction-digits"]=this.maxFractionDigits.serialize()),["number-format",this.number.serialize(),u]};var Ka=function(u){this.type=pr,this.input=u};Ka.parse=function(u,p){if(u.length!==2)return p.error("Expected 1 argument, but found "+(u.length-1)+" instead.");var _=p.parse(u[1],1);return _?_.type.kind!=="array"&&_.type.kind!=="string"&&_.type.kind!=="value"?p.error("Expected argument of type string or array, but found "+wo(_.type)+" instead."):new Ka(_):null},Ka.prototype.evaluate=function(u){var p=this.input.evaluate(u);if(typeof p=="string"||Array.isArray(p))return p.length;throw new Dl("Expected value to be of type string or array, but found "+wo(ca(p))+" instead.")},Ka.prototype.eachChild=function(u){u(this.input)},Ka.prototype.outputDefined=function(){return!1},Ka.prototype.serialize=function(){var u=["length"];return this.eachChild(function(p){u.push(p.serialize())}),u};var Yn={"==":Bi,"!=":gn,">":Mo,"<":gs,">=":al,"<=":bl,array:ua,at:He,boolean:ua,case:Ut,coalesce:pe,collator:Mu,format:Tc,image:Uc,in:We,"index-of":ot,interpolate:q,"interpolate-hcl":q,"interpolate-lab":q,length:Ka,let:be,literal:Ll,match:rr,number:ua,"number-format":Da,object:ua,slice:cr,step:xl,string:ua,"to-boolean":pu,"to-color":pu,"to-number":pu,"to-string":pu,var:Pu,within:ec};function Er(u,p){var _=p[0],R=p[1],j=p[2],$=p[3];_=_.evaluate(u),R=R.evaluate(u),j=j.evaluate(u);var J=$?$.evaluate(u):1,le=md(_,R,j,J);if(le)throw new Dl(le);return new cs(_/255*J,R/255*J,j/255*J,J)}function Gr(u,p){return u in p}function wi(u,p){var _=p[u];return _===void 0?null:_}function ni(u){return{type:u}}function b(u){return{result:"success",value:u}}function Po(u){return{result:"error",value:u}}function _o(u){return u["property-type"]==="data-driven"||u["property-type"]==="cross-faded-data-driven"}function Ye(u){return!!u.expression&&u.expression.parameters.indexOf("zoom")>-1}function Ms(u){return!!u.expression&&u.expression.interpolated}function ao(u){return u instanceof Number?"number":u instanceof String?"string":u instanceof Boolean?"boolean":Array.isArray(u)?"array":u===null?"null":typeof u}function Ps(u){return typeof u=="object"&&u!==null&&!Array.isArray(u)}function Rs(u){return u}function Go(u,p,_){return u!==void 0?u:p!==void 0?p:_!==void 0?_:void 0}function Qs(u,p,_,R,j){return Go(typeof _===j?R[_]:void 0,u.default,p.default)}function Ts(u,p,_){if(ao(_)!=="number")return Go(u.default,p.default);var R=u.stops.length;if(R===1||_<=u.stops[0][0])return u.stops[0][1];if(_>=u.stops[R-1][0])return u.stops[R-1][1];var j=La(u.stops.map(function($){return $[0]}),_);return u.stops[j][1]}function Os(u,p,_){var R=u.base!==void 0?u.base:1;if(ao(_)!=="number")return Go(u.default,p.default);var j=u.stops.length;if(j===1||_<=u.stops[0][0])return u.stops[0][1];if(_>=u.stops[j-1][0])return u.stops[j-1][1];var $=La(u.stops.map(function(ze){return ze[0]}),_),J=function(ze,Ke,lt,Mt){var Dt=Mt-lt,tr=ze-lt;return Dt===0?0:Ke===1?tr/Dt:(Math.pow(Ke,tr)-1)/(Math.pow(Ke,Dt)-1)}(_,R,u.stops[$][0],u.stops[$+1][0]),le=u.stops[$][1],ve=u.stops[$+1][1],Ie=Gh[p.type]||Rs;if(u.colorSpace&&u.colorSpace!=="rgb"){var Le=Gd[u.colorSpace];Ie=function(ze,Ke){return Le.reverse(Le.interpolate(Le.forward(ze),Le.forward(Ke),J))}}return typeof le.evaluate=="function"?{evaluate:function(){for(var ze=[],Ke=arguments.length;Ke--;)ze[Ke]=arguments[Ke];var lt=le.evaluate.apply(void 0,ze),Mt=ve.evaluate.apply(void 0,ze);if(lt!==void 0&&Mt!==void 0)return Ie(lt,Mt,J)}}:Ie(le,ve,J)}function gh(u,p,_){return p.type==="color"?_=cs.parse(_):p.type==="formatted"?_=yl.fromString(_.toString()):p.type==="resolvedImage"?_=Ya.fromString(_.toString()):ao(_)===p.type||p.type==="enum"&&p.values[_]||(_=void 0),Go(_,u.default,p.default)}Ma.register(Yn,{error:[{kind:"error"},[Di],function(u,p){throw new Dl(p[0].evaluate(u))}],typeof:[Di,[zi],function(u,p){return wo(ca(p[0].evaluate(u)))}],"to-rgba":[No(pr,4),[Mi],function(u,p){return p[0].evaluate(u).toArray()}],rgb:[Mi,[pr,pr,pr],Er],rgba:[Mi,[pr,pr,pr,pr],Er],has:{type:Ii,overloads:[[[Di],function(u,p){return Gr(p[0].evaluate(u),u.properties())}],[[Di,Ni],function(u,p){var _=p[1];return Gr(p[0].evaluate(u),_.evaluate(u))}]]},get:{type:zi,overloads:[[[Di],function(u,p){return wi(p[0].evaluate(u),u.properties())}],[[Di,Ni],function(u,p){var _=p[1];return wi(p[0].evaluate(u),_.evaluate(u))}]]},"feature-state":[zi,[Di],function(u,p){return wi(p[0].evaluate(u),u.featureState||{})}],properties:[Ni,[],function(u){return u.properties()}],"geometry-type":[Di,[],function(u){return u.geometryType()}],id:[zi,[],function(u){return u.id()}],zoom:[pr,[],function(u){return u.globals.zoom}],"heatmap-density":[pr,[],function(u){return u.globals.heatmapDensity||0}],"line-progress":[pr,[],function(u){return u.globals.lineProgress||0}],accumulated:[zi,[],function(u){return u.globals.accumulated===void 0?null:u.globals.accumulated}],"+":[pr,ni(pr),function(u,p){for(var _=0,R=0,j=p;R":[Ii,[Di,zi],function(u,p){var _=p[0],R=p[1],j=u.properties()[_.value],$=R.value;return typeof j==typeof $&&j>$}],"filter-id->":[Ii,[zi],function(u,p){var _=p[0],R=u.id(),j=_.value;return typeof R==typeof j&&R>j}],"filter-<=":[Ii,[Di,zi],function(u,p){var _=p[0],R=p[1],j=u.properties()[_.value],$=R.value;return typeof j==typeof $&&j<=$}],"filter-id-<=":[Ii,[zi],function(u,p){var _=p[0],R=u.id(),j=_.value;return typeof R==typeof j&&R<=j}],"filter->=":[Ii,[Di,zi],function(u,p){var _=p[0],R=p[1],j=u.properties()[_.value],$=R.value;return typeof j==typeof $&&j>=$}],"filter-id->=":[Ii,[zi],function(u,p){var _=p[0],R=u.id(),j=_.value;return typeof R==typeof j&&R>=j}],"filter-has":[Ii,[zi],function(u,p){return p[0].value in u.properties()}],"filter-has-id":[Ii,[],function(u){return u.id()!==null&&u.id()!==void 0}],"filter-type-in":[Ii,[No(Di)],function(u,p){return p[0].value.indexOf(u.geometryType())>=0}],"filter-id-in":[Ii,[No(zi)],function(u,p){return p[0].value.indexOf(u.id())>=0}],"filter-in-small":[Ii,[Di,No(zi)],function(u,p){var _=p[0];return p[1].value.indexOf(u.properties()[_.value])>=0}],"filter-in-large":[Ii,[Di,No(zi)],function(u,p){var _=p[0],R=p[1];return function(j,$,J,le){for(;J<=le;){var ve=J+le>>1;if($[ve]===j)return!0;$[ve]>j?le=ve-1:J=ve+1}return!1}(u.properties()[_.value],R.value,0,R.value.length-1)}],all:{type:Ii,overloads:[[[Ii,Ii],function(u,p){var _=p[1];return p[0].evaluate(u)&&_.evaluate(u)}],[ni(Ii),function(u,p){for(var _=0,R=p;_0&&typeof u[0]=="string"&&u[0]in Yn}function mc(u,p){var _=new tu(Yn,[],p?function(j){var $={color:Mi,string:Di,number:pr,enum:Di,boolean:Ii,formatted:Ls,resolvedImage:co};return j.type==="array"?No($[j.value]||zi,j.length):$[j.type]}(p):void 0),R=_.parse(u,void 0,void 0,void 0,p&&p.type==="string"?{typeAnnotation:"coerce"}:void 0);return R?b(new Ss(R,p)):Po(_.errors)}Ss.prototype.evaluateWithoutErrorHandling=function(u,p,_,R,j,$){return this._evaluator.globals=u,this._evaluator.feature=p,this._evaluator.featureState=_,this._evaluator.canonical=R,this._evaluator.availableImages=j||null,this._evaluator.formattedSection=$,this.expression.evaluate(this._evaluator)},Ss.prototype.evaluate=function(u,p,_,R,j,$){this._evaluator.globals=u,this._evaluator.feature=p||null,this._evaluator.featureState=_||null,this._evaluator.canonical=R,this._evaluator.availableImages=j||null,this._evaluator.formattedSection=$||null;try{var J=this.expression.evaluate(this._evaluator);if(J==null||typeof J=="number"&&J!=J)return this._defaultValue;if(this._enumValues&&!(J in this._enumValues))throw new Dl("Expected value to be one of "+Object.keys(this._enumValues).map(function(le){return JSON.stringify(le)}).join(", ")+", but found "+JSON.stringify(J)+" instead.");return J}catch(le){return this._warningHistory[le.message]||(this._warningHistory[le.message]=!0,typeof console<"u"&&console.warn(le.message)),this._defaultValue}};var Qa=function(u,p){this.kind=u,this._styleExpression=p,this.isStateDependent=u!=="constant"&&!Ol(p.expression)};Qa.prototype.evaluateWithoutErrorHandling=function(u,p,_,R,j,$){return this._styleExpression.evaluateWithoutErrorHandling(u,p,_,R,j,$)},Qa.prototype.evaluate=function(u,p,_,R,j,$){return this._styleExpression.evaluate(u,p,_,R,j,$)};var Ru=function(u,p,_,R){this.kind=u,this.zoomStops=_,this._styleExpression=p,this.isStateDependent=u!=="camera"&&!Ol(p.expression),this.interpolationType=R};function gc(u,p){if((u=mc(u,p)).result==="error")return u;var _=u.value.expression,R=sl(_);if(!R&&!_o(p))return Po([new si("","data expressions not supported")]);var j=vl(_,["zoom"]);if(!j&&!Ye(p))return Po([new si("","zoom expressions not supported")]);var $=function J(le){var ve=null;if(le instanceof be)ve=J(le.result);else if(le instanceof pe)for(var Ie=0,Le=le.args;IeR.maximum?[new Ot(p,_,_+" is greater than the maximum value "+R.maximum)]:[]}function dt(u){var p,_,R,j=u.valueSpec,$=ui(u.value.type),J={},le=$!=="categorical"&&u.value.property===void 0,ve=!le,Ie=ao(u.value.stops)==="array"&&ao(u.value.stops[0])==="array"&&ao(u.value.stops[0][0])==="object",Le=Fl({key:u.key,value:u.value,valueSpec:u.styleSpec.function,style:u.style,styleSpec:u.styleSpec,objectElementValidators:{stops:function(lt){if($==="identity")return[new Ot(lt.key,lt.value,'identity function may not have a "stops" property')];var Mt=[],Dt=lt.value;return Mt=Mt.concat(Ac({key:lt.key,value:Dt,valueSpec:lt.valueSpec,style:lt.style,styleSpec:lt.styleSpec,arrayElementValidator:ze})),ao(Dt)==="array"&&Dt.length===0&&Mt.push(new Ot(lt.key,Dt,"array must have at least one stop")),Mt},default:function(lt){return Hi({key:lt.key,value:lt.value,valueSpec:j,style:lt.style,styleSpec:lt.styleSpec})}}});return $==="identity"&&le&&Le.push(new Ot(u.key,u.value,'missing required property "property"')),$==="identity"||u.value.stops||Le.push(new Ot(u.key,u.value,'missing required property "stops"')),$==="exponential"&&u.valueSpec.expression&&!Ms(u.valueSpec)&&Le.push(new Ot(u.key,u.value,"exponential functions not supported")),u.styleSpec.$version>=8&&(ve&&!_o(u.valueSpec)?Le.push(new Ot(u.key,u.value,"property functions not supported")):le&&!Ye(u.valueSpec)&&Le.push(new Ot(u.key,u.value,"zoom functions not supported"))),$!=="categorical"&&!Ie||u.value.property!==void 0||Le.push(new Ot(u.key,u.value,'"property" property is required')),Le;function ze(lt){var Mt=[],Dt=lt.value,tr=lt.key;if(ao(Dt)!=="array")return[new Ot(tr,Dt,"array expected, "+ao(Dt)+" found")];if(Dt.length!==2)return[new Ot(tr,Dt,"array length 2 expected, length "+Dt.length+" found")];if(Ie){if(ao(Dt[0])!=="object")return[new Ot(tr,Dt,"object expected, "+ao(Dt[0])+" found")];if(Dt[0].zoom===void 0)return[new Ot(tr,Dt,"object stop key must have zoom")];if(Dt[0].value===void 0)return[new Ot(tr,Dt,"object stop key must have value")];if(R&&R>ui(Dt[0].zoom))return[new Ot(tr,Dt[0].zoom,"stop zoom values must appear in ascending order")];ui(Dt[0].zoom)!==R&&(R=ui(Dt[0].zoom),_=void 0,J={}),Mt=Mt.concat(Fl({key:tr+"[0]",value:Dt[0],valueSpec:{zoom:{}},style:lt.style,styleSpec:lt.styleSpec,objectElementValidators:{zoom:qn,value:Ke}}))}else Mt=Mt.concat(Ke({key:tr+"[0]",value:Dt[0],valueSpec:{},style:lt.style,styleSpec:lt.styleSpec},Dt));return Ah(Hr(Dt[1]))?Mt.concat([new Ot(tr+"[1]",Dt[1],"expressions are not allowed in function stops.")]):Mt.concat(Hi({key:tr+"[1]",value:Dt[1],valueSpec:j,style:lt.style,styleSpec:lt.styleSpec}))}function Ke(lt,Mt){var Dt=ao(lt.value),tr=ui(lt.value),qt=lt.value!==null?lt.value:Mt;if(p){if(Dt!==p)return[new Ot(lt.key,qt,Dt+" stop domain type must match previous stop domain type "+p)]}else p=Dt;if(Dt!=="number"&&Dt!=="string"&&Dt!=="boolean")return[new Ot(lt.key,qt,"stop domain value must be a number, string, or boolean")];if(Dt!=="number"&&$!=="categorical"){var ur="number expected, "+Dt+" found";return _o(j)&&$===void 0&&(ur+='\nIf you intended to use a categorical function, specify `"type": "categorical"`.'),[new Ot(lt.key,qt,ur)]}return $!=="categorical"||Dt!=="number"||isFinite(tr)&&Math.floor(tr)===tr?$!=="categorical"&&Dt==="number"&&_!==void 0&&tr<_?[new Ot(lt.key,qt,"stop domain values must appear in ascending order")]:(_=tr,$==="categorical"&&tr in J?[new Ot(lt.key,qt,"stop domain values must be unique")]:(J[tr]=!0,[])):[new Ot(lt.key,qt,"integer expected, found "+tr)]}}function Fn(u){var p=(u.expressionContext==="property"?gc:mc)(Hr(u.value),u.valueSpec);if(p.result==="error")return p.value.map(function(R){return new Ot(""+u.key+R.key,u.value,R.message)});var _=p.value.expression||p.value._styleExpression.expression;if(u.expressionContext==="property"&&u.propertyKey==="text-font"&&!_.outputDefined())return[new Ot(u.key,u.value,'Invalid data expression for "'+u.propertyKey+'". Output values must be contained as literals within the expression.')];if(u.expressionContext==="property"&&u.propertyType==="layout"&&!Ol(_))return[new Ot(u.key,u.value,'"feature-state" data expressions are not supported with layout properties.')];if(u.expressionContext==="filter"&&!Ol(_))return[new Ot(u.key,u.value,'"feature-state" data expressions are not supported with filters.')];if(u.expressionContext&&u.expressionContext.indexOf("cluster")===0){if(!vl(_,["zoom","feature-state"]))return[new Ot(u.key,u.value,'"zoom" and "feature-state" expressions are not supported with cluster properties.')];if(u.expressionContext==="cluster-initial"&&!sl(_))return[new Ot(u.key,u.value,"Feature data expressions are not supported with initial expression part of cluster properties.")]}return[]}function $h(u){var p=u.key,_=u.value,R=u.valueSpec,j=[];return Array.isArray(R.values)?R.values.indexOf(ui(_))===-1&&j.push(new Ot(p,_,"expected one of ["+R.values.join(", ")+"], "+JSON.stringify(_)+" found")):Object.keys(R.values).indexOf(ui(_))===-1&&j.push(new Ot(p,_,"expected one of ["+Object.keys(R.values).join(", ")+"], "+JSON.stringify(_)+" found")),j}function _f(u){if(u===!0||u===!1)return!0;if(!Array.isArray(u)||u.length===0)return!1;switch(u[0]){case"has":return u.length>=2&&u[1]!=="$id"&&u[1]!=="$type";case"in":return u.length>=3&&(typeof u[1]!="string"||Array.isArray(u[2]));case"!in":case"!has":case"none":return!1;case"==":case"!=":case">":case">=":case"<":case"<=":return u.length!==3||Array.isArray(u[1])||Array.isArray(u[2]);case"any":case"all":for(var p=0,_=u.slice(1);p<_.length;p+=1){var R=_[p];if(!_f(R)&&typeof R!="boolean")return!1}return!0;default:return!0}}_h.deserialize=function(u){return new _h(u._parameters,u._specification)},_h.serialize=function(u){return{_parameters:u._parameters,_specification:u._specification}};var Xh={type:"boolean",default:!1,transition:!1,"property-type":"data-driven",expression:{interpolated:!1,parameters:["zoom","feature"]}};function Wd(u){if(u==null)return{filter:function(){return!0},needGeometry:!1};_f(u)||(u=et(u));var p=mc(u,Xh);if(p.result==="error")throw new Error(p.value.map(function(_){return _.key+": "+_.message}).join(", "));return{filter:function(_,R,j){return p.value.evaluate(_,R,{},j)},needGeometry:function _(R){if(!Array.isArray(R))return!1;if(R[0]==="within")return!0;for(var j=1;jp?1:0}function et(u){if(!u)return!0;var p,_=u[0];return u.length<=1?_!=="any":_==="=="?yf(u[1],u[2],"=="):_==="!="?qf(yf(u[1],u[2],"==")):_==="<"||_===">"||_==="<="||_===">="?yf(u[1],u[2],_):_==="any"?(p=u.slice(1),["any"].concat(p.map(et))):_==="all"?["all"].concat(u.slice(1).map(et)):_==="none"?["all"].concat(u.slice(1).map(et).map(qf)):_==="in"?Bu(u[1],u.slice(2)):_==="!in"?qf(Bu(u[1],u.slice(2))):_==="has"?Wf(u[1]):_==="!has"?qf(Wf(u[1])):_!=="within"||u}function yf(u,p,_){switch(u){case"$type":return["filter-type-"+_,p];case"$id":return["filter-id-"+_,p];default:return["filter-"+_,u,p]}}function Bu(u,p){if(p.length===0)return!1;switch(u){case"$type":return["filter-type-in",["literal",p]];case"$id":return["filter-id-in",["literal",p]];default:return p.length>200&&!p.some(function(_){return typeof _!=typeof p[0]})?["filter-in-large",u,["literal",p.sort(Ad)]]:["filter-in-small",u,["literal",p]]}}function Wf(u){switch(u){case"$type":return!0;case"$id":return["filter-has-id"];default:return["filter-has",u]}}function qf(u){return["!",u]}function Bt(u){return _f(Hr(u.value))?Fn(ei({},u,{expressionContext:"filter",valueSpec:{value:"boolean"}})):function p(_){var R=_.value,j=_.key;if(ao(R)!=="array")return[new Ot(j,R,"array expected, "+ao(R)+" found")];var $,J=_.styleSpec,le=[];if(R.length<1)return[new Ot(j,R,"filter array must have at least 1 element")];switch(le=le.concat($h({key:j+"[0]",value:R[0],valueSpec:J.filter_operator,style:_.style,styleSpec:_.styleSpec})),ui(R[0])){case"<":case"<=":case">":case">=":R.length>=2&&ui(R[1])==="$type"&&le.push(new Ot(j,R,'"$type" cannot be use with operator "'+R[0]+'"'));case"==":case"!=":R.length!==3&&le.push(new Ot(j,R,'filter array for operator "'+R[0]+'" must have 3 elements'));case"in":case"!in":R.length>=2&&($=ao(R[1]))!=="string"&&le.push(new Ot(j+"[1]",R[1],"string expected, "+$+" found"));for(var ve=2;ve=Le[lt+0]&&R>=Le[lt+1])?(J[Ke]=!0,$.push(Ie[Ke])):J[Ke]=!1}}},Sl.prototype._forEachCell=function(u,p,_,R,j,$,J,le){for(var ve=this._convertToCellCoord(u),Ie=this._convertToCellCoord(p),Le=this._convertToCellCoord(_),ze=this._convertToCellCoord(R),Ke=ve;Ke<=Le;Ke++)for(var lt=Ie;lt<=ze;lt++){var Mt=this.d*lt+Ke;if((!le||le(this._convertFromCellCoord(Ke),this._convertFromCellCoord(lt),this._convertFromCellCoord(Ke+1),this._convertFromCellCoord(lt+1)))&&j.call(this,u,p,_,R,Mt,$,J,le))return}},Sl.prototype._convertFromCellCoord=function(u){return(u-this.padding)/this.scale},Sl.prototype._convertToCellCoord=function(u){return Math.max(0,Math.min(this.d-1,Math.floor(u*this.scale)+this.padding))},Sl.prototype.toArrayBuffer=function(){if(this.arrayBuffer)return this.arrayBuffer;for(var u=this.cells,p=3+this.cells.length+1+1,_=0,R=0;R=0)){var Le=u[Ie];ve[Ie]=Pa[le].shallow.indexOf(Ie)>=0?Le:ru(Le,p)}u instanceof Error&&(ve.message=u.message)}if(ve.$name)throw new Error("$name property is reserved for worker serialization logic.");return le!=="Object"&&(ve.$name=le),ve}throw new Error("can't serialize object of type "+typeof u)}function kl(u){if(u==null||typeof u=="boolean"||typeof u=="number"||typeof u=="string"||u instanceof Boolean||u instanceof Number||u instanceof String||u instanceof Date||u instanceof RegExp||qd(u)||yd(u)||ArrayBuffer.isView(u)||u instanceof _d)return u;if(Array.isArray(u))return u.map(kl);if(typeof u=="object"){var p=u.$name||"Object",_=Pa[p].klass;if(!_)throw new Error("can't deserialize unregistered class "+p);if(_.deserialize)return _.deserialize(u);for(var R=Object.create(_.prototype),j=0,$=Object.keys(u);j<$.length;j+=1){var J=$[j];if(J!=="$name"){var le=u[J];R[J]=Pa[p].shallow.indexOf(J)>=0?le:kl(le)}}return R}throw new Error("can't deserialize object of type "+typeof u)}var Ip=function(){this.first=!0};Ip.prototype.update=function(u,p){var _=Math.floor(u);return this.first?(this.first=!1,this.lastIntegerZoom=_,this.lastIntegerZoomTime=0,this.lastZoom=u,this.lastFloorZoom=_,!0):(this.lastFloorZoom>_?(this.lastIntegerZoom=_+1,this.lastIntegerZoomTime=p):this.lastFloorZoom<_&&(this.lastIntegerZoom=_,this.lastIntegerZoomTime=p),u!==this.lastZoom&&(this.lastZoom=u,this.lastFloorZoom=_,!0))};var Fi={"Latin-1 Supplement":function(u){return u>=128&&u<=255},Arabic:function(u){return u>=1536&&u<=1791},"Arabic Supplement":function(u){return u>=1872&&u<=1919},"Arabic Extended-A":function(u){return u>=2208&&u<=2303},"Hangul Jamo":function(u){return u>=4352&&u<=4607},"Unified Canadian Aboriginal Syllabics":function(u){return u>=5120&&u<=5759},Khmer:function(u){return u>=6016&&u<=6143},"Unified Canadian Aboriginal Syllabics Extended":function(u){return u>=6320&&u<=6399},"General Punctuation":function(u){return u>=8192&&u<=8303},"Letterlike Symbols":function(u){return u>=8448&&u<=8527},"Number Forms":function(u){return u>=8528&&u<=8591},"Miscellaneous Technical":function(u){return u>=8960&&u<=9215},"Control Pictures":function(u){return u>=9216&&u<=9279},"Optical Character Recognition":function(u){return u>=9280&&u<=9311},"Enclosed Alphanumerics":function(u){return u>=9312&&u<=9471},"Geometric Shapes":function(u){return u>=9632&&u<=9727},"Miscellaneous Symbols":function(u){return u>=9728&&u<=9983},"Miscellaneous Symbols and Arrows":function(u){return u>=11008&&u<=11263},"CJK Radicals Supplement":function(u){return u>=11904&&u<=12031},"Kangxi Radicals":function(u){return u>=12032&&u<=12255},"Ideographic Description Characters":function(u){return u>=12272&&u<=12287},"CJK Symbols and Punctuation":function(u){return u>=12288&&u<=12351},Hiragana:function(u){return u>=12352&&u<=12447},Katakana:function(u){return u>=12448&&u<=12543},Bopomofo:function(u){return u>=12544&&u<=12591},"Hangul Compatibility Jamo":function(u){return u>=12592&&u<=12687},Kanbun:function(u){return u>=12688&&u<=12703},"Bopomofo Extended":function(u){return u>=12704&&u<=12735},"CJK Strokes":function(u){return u>=12736&&u<=12783},"Katakana Phonetic Extensions":function(u){return u>=12784&&u<=12799},"Enclosed CJK Letters and Months":function(u){return u>=12800&&u<=13055},"CJK Compatibility":function(u){return u>=13056&&u<=13311},"CJK Unified Ideographs Extension A":function(u){return u>=13312&&u<=19903},"Yijing Hexagram Symbols":function(u){return u>=19904&&u<=19967},"CJK Unified Ideographs":function(u){return u>=19968&&u<=40959},"Yi Syllables":function(u){return u>=40960&&u<=42127},"Yi Radicals":function(u){return u>=42128&&u<=42191},"Hangul Jamo Extended-A":function(u){return u>=43360&&u<=43391},"Hangul Syllables":function(u){return u>=44032&&u<=55215},"Hangul Jamo Extended-B":function(u){return u>=55216&&u<=55295},"Private Use Area":function(u){return u>=57344&&u<=63743},"CJK Compatibility Ideographs":function(u){return u>=63744&&u<=64255},"Arabic Presentation Forms-A":function(u){return u>=64336&&u<=65023},"Vertical Forms":function(u){return u>=65040&&u<=65055},"CJK Compatibility Forms":function(u){return u>=65072&&u<=65103},"Small Form Variants":function(u){return u>=65104&&u<=65135},"Arabic Presentation Forms-B":function(u){return u>=65136&&u<=65279},"Halfwidth and Fullwidth Forms":function(u){return u>=65280&&u<=65519}};function Zo(u){for(var p=0,_=u;p<_.length;p+=1)if(vd(_[p].charCodeAt(0)))return!0;return!1}function vd(u){return!(u!==746&&u!==747&&(u<4352||!(Fi["Bopomofo Extended"](u)||Fi.Bopomofo(u)||Fi["CJK Compatibility Forms"](u)&&!(u>=65097&&u<=65103)||Fi["CJK Compatibility Ideographs"](u)||Fi["CJK Compatibility"](u)||Fi["CJK Radicals Supplement"](u)||Fi["CJK Strokes"](u)||!(!Fi["CJK Symbols and Punctuation"](u)||u>=12296&&u<=12305||u>=12308&&u<=12319||u===12336)||Fi["CJK Unified Ideographs Extension A"](u)||Fi["CJK Unified Ideographs"](u)||Fi["Enclosed CJK Letters and Months"](u)||Fi["Hangul Compatibility Jamo"](u)||Fi["Hangul Jamo Extended-A"](u)||Fi["Hangul Jamo Extended-B"](u)||Fi["Hangul Jamo"](u)||Fi["Hangul Syllables"](u)||Fi.Hiragana(u)||Fi["Ideographic Description Characters"](u)||Fi.Kanbun(u)||Fi["Kangxi Radicals"](u)||Fi["Katakana Phonetic Extensions"](u)||Fi.Katakana(u)&&u!==12540||!(!Fi["Halfwidth and Fullwidth Forms"](u)||u===65288||u===65289||u===65293||u>=65306&&u<=65310||u===65339||u===65341||u===65343||u>=65371&&u<=65503||u===65507||u>=65512&&u<=65519)||!(!Fi["Small Form Variants"](u)||u>=65112&&u<=65118||u>=65123&&u<=65126)||Fi["Unified Canadian Aboriginal Syllabics"](u)||Fi["Unified Canadian Aboriginal Syllabics Extended"](u)||Fi["Vertical Forms"](u)||Fi["Yijing Hexagram Symbols"](u)||Fi["Yi Syllables"](u)||Fi["Yi Radicals"](u))))}function tg(u){return!(vd(u)||function(p){return!!(Fi["Latin-1 Supplement"](p)&&(p===167||p===169||p===174||p===177||p===188||p===189||p===190||p===215||p===247)||Fi["General Punctuation"](p)&&(p===8214||p===8224||p===8225||p===8240||p===8241||p===8251||p===8252||p===8258||p===8263||p===8264||p===8265||p===8273)||Fi["Letterlike Symbols"](p)||Fi["Number Forms"](p)||Fi["Miscellaneous Technical"](p)&&(p>=8960&&p<=8967||p>=8972&&p<=8991||p>=8996&&p<=9e3||p===9003||p>=9085&&p<=9114||p>=9150&&p<=9165||p===9167||p>=9169&&p<=9179||p>=9186&&p<=9215)||Fi["Control Pictures"](p)&&p!==9251||Fi["Optical Character Recognition"](p)||Fi["Enclosed Alphanumerics"](p)||Fi["Geometric Shapes"](p)||Fi["Miscellaneous Symbols"](p)&&!(p>=9754&&p<=9759)||Fi["Miscellaneous Symbols and Arrows"](p)&&(p>=11026&&p<=11055||p>=11088&&p<=11097||p>=11192&&p<=11243)||Fi["CJK Symbols and Punctuation"](p)||Fi.Katakana(p)||Fi["Private Use Area"](p)||Fi["CJK Compatibility Forms"](p)||Fi["Small Form Variants"](p)||Fi["Halfwidth and Fullwidth Forms"](p)||p===8734||p===8756||p===8757||p>=9984&&p<=10087||p>=10102&&p<=10131||p===65532||p===65533)}(u))}function Zu(u){return u>=1424&&u<=2303||Fi["Arabic Presentation Forms-A"](u)||Fi["Arabic Presentation Forms-B"](u)}function Ic(u,p){return!(!p&&Zu(u)||u>=2304&&u<=3583||u>=3840&&u<=4255||Fi.Khmer(u))}function rg(u){for(var p=0,_=u;p<_.length;p+=1)if(Zu(_[p].charCodeAt(0)))return!0;return!1}var ig=null,ha="unavailable",mu=null,Mc=function(u){u&&typeof u=="string"&&u.indexOf("NetworkError")>-1&&(ha="error"),ig&&ig(u)};function yh(){$d.fire(new Qe("pluginStateChange",{pluginStatus:ha,pluginURL:mu}))}var $d=new Jt,$f=function(){return ha},Yu=function(){if(ha!=="deferred"||!mu)throw new Error("rtl-text-plugin cannot be downloaded unless a pluginURL is specified");ha="loading",yh(),mu&&Us({url:mu},function(u){u?Mc(u):(ha="loaded",yh())})},gu={applyArabicShaping:null,processBidirectionalText:null,processStyledBidirectionalText:null,isLoaded:function(){return ha==="loaded"||gu.applyArabicShaping!=null},isLoading:function(){return ha==="loading"},setState:function(u){ha=u.pluginStatus,mu=u.pluginURL},isParsed:function(){return gu.applyArabicShaping!=null&&gu.processBidirectionalText!=null&&gu.processStyledBidirectionalText!=null},getPluginURL:function(){return mu}},So=function(u,p){this.zoom=u,p?(this.now=p.now,this.fadeDuration=p.fadeDuration,this.zoomHistory=p.zoomHistory,this.transition=p.transition):(this.now=0,this.fadeDuration=0,this.zoomHistory=new Ip,this.transition={})};So.prototype.isSupportedScript=function(u){return function(p,_){for(var R=0,j=p;Rthis.zoomHistory.lastIntegerZoom?{fromScale:2,toScale:1,t:p+(1-p)*_}:{fromScale:.5,toScale:1,t:1-(1-_)*p}};var Lu=function(u,p){this.property=u,this.value=p,this.expression=function(_,R){if(Ps(_))return new _h(_,R);if(Ah(_)){var j=gc(_,R);if(j.result==="error")throw new Error(j.value.map(function(J){return J.key+": "+J.message}).join(", "));return j.value}var $=_;return typeof _=="string"&&R.type==="color"&&($=cs.parse(_)),{kind:"constant",evaluate:function(){return $}}}(p===void 0?u.specification.default:p,u.specification)};Lu.prototype.isDataDriven=function(){return this.expression.kind==="source"||this.expression.kind==="composite"},Lu.prototype.possiblyEvaluate=function(u,p,_){return this.property.possiblyEvaluate(this,u,p,_)};var Nl=function(u){this.property=u,this.value=new Lu(u,void 0)};Nl.prototype.transitioned=function(u,p){return new xf(this.property,this.value,p,ee({},u.transition,this.transition),u.now)},Nl.prototype.untransitioned=function(){return new xf(this.property,this.value,null,{},0)};var fa=function(u){this._properties=u,this._values=Object.create(u.defaultTransitionablePropertyValues)};fa.prototype.getValue=function(u){return Ce(this._values[u].value.value)},fa.prototype.setValue=function(u,p){this._values.hasOwnProperty(u)||(this._values[u]=new Nl(this._values[u].property)),this._values[u].value=new Lu(this._values[u].property,p===null?void 0:Ce(p))},fa.prototype.getTransition=function(u){return Ce(this._values[u].transition)},fa.prototype.setTransition=function(u,p){this._values.hasOwnProperty(u)||(this._values[u]=new Nl(this._values[u].property)),this._values[u].transition=Ce(p)||void 0},fa.prototype.serialize=function(){for(var u={},p=0,_=Object.keys(this._values);p<_.length;p+=1){var R=_[p],j=this.getValue(R);j!==void 0&&(u[R]=j);var $=this.getTransition(R);$!==void 0&&(u[R+"-transition"]=$)}return u},fa.prototype.transitioned=function(u,p){for(var _=new Xf(this._properties),R=0,j=Object.keys(this._values);Rthis.end)return this.prior=null,j;if(this.value.isDataDriven())return this.prior=null,j;if(R=1)return 1;var ve=le*le,Ie=ve*le;return 4*(le<.5?Ie:3*(le-ve)+Ie-.75)}(J))}return j};var Xf=function(u){this._properties=u,this._values=Object.create(u.defaultTransitioningPropertyValues)};Xf.prototype.possiblyEvaluate=function(u,p,_){for(var R=new Ku(this._properties),j=0,$=Object.keys(this._values);j<$.length;j+=1){var J=$[j];R._values[J]=this._values[J].possiblyEvaluate(u,p,_)}return R},Xf.prototype.hasTransition=function(){for(var u=0,p=Object.keys(this._values);u$.zoomHistory.lastIntegerZoom?{from:_,to:R}:{from:j,to:R}},p.prototype.interpolate=function(_){return _},p}(nn),Vc=function(u){this.specification=u};Vc.prototype.possiblyEvaluate=function(u,p,_,R){if(u.value!==void 0){if(u.expression.kind==="constant"){var j=u.expression.evaluate(p,null,{},_,R);return this._calculate(j,j,j,p)}return this._calculate(u.expression.evaluate(new So(Math.floor(p.zoom-1),p)),u.expression.evaluate(new So(Math.floor(p.zoom),p)),u.expression.evaluate(new So(Math.floor(p.zoom+1),p)),p)}},Vc.prototype._calculate=function(u,p,_,R){return R.zoom>R.zoomHistory.lastIntegerZoom?{from:u,to:p}:{from:_,to:p}},Vc.prototype.interpolate=function(u){return u};var Au=function(u){this.specification=u};Au.prototype.possiblyEvaluate=function(u,p,_,R){return!!u.expression.evaluate(p,null,{},_,R)},Au.prototype.interpolate=function(){return!1};var Cl=function(u){for(var p in this.properties=u,this.defaultPropertyValues={},this.defaultTransitionablePropertyValues={},this.defaultTransitioningPropertyValues={},this.defaultPossiblyEvaluatedValues={},this.overridableProperties=[],u){var _=u[p];_.specification.overridable&&this.overridableProperties.push(p);var R=this.defaultPropertyValues[p]=new Lu(_,void 0),j=this.defaultTransitionablePropertyValues[p]=new Nl(_);this.defaultTransitioningPropertyValues[p]=j.untransitioned(),this.defaultPossiblyEvaluatedValues[p]=R.possiblyEvaluate({})}};Yi("DataDrivenProperty",nn),Yi("DataConstantProperty",An),Yi("CrossFadedDataDrivenProperty",Xd),Yi("CrossFadedProperty",Vc),Yi("ColorRampProperty",Au);var Zh=function(u){function p(_,R){if(u.call(this),this.id=_.id,this.type=_.type,this._featureFilter={filter:function(){return!0},needGeometry:!1},_.type!=="custom"&&(this.metadata=(_=_).metadata,this.minzoom=_.minzoom,this.maxzoom=_.maxzoom,_.type!=="background"&&(this.source=_.source,this.sourceLayer=_["source-layer"],this.filter=_.filter),R.layout&&(this._unevaluatedLayout=new Pc(R.layout)),R.paint)){for(var j in this._transitionablePaint=new fa(R.paint),_.paint)this.setPaintProperty(j,_.paint[j],{validate:!1});for(var $ in _.layout)this.setLayoutProperty($,_.layout[$],{validate:!1});this._transitioningPaint=this._transitionablePaint.untransitioned(),this.paint=new Ku(R.paint)}}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype.getCrossfadeParameters=function(){return this._crossfadeParameters},p.prototype.getLayoutProperty=function(_){return _==="visibility"?this.visibility:this._unevaluatedLayout.getValue(_)},p.prototype.setLayoutProperty=function(_,R,j){j===void 0&&(j={}),R!=null&&this._validate(Tl,"layers."+this.id+".layout."+_,_,R,j)||(_!=="visibility"?this._unevaluatedLayout.setValue(_,R):this.visibility=R)},p.prototype.getPaintProperty=function(_){return ne(_,"-transition")?this._transitionablePaint.getTransition(_.slice(0,-11)):this._transitionablePaint.getValue(_)},p.prototype.setPaintProperty=function(_,R,j){if(j===void 0&&(j={}),R!=null&&this._validate(tc,"layers."+this.id+".paint."+_,_,R,j))return!1;if(ne(_,"-transition"))return this._transitionablePaint.setTransition(_.slice(0,-11),R||void 0),!1;var $=this._transitionablePaint._values[_],J=$.property.specification["property-type"]==="cross-faded-data-driven",le=$.value.isDataDriven(),ve=$.value;this._transitionablePaint.setValue(_,R),this._handleSpecialPaintPropertyUpdate(_);var Ie=this._transitionablePaint._values[_].value;return Ie.isDataDriven()||le||J||this._handleOverridablePaintPropertyUpdate(_,ve,Ie)},p.prototype._handleSpecialPaintPropertyUpdate=function(_){},p.prototype._handleOverridablePaintPropertyUpdate=function(_,R,j){return!1},p.prototype.isHidden=function(_){return!!(this.minzoom&&_=this.maxzoom)||this.visibility==="none"},p.prototype.updateTransitions=function(_){this._transitioningPaint=this._transitionablePaint.transitioned(_,this._transitioningPaint)},p.prototype.hasTransition=function(){return this._transitioningPaint.hasTransition()},p.prototype.recalculate=function(_,R){_.getCrossfadeParameters&&(this._crossfadeParameters=_.getCrossfadeParameters()),this._unevaluatedLayout&&(this.layout=this._unevaluatedLayout.possiblyEvaluate(_,void 0,R)),this.paint=this._transitioningPaint.possiblyEvaluate(_,void 0,R)},p.prototype.serialize=function(){var _={id:this.id,type:this.type,source:this.source,"source-layer":this.sourceLayer,metadata:this.metadata,minzoom:this.minzoom,maxzoom:this.maxzoom,filter:this.filter,layout:this._unevaluatedLayout&&this._unevaluatedLayout.serialize(),paint:this._transitionablePaint&&this._transitionablePaint.serialize()};return this.visibility&&(_.layout=_.layout||{},_.layout.visibility=this.visibility),Xe(_,function(R,j){return!(R===void 0||j==="layout"&&!Object.keys(R).length||j==="paint"&&!Object.keys(R).length)})},p.prototype._validate=function(_,R,j,$,J){return J===void 0&&(J={}),(!J||J.validate!==!1)&&ll(this,_.call(wl,{key:R,layerType:this.type,objectKey:j,value:$,styleSpec:ht,style:{glyphs:!0,sprite:!0}}))},p.prototype.is3D=function(){return!1},p.prototype.isTileClipped=function(){return!1},p.prototype.hasOffscreenPass=function(){return!1},p.prototype.resize=function(){},p.prototype.isStateDependent=function(){for(var _ in this.paint._values){var R=this.paint.get(_);if(R instanceof El&&_o(R.property.specification)&&(R.value.kind==="source"||R.value.kind==="composite")&&R.value.isStateDependent)return!0}return!1},p}(Jt),ng={Int8:Int8Array,Uint8:Uint8Array,Int16:Int16Array,Uint16:Uint16Array,Int32:Int32Array,Uint32:Uint32Array,Float32:Float32Array},Ha=function(u,p){this._structArray=u,this._pos1=p*this.size,this._pos2=this._pos1/2,this._pos4=this._pos1/4,this._pos8=this._pos1/8},As=function(){this.isTransferred=!1,this.capacity=-1,this.resize(0)};function da(u,p){p===void 0&&(p=1);var _=0,R=0;return{members:u.map(function(j){var $=ng[j.type].BYTES_PER_ELEMENT,J=_=Mp(_,Math.max(p,$)),le=j.components||1;return R=Math.max(R,$),_+=$*le,{name:j.name,type:j.type,components:le,offset:J}}),size:Mp(_,Math.max(R,p)),alignment:p}}function Mp(u,p){return Math.ceil(u/p)*p}As.serialize=function(u,p){return u._trim(),p&&(u.isTransferred=!0,p.push(u.arrayBuffer)),{length:u.length,arrayBuffer:u.arrayBuffer}},As.deserialize=function(u){var p=Object.create(this.prototype);return p.arrayBuffer=u.arrayBuffer,p.length=u.length,p.capacity=u.arrayBuffer.byteLength/p.bytesPerElement,p._refreshViews(),p},As.prototype._trim=function(){this.length!==this.capacity&&(this.capacity=this.length,this.arrayBuffer=this.arrayBuffer.slice(0,this.length*this.bytesPerElement),this._refreshViews())},As.prototype.clear=function(){this.length=0},As.prototype.resize=function(u){this.reserve(u),this.length=u},As.prototype.reserve=function(u){if(u>this.capacity){this.capacity=Math.max(u,Math.floor(5*this.capacity),128),this.arrayBuffer=new ArrayBuffer(this.capacity*this.bytesPerElement);var p=this.uint8;this._refreshViews(),p&&this.uint8.set(p)}},As.prototype._refreshViews=function(){throw new Error("_refreshViews() must be implemented by each concrete StructArray layout")};var Yh=function(u){function p(){u.apply(this,arguments)}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer)},p.prototype.emplaceBack=function(_,R){var j=this.length;return this.resize(j+1),this.emplace(j,_,R)},p.prototype.emplace=function(_,R,j){var $=2*_;return this.int16[$+0]=R,this.int16[$+1]=j,_},p}(As);Yh.prototype.bytesPerElement=4,Yi("StructArrayLayout2i4",Yh);var Pp=function(u){function p(){u.apply(this,arguments)}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer)},p.prototype.emplaceBack=function(_,R,j,$){var J=this.length;return this.resize(J+1),this.emplace(J,_,R,j,$)},p.prototype.emplace=function(_,R,j,$,J){var le=4*_;return this.int16[le+0]=R,this.int16[le+1]=j,this.int16[le+2]=$,this.int16[le+3]=J,_},p}(As);Pp.prototype.bytesPerElement=8,Yi("StructArrayLayout4i8",Pp);var _c=function(u){function p(){u.apply(this,arguments)}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer)},p.prototype.emplaceBack=function(_,R,j,$,J,le){var ve=this.length;return this.resize(ve+1),this.emplace(ve,_,R,j,$,J,le)},p.prototype.emplace=function(_,R,j,$,J,le,ve){var Ie=6*_;return this.int16[Ie+0]=R,this.int16[Ie+1]=j,this.int16[Ie+2]=$,this.int16[Ie+3]=J,this.int16[Ie+4]=le,this.int16[Ie+5]=ve,_},p}(As);_c.prototype.bytesPerElement=12,Yi("StructArrayLayout2i4i12",_c);var Rc=function(u){function p(){u.apply(this,arguments)}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer)},p.prototype.emplaceBack=function(_,R,j,$,J,le){var ve=this.length;return this.resize(ve+1),this.emplace(ve,_,R,j,$,J,le)},p.prototype.emplace=function(_,R,j,$,J,le,ve){var Ie=4*_,Le=8*_;return this.int16[Ie+0]=R,this.int16[Ie+1]=j,this.uint8[Le+4]=$,this.uint8[Le+5]=J,this.uint8[Le+6]=le,this.uint8[Le+7]=ve,_},p}(As);Rc.prototype.bytesPerElement=8,Yi("StructArrayLayout2i4ub8",Rc);var vh=function(u){function p(){u.apply(this,arguments)}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.float32=new Float32Array(this.arrayBuffer)},p.prototype.emplaceBack=function(_,R){var j=this.length;return this.resize(j+1),this.emplace(j,_,R)},p.prototype.emplace=function(_,R,j){var $=2*_;return this.float32[$+0]=R,this.float32[$+1]=j,_},p}(As);vh.prototype.bytesPerElement=8,Yi("StructArrayLayout2f8",vh);var _u=function(u){function p(){u.apply(this,arguments)}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer)},p.prototype.emplaceBack=function(_,R,j,$,J,le,ve,Ie,Le,ze){var Ke=this.length;return this.resize(Ke+1),this.emplace(Ke,_,R,j,$,J,le,ve,Ie,Le,ze)},p.prototype.emplace=function(_,R,j,$,J,le,ve,Ie,Le,ze,Ke){var lt=10*_;return this.uint16[lt+0]=R,this.uint16[lt+1]=j,this.uint16[lt+2]=$,this.uint16[lt+3]=J,this.uint16[lt+4]=le,this.uint16[lt+5]=ve,this.uint16[lt+6]=Ie,this.uint16[lt+7]=Le,this.uint16[lt+8]=ze,this.uint16[lt+9]=Ke,_},p}(As);_u.prototype.bytesPerElement=20,Yi("StructArrayLayout10ui20",_u);var Zf=function(u){function p(){u.apply(this,arguments)}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer)},p.prototype.emplaceBack=function(_,R,j,$,J,le,ve,Ie,Le,ze,Ke,lt){var Mt=this.length;return this.resize(Mt+1),this.emplace(Mt,_,R,j,$,J,le,ve,Ie,Le,ze,Ke,lt)},p.prototype.emplace=function(_,R,j,$,J,le,ve,Ie,Le,ze,Ke,lt,Mt){var Dt=12*_;return this.int16[Dt+0]=R,this.int16[Dt+1]=j,this.int16[Dt+2]=$,this.int16[Dt+3]=J,this.uint16[Dt+4]=le,this.uint16[Dt+5]=ve,this.uint16[Dt+6]=Ie,this.uint16[Dt+7]=Le,this.int16[Dt+8]=ze,this.int16[Dt+9]=Ke,this.int16[Dt+10]=lt,this.int16[Dt+11]=Mt,_},p}(As);Zf.prototype.bytesPerElement=24,Yi("StructArrayLayout4i4ui4i24",Zf);var Zd=function(u){function p(){u.apply(this,arguments)}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.float32=new Float32Array(this.arrayBuffer)},p.prototype.emplaceBack=function(_,R,j){var $=this.length;return this.resize($+1),this.emplace($,_,R,j)},p.prototype.emplace=function(_,R,j,$){var J=3*_;return this.float32[J+0]=R,this.float32[J+1]=j,this.float32[J+2]=$,_},p}(As);Zd.prototype.bytesPerElement=12,Yi("StructArrayLayout3f12",Zd);var xd=function(u){function p(){u.apply(this,arguments)}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.uint32=new Uint32Array(this.arrayBuffer)},p.prototype.emplaceBack=function(_){var R=this.length;return this.resize(R+1),this.emplace(R,_)},p.prototype.emplace=function(_,R){return this.uint32[1*_+0]=R,_},p}(As);xd.prototype.bytesPerElement=4,Yi("StructArrayLayout1ul4",xd);var mm=function(u){function p(){u.apply(this,arguments)}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer),this.uint32=new Uint32Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer)},p.prototype.emplaceBack=function(_,R,j,$,J,le,ve,Ie,Le){var ze=this.length;return this.resize(ze+1),this.emplace(ze,_,R,j,$,J,le,ve,Ie,Le)},p.prototype.emplace=function(_,R,j,$,J,le,ve,Ie,Le,ze){var Ke=10*_,lt=5*_;return this.int16[Ke+0]=R,this.int16[Ke+1]=j,this.int16[Ke+2]=$,this.int16[Ke+3]=J,this.int16[Ke+4]=le,this.int16[Ke+5]=ve,this.uint32[lt+3]=Ie,this.uint16[Ke+8]=Le,this.uint16[Ke+9]=ze,_},p}(As);mm.prototype.bytesPerElement=20,Yi("StructArrayLayout6i1ul2ui20",mm);var xh=function(u){function p(){u.apply(this,arguments)}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer)},p.prototype.emplaceBack=function(_,R,j,$,J,le){var ve=this.length;return this.resize(ve+1),this.emplace(ve,_,R,j,$,J,le)},p.prototype.emplace=function(_,R,j,$,J,le,ve){var Ie=6*_;return this.int16[Ie+0]=R,this.int16[Ie+1]=j,this.int16[Ie+2]=$,this.int16[Ie+3]=J,this.int16[Ie+4]=le,this.int16[Ie+5]=ve,_},p}(As);xh.prototype.bytesPerElement=12,Yi("StructArrayLayout2i2i2i12",xh);var Qu=function(u){function p(){u.apply(this,arguments)}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.float32=new Float32Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer)},p.prototype.emplaceBack=function(_,R,j,$,J){var le=this.length;return this.resize(le+1),this.emplace(le,_,R,j,$,J)},p.prototype.emplace=function(_,R,j,$,J,le){var ve=4*_,Ie=8*_;return this.float32[ve+0]=R,this.float32[ve+1]=j,this.float32[ve+2]=$,this.int16[Ie+6]=J,this.int16[Ie+7]=le,_},p}(As);Qu.prototype.bytesPerElement=16,Yi("StructArrayLayout2f1f2i16",Qu);var Yd=function(u){function p(){u.apply(this,arguments)}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.float32=new Float32Array(this.arrayBuffer)},p.prototype.emplaceBack=function(_,R,j,$){var J=this.length;return this.resize(J+1),this.emplace(J,_,R,j,$)},p.prototype.emplace=function(_,R,j,$,J){var le=12*_,ve=3*_;return this.uint8[le+0]=R,this.uint8[le+1]=j,this.float32[ve+1]=$,this.float32[ve+2]=J,_},p}(As);Yd.prototype.bytesPerElement=12,Yi("StructArrayLayout2ub2f12",Yd);var Kh=function(u){function p(){u.apply(this,arguments)}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer)},p.prototype.emplaceBack=function(_,R,j){var $=this.length;return this.resize($+1),this.emplace($,_,R,j)},p.prototype.emplace=function(_,R,j,$){var J=3*_;return this.uint16[J+0]=R,this.uint16[J+1]=j,this.uint16[J+2]=$,_},p}(As);Kh.prototype.bytesPerElement=6,Yi("StructArrayLayout3ui6",Kh);var bh=function(u){function p(){u.apply(this,arguments)}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer),this.uint32=new Uint32Array(this.arrayBuffer),this.float32=new Float32Array(this.arrayBuffer)},p.prototype.emplaceBack=function(_,R,j,$,J,le,ve,Ie,Le,ze,Ke,lt,Mt,Dt,tr,qt,ur){var Tr=this.length;return this.resize(Tr+1),this.emplace(Tr,_,R,j,$,J,le,ve,Ie,Le,ze,Ke,lt,Mt,Dt,tr,qt,ur)},p.prototype.emplace=function(_,R,j,$,J,le,ve,Ie,Le,ze,Ke,lt,Mt,Dt,tr,qt,ur,Tr){var Nr=24*_,Vr=12*_,ri=48*_;return this.int16[Nr+0]=R,this.int16[Nr+1]=j,this.uint16[Nr+2]=$,this.uint16[Nr+3]=J,this.uint32[Vr+2]=le,this.uint32[Vr+3]=ve,this.uint32[Vr+4]=Ie,this.uint16[Nr+10]=Le,this.uint16[Nr+11]=ze,this.uint16[Nr+12]=Ke,this.float32[Vr+7]=lt,this.float32[Vr+8]=Mt,this.uint8[ri+36]=Dt,this.uint8[ri+37]=tr,this.uint8[ri+38]=qt,this.uint32[Vr+10]=ur,this.int16[Nr+22]=Tr,_},p}(As);bh.prototype.bytesPerElement=48,Yi("StructArrayLayout2i2ui3ul3ui2f3ub1ul1i48",bh);var Rp=function(u){function p(){u.apply(this,arguments)}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer),this.uint32=new Uint32Array(this.arrayBuffer),this.float32=new Float32Array(this.arrayBuffer)},p.prototype.emplaceBack=function(_,R,j,$,J,le,ve,Ie,Le,ze,Ke,lt,Mt,Dt,tr,qt,ur,Tr,Nr,Vr,ri,Ei,Ui,Cn,Ki,Bn,en,Wo){var Xn=this.length;return this.resize(Xn+1),this.emplace(Xn,_,R,j,$,J,le,ve,Ie,Le,ze,Ke,lt,Mt,Dt,tr,qt,ur,Tr,Nr,Vr,ri,Ei,Ui,Cn,Ki,Bn,en,Wo)},p.prototype.emplace=function(_,R,j,$,J,le,ve,Ie,Le,ze,Ke,lt,Mt,Dt,tr,qt,ur,Tr,Nr,Vr,ri,Ei,Ui,Cn,Ki,Bn,en,Wo,Xn){var pn=34*_,Jo=17*_;return this.int16[pn+0]=R,this.int16[pn+1]=j,this.int16[pn+2]=$,this.int16[pn+3]=J,this.int16[pn+4]=le,this.int16[pn+5]=ve,this.int16[pn+6]=Ie,this.int16[pn+7]=Le,this.uint16[pn+8]=ze,this.uint16[pn+9]=Ke,this.uint16[pn+10]=lt,this.uint16[pn+11]=Mt,this.uint16[pn+12]=Dt,this.uint16[pn+13]=tr,this.uint16[pn+14]=qt,this.uint16[pn+15]=ur,this.uint16[pn+16]=Tr,this.uint16[pn+17]=Nr,this.uint16[pn+18]=Vr,this.uint16[pn+19]=ri,this.uint16[pn+20]=Ei,this.uint16[pn+21]=Ui,this.uint16[pn+22]=Cn,this.uint32[Jo+12]=Ki,this.float32[Jo+13]=Bn,this.float32[Jo+14]=en,this.float32[Jo+15]=Wo,this.float32[Jo+16]=Xn,_},p}(As);Rp.prototype.bytesPerElement=68,Yi("StructArrayLayout8i15ui1ul4f68",Rp);var bf=function(u){function p(){u.apply(this,arguments)}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.float32=new Float32Array(this.arrayBuffer)},p.prototype.emplaceBack=function(_){var R=this.length;return this.resize(R+1),this.emplace(R,_)},p.prototype.emplace=function(_,R){return this.float32[1*_+0]=R,_},p}(As);bf.prototype.bytesPerElement=4,Yi("StructArrayLayout1f4",bf);var Du=function(u){function p(){u.apply(this,arguments)}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer)},p.prototype.emplaceBack=function(_,R,j){var $=this.length;return this.resize($+1),this.emplace($,_,R,j)},p.prototype.emplace=function(_,R,j,$){var J=3*_;return this.int16[J+0]=R,this.int16[J+1]=j,this.int16[J+2]=$,_},p}(As);Du.prototype.bytesPerElement=6,Yi("StructArrayLayout3i6",Du);var Bp=function(u){function p(){u.apply(this,arguments)}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.uint32=new Uint32Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer)},p.prototype.emplaceBack=function(_,R,j){var $=this.length;return this.resize($+1),this.emplace($,_,R,j)},p.prototype.emplace=function(_,R,j,$){var J=4*_;return this.uint32[2*_+0]=R,this.uint16[J+2]=j,this.uint16[J+3]=$,_},p}(As);Bp.prototype.bytesPerElement=8,Yi("StructArrayLayout1ul2ui8",Bp);var Kd=function(u){function p(){u.apply(this,arguments)}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer)},p.prototype.emplaceBack=function(_,R){var j=this.length;return this.resize(j+1),this.emplace(j,_,R)},p.prototype.emplace=function(_,R,j){var $=2*_;return this.uint16[$+0]=R,this.uint16[$+1]=j,_},p}(As);Kd.prototype.bytesPerElement=4,Yi("StructArrayLayout2ui4",Kd);var Yf=function(u){function p(){u.apply(this,arguments)}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer)},p.prototype.emplaceBack=function(_){var R=this.length;return this.resize(R+1),this.emplace(R,_)},p.prototype.emplace=function(_,R){return this.uint16[1*_+0]=R,_},p}(As);Yf.prototype.bytesPerElement=2,Yi("StructArrayLayout1ui2",Yf);var Qh=function(u){function p(){u.apply(this,arguments)}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype._refreshViews=function(){this.uint8=new Uint8Array(this.arrayBuffer),this.float32=new Float32Array(this.arrayBuffer)},p.prototype.emplaceBack=function(_,R,j,$){var J=this.length;return this.resize(J+1),this.emplace(J,_,R,j,$)},p.prototype.emplace=function(_,R,j,$,J){var le=4*_;return this.float32[le+0]=R,this.float32[le+1]=j,this.float32[le+2]=$,this.float32[le+3]=J,_},p}(As);Qh.prototype.bytesPerElement=16,Yi("StructArrayLayout4f16",Qh);var w=function(u){function p(){u.apply(this,arguments)}u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p;var _={anchorPointX:{configurable:!0},anchorPointY:{configurable:!0},x1:{configurable:!0},y1:{configurable:!0},x2:{configurable:!0},y2:{configurable:!0},featureIndex:{configurable:!0},sourceLayerIndex:{configurable:!0},bucketIndex:{configurable:!0},anchorPoint:{configurable:!0}};return _.anchorPointX.get=function(){return this._structArray.int16[this._pos2+0]},_.anchorPointY.get=function(){return this._structArray.int16[this._pos2+1]},_.x1.get=function(){return this._structArray.int16[this._pos2+2]},_.y1.get=function(){return this._structArray.int16[this._pos2+3]},_.x2.get=function(){return this._structArray.int16[this._pos2+4]},_.y2.get=function(){return this._structArray.int16[this._pos2+5]},_.featureIndex.get=function(){return this._structArray.uint32[this._pos4+3]},_.sourceLayerIndex.get=function(){return this._structArray.uint16[this._pos2+8]},_.bucketIndex.get=function(){return this._structArray.uint16[this._pos2+9]},_.anchorPoint.get=function(){return new f(this.anchorPointX,this.anchorPointY)},Object.defineProperties(p.prototype,_),p}(Ha);w.prototype.size=20;var M=function(u){function p(){u.apply(this,arguments)}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype.get=function(_){return new w(this,_)},p}(mm);Yi("CollisionBoxArray",M);var S=function(u){function p(){u.apply(this,arguments)}u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p;var _={anchorX:{configurable:!0},anchorY:{configurable:!0},glyphStartIndex:{configurable:!0},numGlyphs:{configurable:!0},vertexStartIndex:{configurable:!0},lineStartIndex:{configurable:!0},lineLength:{configurable:!0},segment:{configurable:!0},lowerSize:{configurable:!0},upperSize:{configurable:!0},lineOffsetX:{configurable:!0},lineOffsetY:{configurable:!0},writingMode:{configurable:!0},placedOrientation:{configurable:!0},hidden:{configurable:!0},crossTileID:{configurable:!0},associatedIconIndex:{configurable:!0}};return _.anchorX.get=function(){return this._structArray.int16[this._pos2+0]},_.anchorY.get=function(){return this._structArray.int16[this._pos2+1]},_.glyphStartIndex.get=function(){return this._structArray.uint16[this._pos2+2]},_.numGlyphs.get=function(){return this._structArray.uint16[this._pos2+3]},_.vertexStartIndex.get=function(){return this._structArray.uint32[this._pos4+2]},_.lineStartIndex.get=function(){return this._structArray.uint32[this._pos4+3]},_.lineLength.get=function(){return this._structArray.uint32[this._pos4+4]},_.segment.get=function(){return this._structArray.uint16[this._pos2+10]},_.lowerSize.get=function(){return this._structArray.uint16[this._pos2+11]},_.upperSize.get=function(){return this._structArray.uint16[this._pos2+12]},_.lineOffsetX.get=function(){return this._structArray.float32[this._pos4+7]},_.lineOffsetY.get=function(){return this._structArray.float32[this._pos4+8]},_.writingMode.get=function(){return this._structArray.uint8[this._pos1+36]},_.placedOrientation.get=function(){return this._structArray.uint8[this._pos1+37]},_.placedOrientation.set=function(R){this._structArray.uint8[this._pos1+37]=R},_.hidden.get=function(){return this._structArray.uint8[this._pos1+38]},_.hidden.set=function(R){this._structArray.uint8[this._pos1+38]=R},_.crossTileID.get=function(){return this._structArray.uint32[this._pos4+10]},_.crossTileID.set=function(R){this._structArray.uint32[this._pos4+10]=R},_.associatedIconIndex.get=function(){return this._structArray.int16[this._pos2+22]},Object.defineProperties(p.prototype,_),p}(Ha);S.prototype.size=48;var L=function(u){function p(){u.apply(this,arguments)}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype.get=function(_){return new S(this,_)},p}(bh);Yi("PlacedSymbolArray",L);var Y=function(u){function p(){u.apply(this,arguments)}u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p;var _={anchorX:{configurable:!0},anchorY:{configurable:!0},rightJustifiedTextSymbolIndex:{configurable:!0},centerJustifiedTextSymbolIndex:{configurable:!0},leftJustifiedTextSymbolIndex:{configurable:!0},verticalPlacedTextSymbolIndex:{configurable:!0},placedIconSymbolIndex:{configurable:!0},verticalPlacedIconSymbolIndex:{configurable:!0},key:{configurable:!0},textBoxStartIndex:{configurable:!0},textBoxEndIndex:{configurable:!0},verticalTextBoxStartIndex:{configurable:!0},verticalTextBoxEndIndex:{configurable:!0},iconBoxStartIndex:{configurable:!0},iconBoxEndIndex:{configurable:!0},verticalIconBoxStartIndex:{configurable:!0},verticalIconBoxEndIndex:{configurable:!0},featureIndex:{configurable:!0},numHorizontalGlyphVertices:{configurable:!0},numVerticalGlyphVertices:{configurable:!0},numIconVertices:{configurable:!0},numVerticalIconVertices:{configurable:!0},useRuntimeCollisionCircles:{configurable:!0},crossTileID:{configurable:!0},textBoxScale:{configurable:!0},textOffset0:{configurable:!0},textOffset1:{configurable:!0},collisionCircleDiameter:{configurable:!0}};return _.anchorX.get=function(){return this._structArray.int16[this._pos2+0]},_.anchorY.get=function(){return this._structArray.int16[this._pos2+1]},_.rightJustifiedTextSymbolIndex.get=function(){return this._structArray.int16[this._pos2+2]},_.centerJustifiedTextSymbolIndex.get=function(){return this._structArray.int16[this._pos2+3]},_.leftJustifiedTextSymbolIndex.get=function(){return this._structArray.int16[this._pos2+4]},_.verticalPlacedTextSymbolIndex.get=function(){return this._structArray.int16[this._pos2+5]},_.placedIconSymbolIndex.get=function(){return this._structArray.int16[this._pos2+6]},_.verticalPlacedIconSymbolIndex.get=function(){return this._structArray.int16[this._pos2+7]},_.key.get=function(){return this._structArray.uint16[this._pos2+8]},_.textBoxStartIndex.get=function(){return this._structArray.uint16[this._pos2+9]},_.textBoxEndIndex.get=function(){return this._structArray.uint16[this._pos2+10]},_.verticalTextBoxStartIndex.get=function(){return this._structArray.uint16[this._pos2+11]},_.verticalTextBoxEndIndex.get=function(){return this._structArray.uint16[this._pos2+12]},_.iconBoxStartIndex.get=function(){return this._structArray.uint16[this._pos2+13]},_.iconBoxEndIndex.get=function(){return this._structArray.uint16[this._pos2+14]},_.verticalIconBoxStartIndex.get=function(){return this._structArray.uint16[this._pos2+15]},_.verticalIconBoxEndIndex.get=function(){return this._structArray.uint16[this._pos2+16]},_.featureIndex.get=function(){return this._structArray.uint16[this._pos2+17]},_.numHorizontalGlyphVertices.get=function(){return this._structArray.uint16[this._pos2+18]},_.numVerticalGlyphVertices.get=function(){return this._structArray.uint16[this._pos2+19]},_.numIconVertices.get=function(){return this._structArray.uint16[this._pos2+20]},_.numVerticalIconVertices.get=function(){return this._structArray.uint16[this._pos2+21]},_.useRuntimeCollisionCircles.get=function(){return this._structArray.uint16[this._pos2+22]},_.crossTileID.get=function(){return this._structArray.uint32[this._pos4+12]},_.crossTileID.set=function(R){this._structArray.uint32[this._pos4+12]=R},_.textBoxScale.get=function(){return this._structArray.float32[this._pos4+13]},_.textOffset0.get=function(){return this._structArray.float32[this._pos4+14]},_.textOffset1.get=function(){return this._structArray.float32[this._pos4+15]},_.collisionCircleDiameter.get=function(){return this._structArray.float32[this._pos4+16]},Object.defineProperties(p.prototype,_),p}(Ha);Y.prototype.size=68;var ie=function(u){function p(){u.apply(this,arguments)}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype.get=function(_){return new Y(this,_)},p}(Rp);Yi("SymbolInstanceArray",ie);var ae=function(u){function p(){u.apply(this,arguments)}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype.getoffsetX=function(_){return this.float32[1*_+0]},p}(bf);Yi("GlyphOffsetArray",ae);var ge=function(u){function p(){u.apply(this,arguments)}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype.getx=function(_){return this.int16[3*_+0]},p.prototype.gety=function(_){return this.int16[3*_+1]},p.prototype.gettileUnitDistanceFromAnchor=function(_){return this.int16[3*_+2]},p}(Du);Yi("SymbolLineVertexArray",ge);var Pe=function(u){function p(){u.apply(this,arguments)}u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p;var _={featureIndex:{configurable:!0},sourceLayerIndex:{configurable:!0},bucketIndex:{configurable:!0}};return _.featureIndex.get=function(){return this._structArray.uint32[this._pos4+0]},_.sourceLayerIndex.get=function(){return this._structArray.uint16[this._pos2+2]},_.bucketIndex.get=function(){return this._structArray.uint16[this._pos2+3]},Object.defineProperties(p.prototype,_),p}(Ha);Pe.prototype.size=8;var Ue=function(u){function p(){u.apply(this,arguments)}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype.get=function(_){return new Pe(this,_)},p}(Bp);Yi("FeatureIndexArray",Ue);var ct=da([{name:"a_pos",components:2,type:"Int16"}],4).members,ft=function(u){u===void 0&&(u=[]),this.segments=u};function gt(u,p){return 256*(u=U(Math.floor(u),0,255))+U(Math.floor(p),0,255)}ft.prototype.prepareSegment=function(u,p,_,R){var j=this.segments[this.segments.length-1];return u>ft.MAX_VERTEX_ARRAY_LENGTH&&Je("Max vertices per segment is "+ft.MAX_VERTEX_ARRAY_LENGTH+": bucket requested "+u),(!j||j.vertexLength+u>ft.MAX_VERTEX_ARRAY_LENGTH||j.sortKey!==R)&&(j={vertexOffset:p.length,primitiveOffset:_.length,vertexLength:0,primitiveLength:0},R!==void 0&&(j.sortKey=R),this.segments.push(j)),j},ft.prototype.get=function(){return this.segments},ft.prototype.destroy=function(){for(var u=0,p=this.segments;u>>16)*le&65535)<<16)&4294967295)<<15|Ie>>>17))*ve+(((Ie>>>16)*ve&65535)<<16)&4294967295)<<13|$>>>19))+((5*($>>>16)&65535)<<16)&4294967295))+((58964+(J>>>16)&65535)<<16);switch(Ie=0,R){case 3:Ie^=(255&p.charCodeAt(Le+2))<<16;case 2:Ie^=(255&p.charCodeAt(Le+1))<<8;case 1:$^=Ie=(65535&(Ie=(Ie=(65535&(Ie^=255&p.charCodeAt(Le)))*le+(((Ie>>>16)*le&65535)<<16)&4294967295)<<15|Ie>>>17))*ve+(((Ie>>>16)*ve&65535)<<16)&4294967295}return $^=p.length,$=2246822507*(65535&($^=$>>>16))+((2246822507*($>>>16)&65535)<<16)&4294967295,$=3266489909*(65535&($^=$>>>13))+((3266489909*($>>>16)&65535)<<16)&4294967295,($^=$>>>16)>>>0}}),Wt=o(function(u){u.exports=function(p,_){for(var R,j=p.length,$=_^j,J=0;j>=4;)R=1540483477*(65535&(R=255&p.charCodeAt(J)|(255&p.charCodeAt(++J))<<8|(255&p.charCodeAt(++J))<<16|(255&p.charCodeAt(++J))<<24))+((1540483477*(R>>>16)&65535)<<16),$=1540483477*(65535&$)+((1540483477*($>>>16)&65535)<<16)^(R=1540483477*(65535&(R^=R>>>24))+((1540483477*(R>>>16)&65535)<<16)),j-=4,++J;switch(j){case 3:$^=(255&p.charCodeAt(J+2))<<16;case 2:$^=(255&p.charCodeAt(J+1))<<8;case 1:$=1540483477*(65535&($^=255&p.charCodeAt(J)))+((1540483477*($>>>16)&65535)<<16)}return $=1540483477*(65535&($^=$>>>13))+((1540483477*($>>>16)&65535)<<16),($^=$>>>15)>>>0}}),St=Pt,Zt=Wt;St.murmur3=Pt,St.murmur2=Zt;var ir=function(){this.ids=[],this.positions=[],this.indexed=!1};ir.prototype.add=function(u,p,_,R){this.ids.push(kr(u)),this.positions.push(p,_,R)},ir.prototype.getPositions=function(u){for(var p=kr(u),_=0,R=this.ids.length-1;_>1;this.ids[j]>=p?R=j:_=j+1}for(var $=[];this.ids[_]===p;)$.push({index:this.positions[3*_],start:this.positions[3*_+1],end:this.positions[3*_+2]}),_++;return $},ir.serialize=function(u,p){var _=new Float64Array(u.ids),R=new Uint32Array(u.positions);return function j($,J,le,ve){for(;le>1],Le=le-1,ze=ve+1;;){do Le++;while($[Le]Ie);if(Le>=ze)break;Lr($,Le,ze),Lr(J,3*Le,3*ze),Lr(J,3*Le+1,3*ze+1),Lr(J,3*Le+2,3*ze+2)}ze-leJ.x+1||veJ.y+1)&&Je("Geometry exceeds allowed extent, reduce your vector tile buffer size")}return _}function Ta(u,p){return{type:u.type,id:u.id,properties:u.properties,geometry:p?Vs(u):[]}}function tn(u,p,_,R,j){u.emplaceBack(2*p+(R+1)/2,2*_+(j+1)/2)}var _n=function(u){this.zoom=u.zoom,this.overscaling=u.overscaling,this.layers=u.layers,this.layerIds=this.layers.map(function(p){return p.id}),this.index=u.index,this.hasPattern=!1,this.layoutVertexArray=new Yh,this.indexArray=new Kh,this.segments=new ft,this.programConfigurations=new Rn(u.layers,u.zoom),this.stateDependentLayerIds=this.layers.filter(function(p){return p.isStateDependent()}).map(function(p){return p.id})};function Ju(u,p){for(var _=0;_1){if(Gc(u,p))return!0;for(var R=0;R1?_:_.sub(p)._mult(j)._add(p))}function Ou(u,p){for(var _,R,j,$=!1,J=0;Jp.y!=(j=_[ve]).y>p.y&&p.x<(j.x-R.x)*(p.y-R.y)/(j.y-R.y)+R.x&&($=!$);return $}function iu(u,p){for(var _=!1,R=0,j=u.length-1;Rp.y!=J.y>p.y&&p.x<(J.x-$.x)*(p.y-$.y)/(J.y-$.y)+$.x&&(_=!_)}return _}function Sa(u,p,_){var R=_[0],j=_[2];if(u.xj.x&&p.x>j.x||u.yj.y&&p.y>j.y)return!1;var $=Et(u,p,_[0]);return $!==Et(u,p,_[1])||$!==Et(u,p,_[2])||$!==Et(u,p,_[3])}function na(u,p,_){var R=p.paint.get(u).value;return R.kind==="constant"?R.value:_.programConfigurations.get(p.id).getMaxValue(u)}function zl(u){return Math.sqrt(u[0]*u[0]+u[1]*u[1])}function eh(u,p,_,R,j){if(!p[0]&&!p[1])return u;var $=f.convert(p)._mult(j);_==="viewport"&&$._rotate(-R);for(var J=[],le=0;le=8192||Le<0||Le>=8192)){var ze=this.segments.prepareSegment(4,this.layoutVertexArray,this.indexArray,u.sortKey),Ke=ze.vertexLength;tn(this.layoutVertexArray,Ie,Le,-1,-1),tn(this.layoutVertexArray,Ie,Le,1,-1),tn(this.layoutVertexArray,Ie,Le,1,1),tn(this.layoutVertexArray,Ie,Le,-1,1),this.indexArray.emplaceBack(Ke,Ke+1,Ke+2),this.indexArray.emplaceBack(Ke,Ke+3,Ke+2),ze.vertexLength+=4,ze.primitiveLength+=2}}this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length,u,_,{},R)},Yi("CircleBucket",_n,{omit:["layers"]});var Jh=new Cl({"circle-sort-key":new nn(ht.layout_circle["circle-sort-key"])}),Ul={paint:new Cl({"circle-radius":new nn(ht.paint_circle["circle-radius"]),"circle-color":new nn(ht.paint_circle["circle-color"]),"circle-blur":new nn(ht.paint_circle["circle-blur"]),"circle-opacity":new nn(ht.paint_circle["circle-opacity"]),"circle-translate":new An(ht.paint_circle["circle-translate"]),"circle-translate-anchor":new An(ht.paint_circle["circle-translate-anchor"]),"circle-pitch-scale":new An(ht.paint_circle["circle-pitch-scale"]),"circle-pitch-alignment":new An(ht.paint_circle["circle-pitch-alignment"]),"circle-stroke-width":new nn(ht.paint_circle["circle-stroke-width"]),"circle-stroke-color":new nn(ht.paint_circle["circle-stroke-color"]),"circle-stroke-opacity":new nn(ht.paint_circle["circle-stroke-opacity"])}),layout:Jh},_s=typeof Float32Array<"u"?Float32Array:Array;function yu(u){return u[0]=1,u[1]=0,u[2]=0,u[3]=0,u[4]=0,u[5]=1,u[6]=0,u[7]=0,u[8]=0,u[9]=0,u[10]=1,u[11]=0,u[12]=0,u[13]=0,u[14]=0,u[15]=1,u}function Ml(u,p,_){var R=p[0],j=p[1],$=p[2],J=p[3],le=p[4],ve=p[5],Ie=p[6],Le=p[7],ze=p[8],Ke=p[9],lt=p[10],Mt=p[11],Dt=p[12],tr=p[13],qt=p[14],ur=p[15],Tr=_[0],Nr=_[1],Vr=_[2],ri=_[3];return u[0]=Tr*R+Nr*le+Vr*ze+ri*Dt,u[1]=Tr*j+Nr*ve+Vr*Ke+ri*tr,u[2]=Tr*$+Nr*Ie+Vr*lt+ri*qt,u[3]=Tr*J+Nr*Le+Vr*Mt+ri*ur,u[4]=(Tr=_[4])*R+(Nr=_[5])*le+(Vr=_[6])*ze+(ri=_[7])*Dt,u[5]=Tr*j+Nr*ve+Vr*Ke+ri*tr,u[6]=Tr*$+Nr*Ie+Vr*lt+ri*qt,u[7]=Tr*J+Nr*Le+Vr*Mt+ri*ur,u[8]=(Tr=_[8])*R+(Nr=_[9])*le+(Vr=_[10])*ze+(ri=_[11])*Dt,u[9]=Tr*j+Nr*ve+Vr*Ke+ri*tr,u[10]=Tr*$+Nr*Ie+Vr*lt+ri*qt,u[11]=Tr*J+Nr*Le+Vr*Mt+ri*ur,u[12]=(Tr=_[12])*R+(Nr=_[13])*le+(Vr=_[14])*ze+(ri=_[15])*Dt,u[13]=Tr*j+Nr*ve+Vr*Ke+ri*tr,u[14]=Tr*$+Nr*Ie+Vr*lt+ri*qt,u[15]=Tr*J+Nr*Le+Vr*Mt+ri*ur,u}Math.hypot||(Math.hypot=function(){for(var u=arguments,p=0,_=arguments.length;_--;)p+=u[_]*u[_];return Math.sqrt(p)});var ef,t0=Ml;function Lp(u,p,_){var R=p[0],j=p[1],$=p[2],J=p[3];return u[0]=_[0]*R+_[4]*j+_[8]*$+_[12]*J,u[1]=_[1]*R+_[5]*j+_[9]*$+_[13]*J,u[2]=_[2]*R+_[6]*j+_[10]*$+_[14]*J,u[3]=_[3]*R+_[7]*j+_[11]*$+_[15]*J,u}ef=new _s(3),_s!=Float32Array&&(ef[0]=0,ef[1]=0,ef[2]=0),function(){var u=new _s(4);_s!=Float32Array&&(u[0]=0,u[1]=0,u[2]=0,u[3]=0)}();var th=(function(){var u=new _s(2);_s!=Float32Array&&(u[0]=0,u[1]=0)}(),function(u){function p(_){u.call(this,_,Ul)}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype.createBucket=function(_){return new _n(_)},p.prototype.queryRadius=function(_){var R=_;return na("circle-radius",this,R)+na("circle-stroke-width",this,R)+zl(this.paint.get("circle-translate"))},p.prototype.queryIntersectsFeature=function(_,R,j,$,J,le,ve,Ie){for(var Le=eh(_,this.paint.get("circle-translate"),this.paint.get("circle-translate-anchor"),le.angle,ve),ze=this.paint.get("circle-radius").evaluate(R,j)+this.paint.get("circle-stroke-width").evaluate(R,j),Ke=this.paint.get("circle-pitch-alignment")==="map",lt=Ke?Le:function(Ei,Ui){return Ei.map(function(Cn){return Kf(Cn,Ui)})}(Le,Ie),Mt=Ke?ze*ve:ze,Dt=0,tr=$;Dtu.width||j.height>u.height||_.x>u.width-j.width||_.y>u.height-j.height)throw new RangeError("out of range source coordinates for image copy");if(j.width>p.width||j.height>p.height||R.x>p.width-j.width||R.y>p.height-j.height)throw new RangeError("out of range destination coordinates for image copy");for(var J=u.data,le=p.data,ve=0;ve80*_){R=$=u[0],j=J=u[1];for(var Mt=_;Mt$&&($=le),ve>J&&(J=ve);Ie=(Ie=Math.max($-R,J-j))!==0?1/Ie:0}return P(Ke,lt,_,R,j,Ie),lt}function m(u,p,_,R,j){var $,J;if(j===Cr(u,p,_,R)>0)for($=p;$<_;$+=R)J=zt($,u[$],u[$+1],J);else for($=_-R;$>=p;$-=R)J=zt($,u[$],u[$+1],J);return J&&vt(J,J.next)&&(jt(J),J=J.next),J}function T(u,p){if(!u)return u;p||(p=u);var _,R=u;do if(_=!1,R.steiner||!vt(R,R.next)&&At(R.prev,R,R.next)!==0)R=R.next;else{if(jt(R),(R=p=R.prev)===R.next)break;_=!0}while(_||R!==p);return p}function P(u,p,_,R,j,$,J){if(u){!J&&$&&function(Le,ze,Ke,lt){var Mt=Le;do Mt.z===null&&(Mt.z=Me(Mt.x,Mt.y,ze,Ke,lt)),Mt.prevZ=Mt.prev,Mt.nextZ=Mt.next,Mt=Mt.next;while(Mt!==Le);Mt.prevZ.nextZ=null,Mt.prevZ=null,function(Dt){var tr,qt,ur,Tr,Nr,Vr,ri,Ei,Ui=1;do{for(qt=Dt,Dt=null,Nr=null,Vr=0;qt;){for(Vr++,ur=qt,ri=0,tr=0;tr0||Ei>0&&ur;)ri!==0&&(Ei===0||!ur||qt.z<=ur.z)?(Tr=qt,qt=qt.nextZ,ri--):(Tr=ur,ur=ur.nextZ,Ei--),Nr?Nr.nextZ=Tr:Dt=Tr,Tr.prevZ=Nr,Nr=Tr;qt=ur}Nr.nextZ=null,Ui*=2}while(Vr>1)}(Mt)}(u,R,j,$);for(var le,ve,Ie=u;u.prev!==u.next;)if(le=u.prev,ve=u.next,$?W(u,R,j,$):V(u))p.push(le.i/_),p.push(u.i/_),p.push(ve.i/_),jt(u),u=ve.next,Ie=ve.next;else if((u=ve)===Ie){J?J===1?P(u=te(T(u),p,_),p,_,R,j,$,2):J===2&&se(u,p,_,R,j,$):P(T(u),p,_,R,j,$,1);break}}}function V(u){var p=u.prev,_=u,R=u.next;if(At(p,_,R)>=0)return!1;for(var j=u.next.next;j!==u.prev;){if(tt(p.x,p.y,_.x,_.y,R.x,R.y,j.x,j.y)&&At(j.prev,j,j.next)>=0)return!1;j=j.next}return!0}function W(u,p,_,R){var j=u.prev,$=u,J=u.next;if(At(j,$,J)>=0)return!1;for(var le=j.x>$.x?j.x>J.x?j.x:J.x:$.x>J.x?$.x:J.x,ve=j.y>$.y?j.y>J.y?j.y:J.y:$.y>J.y?$.y:J.y,Ie=Me(j.x<$.x?j.x=Ie&&Ke&&Ke.z<=Le;){if(ze!==u.prev&&ze!==u.next&&tt(j.x,j.y,$.x,$.y,J.x,J.y,ze.x,ze.y)&&At(ze.prev,ze,ze.next)>=0||(ze=ze.prevZ,Ke!==u.prev&&Ke!==u.next&&tt(j.x,j.y,$.x,$.y,J.x,J.y,Ke.x,Ke.y)&&At(Ke.prev,Ke,Ke.next)>=0))return!1;Ke=Ke.nextZ}for(;ze&&ze.z>=Ie;){if(ze!==u.prev&&ze!==u.next&&tt(j.x,j.y,$.x,$.y,J.x,J.y,ze.x,ze.y)&&At(ze.prev,ze,ze.next)>=0)return!1;ze=ze.prevZ}for(;Ke&&Ke.z<=Le;){if(Ke!==u.prev&&Ke!==u.next&&tt(j.x,j.y,$.x,$.y,J.x,J.y,Ke.x,Ke.y)&&At(Ke.prev,Ke,Ke.next)>=0)return!1;Ke=Ke.nextZ}return!0}function te(u,p,_){var R=u;do{var j=R.prev,$=R.next.next;!vt(j,$)&&Lt(j,R,R.next,$)&&Xt(j,$)&&Xt($,j)&&(p.push(j.i/_),p.push(R.i/_),p.push($.i/_),jt(R),jt(R.next),R=u=$),R=R.next}while(R!==u);return T(R)}function se(u,p,_,R,j,$){var J=u;do{for(var le=J.next.next;le!==J.prev;){if(J.i!==le.i&&yt(J,le)){var ve=Rt(J,le);return J=T(J,J.next),ve=T(ve,ve.next),P(J,p,_,R,j,$),void P(ve,p,_,R,j,$)}le=le.next}J=J.next}while(J!==u)}function fe(u,p){return u.x-p.x}function ye(u,p){if(p=function(R,j){var $,J=j,le=R.x,ve=R.y,Ie=-1/0;do{if(ve<=J.y&&ve>=J.next.y&&J.next.y!==J.y){var Le=J.x+(ve-J.y)*(J.next.x-J.x)/(J.next.y-J.y);if(Le<=le&&Le>Ie){if(Ie=Le,Le===le){if(ve===J.y)return J;if(ve===J.next.y)return J.next}$=J.x=J.x&&J.x>=lt&&le!==J.x&&tt(ve$.x||J.x===$.x&&Re($,J)))&&($=J,Dt=ze)),J=J.next;while(J!==Ke);return $}(u,p)){var _=Rt(p,u);T(p,p.next),T(_,_.next)}}function Re(u,p){return At(u.prev,u,p.prev)<0&&At(p.next,u,u.next)<0}function Me(u,p,_,R,j){return(u=1431655765&((u=858993459&((u=252645135&((u=16711935&((u=32767*(u-_)*j)|u<<8))|u<<4))|u<<2))|u<<1))|(p=1431655765&((p=858993459&((p=252645135&((p=16711935&((p=32767*(p-R)*j)|p<<8))|p<<4))|p<<2))|p<<1))<<1}function je(u){var p=u,_=u;do(p.x<_.x||p.x===_.x&&p.y<_.y)&&(_=p),p=p.next;while(p!==u);return _}function tt(u,p,_,R,j,$,J,le){return(j-J)*(p-le)-(u-J)*($-le)>=0&&(u-J)*(R-le)-(_-J)*(p-le)>=0&&(_-J)*($-le)-(j-J)*(R-le)>=0}function yt(u,p){return u.next.i!==p.i&&u.prev.i!==p.i&&!function(_,R){var j=_;do{if(j.i!==_.i&&j.next.i!==_.i&&j.i!==R.i&&j.next.i!==R.i&&Lt(j,j.next,_,R))return!0;j=j.next}while(j!==_);return!1}(u,p)&&(Xt(u,p)&&Xt(p,u)&&function(_,R){var j=_,$=!1,J=(_.x+R.x)/2,le=(_.y+R.y)/2;do j.y>le!=j.next.y>le&&j.next.y!==j.y&&J<(j.next.x-j.x)*(le-j.y)/(j.next.y-j.y)+j.x&&($=!$),j=j.next;while(j!==_);return $}(u,p)&&(At(u.prev,u,p.prev)||At(u,p.prev,p))||vt(u,p)&&At(u.prev,u,u.next)>0&&At(p.prev,p,p.next)>0)}function At(u,p,_){return(p.y-u.y)*(_.x-p.x)-(p.x-u.x)*(_.y-p.y)}function vt(u,p){return u.x===p.x&&u.y===p.y}function Lt(u,p,_,R){var j=It(At(u,p,_)),$=It(At(u,p,R)),J=It(At(_,R,u)),le=It(At(_,R,p));return j!==$&&J!==le||!(j!==0||!Kt(u,_,p))||!($!==0||!Kt(u,R,p))||!(J!==0||!Kt(_,u,R))||!(le!==0||!Kt(_,p,R))}function Kt(u,p,_){return p.x<=Math.max(u.x,_.x)&&p.x>=Math.min(u.x,_.x)&&p.y<=Math.max(u.y,_.y)&&p.y>=Math.min(u.y,_.y)}function It(u){return u>0?1:u<0?-1:0}function Xt(u,p){return At(u.prev,u,u.next)<0?At(u,p,u.next)>=0&&At(u,u.prev,p)>=0:At(u,p,u.prev)<0||At(u,u.next,p)<0}function Rt(u,p){var _=new br(u.i,u.x,u.y),R=new br(p.i,p.x,p.y),j=u.next,$=p.prev;return u.next=p,p.prev=u,_.next=j,j.prev=_,R.next=_,_.prev=R,$.next=R,R.prev=$,R}function zt(u,p,_,R){var j=new br(u,p,_);return R?(j.next=R.next,j.prev=R,R.next.prev=j,R.next=j):(j.prev=j,j.next=j),j}function jt(u){u.next.prev=u.prev,u.prev.next=u.next,u.prevZ&&(u.prevZ.nextZ=u.nextZ),u.nextZ&&(u.nextZ.prevZ=u.prevZ)}function br(u,p,_){this.i=u,this.x=p,this.y=_,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function Cr(u,p,_,R){for(var j=0,$=p,J=_-R;$<_;$+=R)j+=(u[J]-u[$])*(u[$+1]+u[J+1]),J=$;return j}function Rr(u,p,_,R,j){(function $(J,le,ve,Ie,Le){for(;Ie>ve;){if(Ie-ve>600){var ze=Ie-ve+1,Ke=le-ve+1,lt=Math.log(ze),Mt=.5*Math.exp(2*lt/3),Dt=.5*Math.sqrt(lt*Mt*(ze-Mt)/ze)*(Ke-ze/2<0?-1:1);$(J,le,Math.max(ve,Math.floor(le-Ke*Mt/ze+Dt)),Math.min(Ie,Math.floor(le+(ze-Ke)*Mt/ze+Dt)),Le)}var tr=J[le],qt=ve,ur=Ie;for(Pr(J,ve,le),Le(J[Ie],tr)>0&&Pr(J,ve,Ie);qt0;)ur--}Le(J[ve],tr)===0?Pr(J,ve,ur):Pr(J,++ur,Ie),ur<=le&&(ve=ur+1),le<=ur&&(Ie=ur-1)}})(u,p,_||0,R||u.length-1,j||Ai)}function Pr(u,p,_){var R=u[p];u[p]=u[_],u[_]=R}function Ai(u,p){return up?1:0}function _i(u,p){var _=u.length;if(_<=1)return[u];for(var R,j,$=[],J=0;J<_;J++){var le=Ze(u[J]);le!==0&&(u[J].area=Math.abs(le),j===void 0&&(j=le<0),j===le<0?(R&&$.push(R),R=[u[J]]):R.push(u[J]))}if(R&&$.push(R),p>1)for(var ve=0;ve<$.length;ve++)$[ve].length<=p||(Rr($[ve],p,1,$[ve].length-1,hi),$[ve]=$[ve].slice(0,p));return $}function hi(u,p){return p.area-u.area}function hn(u,p,_){for(var R=_.patternDependencies,j=!1,$=0,J=p;$0&&_.holes.push(R+=u[j-1].length)}return _},r0.default=z;var $r=function(u){this.zoom=u.zoom,this.overscaling=u.overscaling,this.layers=u.layers,this.layerIds=this.layers.map(function(p){return p.id}),this.index=u.index,this.hasPattern=!1,this.patternFeatures=[],this.layoutVertexArray=new Yh,this.indexArray=new Kh,this.indexArray2=new Kd,this.programConfigurations=new Rn(u.layers,u.zoom),this.segments=new ft,this.segments2=new ft,this.stateDependentLayerIds=this.layers.filter(function(p){return p.isStateDependent()}).map(function(p){return p.id})};$r.prototype.populate=function(u,p,_){this.hasPattern=hn("fill",this.layers,p);for(var R=this.layers[0].layout.get("fill-sort-key"),j=[],$=0,J=u;$>3}if(j--,R===1||R===2)$+=u.readSVarint(),J+=u.readSVarint(),R===1&&(p&&le.push(p),p=[]),p.push(new f($,J));else{if(R!==7)throw new Error("unknown command "+R);p&&p.push(p[0].clone())}}return p&&le.push(p),le},qs.prototype.bbox=function(){var u=this._pbf;u.pos=this._geometry;for(var p=u.readVarint()+u.pos,_=1,R=0,j=0,$=0,J=1/0,le=-1/0,ve=1/0,Ie=-1/0;u.pos>3}if(R--,_===1||_===2)(j+=u.readSVarint())le&&(le=j),($+=u.readSVarint())Ie&&(Ie=$);else if(_!==7)throw new Error("unknown command "+_)}return[J,ve,le,Ie]},qs.prototype.toGeoJSON=function(u,p,_){var R,j,$=this.extent*Math.pow(2,_),J=this.extent*u,le=this.extent*p,ve=this.loadGeometry(),Ie=qs.types[this.type];function Le(lt){for(var Mt=0;Mt>3;j=J===1?R.readString():J===2?R.readFloat():J===3?R.readDouble():J===4?R.readVarint64():J===5?R.readVarint():J===6?R.readSVarint():J===7?R.readBoolean():null}return j}(_))}function E(u,p,_){if(u===3){var R=new Ea(_,_.readVarint()+_.pos);R.length&&(p[R.name]=R)}}v.prototype.feature=function(u){if(u<0||u>=this._features.length)throw new Error("feature index out of bounds");this._pbf.pos=this._features[u];var p=this._pbf.readVarint()+this._pbf.pos;return new jl(this._pbf,p,this.extent,this._keys,this._values)};var B={VectorTile:function(u,p){this.layers=u.readFields(E,{},p)},VectorTileFeature:jl,VectorTileLayer:Ea},N=B.VectorTileFeature.types,G=Math.pow(2,13);function X(u,p,_,R,j,$,J,le){u.emplaceBack(p,_,2*Math.floor(R*G)+J,j*G*2,$*G*2,Math.round(le))}var Q=function(u){this.zoom=u.zoom,this.overscaling=u.overscaling,this.layers=u.layers,this.layerIds=this.layers.map(function(p){return p.id}),this.index=u.index,this.hasPattern=!1,this.layoutVertexArray=new _c,this.indexArray=new Kh,this.programConfigurations=new Rn(u.layers,u.zoom),this.segments=new ft,this.stateDependentLayerIds=this.layers.filter(function(p){return p.isStateDependent()}).map(function(p){return p.id})};function ue(u,p){return u.x===p.x&&(u.x<0||u.x>8192)||u.y===p.y&&(u.y<0||u.y>8192)}Q.prototype.populate=function(u,p,_){this.features=[],this.hasPattern=hn("fill-extrusion",this.layers,p);for(var R=0,j=u;R8192})||Jo.every(function(xo){return xo.y<0})||Jo.every(function(xo){return xo.y>8192})))for(var Dt=0,tr=0;tr=1){var ur=Mt[tr-1];if(!ue(qt,ur)){ze.vertexLength+4>ft.MAX_VERTEX_ARRAY_LENGTH&&(ze=this.segments.prepareSegment(4,this.layoutVertexArray,this.indexArray));var Tr=qt.sub(ur)._perp()._unit(),Nr=ur.dist(qt);Dt+Nr>32768&&(Dt=0),X(this.layoutVertexArray,qt.x,qt.y,Tr.x,Tr.y,0,0,Dt),X(this.layoutVertexArray,qt.x,qt.y,Tr.x,Tr.y,0,1,Dt),X(this.layoutVertexArray,ur.x,ur.y,Tr.x,Tr.y,0,0,Dt+=Nr),X(this.layoutVertexArray,ur.x,ur.y,Tr.x,Tr.y,0,1,Dt);var Vr=ze.vertexLength;this.indexArray.emplaceBack(Vr,Vr+2,Vr+1),this.indexArray.emplaceBack(Vr+1,Vr+2,Vr+3),ze.vertexLength+=4,ze.primitiveLength+=2}}}}if(ze.vertexLength+ve>ft.MAX_VERTEX_ARRAY_LENGTH&&(ze=this.segments.prepareSegment(ve,this.layoutVertexArray,this.indexArray)),N[u.type]==="Polygon"){for(var ri=[],Ei=[],Ui=ze.vertexLength,Cn=0,Ki=le;Cn=2&&u[ve-1].equals(u[ve-2]);)ve--;for(var Ie=0;Ie0;if(Ei&&qt>Ie){var Cn=Le.dist(lt);if(Cn>2*ze){var Ki=Le.sub(Le.sub(lt)._mult(ze/Cn)._round());this.updateDistance(lt,Ki),this.addCurrentVertex(Ki,Dt,0,0,Ke),lt=Ki}}var Bn=lt&&Mt,en=Bn?_:le?"butt":R;if(Bn&&en==="round"&&(Vr<$?en="miter":Vr<=2&&(en="fakeround")),en==="miter"&&Vr>j&&(en="bevel"),en==="bevel"&&(Vr>2&&(en="flipbevel"),Vr100)ur=tr.mult(-1);else{var Wo=Vr*Dt.add(tr).mag()/Dt.sub(tr).mag();ur._perp()._mult(Wo*(Ui?-1:1))}this.addCurrentVertex(Le,ur,0,0,Ke),this.addCurrentVertex(Le,ur.mult(-1),0,0,Ke)}else if(en==="bevel"||en==="fakeround"){var Xn=-Math.sqrt(Vr*Vr-1),pn=Ui?Xn:0,Jo=Ui?0:Xn;if(lt&&this.addCurrentVertex(Le,Dt,pn,Jo,Ke),en==="fakeround")for(var xo=Math.round(180*ri/Math.PI/20),es=1;es2*ze){var fl=Le.add(Mt.sub(Le)._mult(ze/Wl)._round());this.updateDistance(Le,fl),this.addCurrentVertex(fl,tr,0,0,Ke),Le=fl}}}}},_r.prototype.addCurrentVertex=function(u,p,_,R,j,$){$===void 0&&($=!1);var J=p.y*R-p.x,le=-p.y-p.x*R;this.addHalfVertex(u,p.x+p.y*_,p.y-p.x*_,$,!1,_,j),this.addHalfVertex(u,J,le,$,!0,-R,j),this.distance>qr/2&&this.totalDistance===0&&(this.distance=0,this.addCurrentVertex(u,p,_,R,j,$))},_r.prototype.addHalfVertex=function(u,p,_,R,j,$,J){var le=.5*(this.lineClips?this.scaledDistance*(qr-1):this.scaledDistance);this.layoutVertexArray.emplaceBack((u.x<<1)+(R?1:0),(u.y<<1)+(j?1:0),Math.round(63*p)+128,Math.round(63*_)+128,1+($===0?0:$<0?-1:1)|(63&le)<<2,le>>6),this.lineClips&&this.layoutVertexArray2.emplaceBack((this.scaledDistance-this.lineClips.start)/(this.lineClips.end-this.lineClips.start),this.lineClipsArray.length);var ve=J.vertexLength++;this.e1>=0&&this.e2>=0&&(this.indexArray.emplaceBack(this.e1,this.e2,ve),J.primitiveLength++),j?this.e2=ve:this.e1=ve},_r.prototype.updateScaledDistance=function(){this.scaledDistance=this.lineClips?this.lineClips.start+(this.lineClips.end-this.lineClips.start)*this.distance/this.totalDistance:this.distance},_r.prototype.updateDistance=function(u,p){this.distance+=u.dist(p),this.updateScaledDistance()},Yi("LineBucket",_r,{omit:["layers","patternFeatures"]});var Sr=new Cl({"line-cap":new An(ht.layout_line["line-cap"]),"line-join":new nn(ht.layout_line["line-join"]),"line-miter-limit":new An(ht.layout_line["line-miter-limit"]),"line-round-limit":new An(ht.layout_line["line-round-limit"]),"line-sort-key":new nn(ht.layout_line["line-sort-key"])}),or={paint:new Cl({"line-opacity":new nn(ht.paint_line["line-opacity"]),"line-color":new nn(ht.paint_line["line-color"]),"line-translate":new An(ht.paint_line["line-translate"]),"line-translate-anchor":new An(ht.paint_line["line-translate-anchor"]),"line-width":new nn(ht.paint_line["line-width"]),"line-gap-width":new nn(ht.paint_line["line-gap-width"]),"line-offset":new nn(ht.paint_line["line-offset"]),"line-blur":new nn(ht.paint_line["line-blur"]),"line-dasharray":new Vc(ht.paint_line["line-dasharray"]),"line-pattern":new Xd(ht.paint_line["line-pattern"]),"line-gradient":new Au(ht.paint_line["line-gradient"])}),layout:Sr},Pi=new(function(u){function p(){u.apply(this,arguments)}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype.possiblyEvaluate=function(_,R){return R=new So(Math.floor(R.zoom),{now:R.now,fadeDuration:R.fadeDuration,zoomHistory:R.zoomHistory,transition:R.transition}),u.prototype.possiblyEvaluate.call(this,_,R)},p.prototype.evaluate=function(_,R,j,$){return R=ee({},R,{zoom:Math.floor(R.zoom)}),u.prototype.evaluate.call(this,_,R,j,$)},p}(nn))(or.paint.properties["line-width"].specification);Pi.useIntegerZoom=!0;var En=function(u){function p(_){u.call(this,_,or),this.gradientVersion=0}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype._handleSpecialPaintPropertyUpdate=function(_){_==="line-gradient"&&(this.stepInterpolant=this._transitionablePaint._values["line-gradient"].value.expression._styleExpression.expression instanceof xl,this.gradientVersion=(this.gradientVersion+1)%I)},p.prototype.gradientExpression=function(){return this._transitionablePaint._values["line-gradient"].value.expression},p.prototype.recalculate=function(_,R){u.prototype.recalculate.call(this,_,R),this.paint._values["line-floorwidth"]=Pi.possiblyEvaluate(this._transitioningPaint._values["line-width"].value,_)},p.prototype.createBucket=function(_){return new _r(_)},p.prototype.queryRadius=function(_){var R=_,j=wn(na("line-width",this,R),na("line-gap-width",this,R)),$=na("line-offset",this,R);return j/2+Math.abs($)+zl(this.paint.get("line-translate"))},p.prototype.queryIntersectsFeature=function(_,R,j,$,J,le,ve){var Ie=eh(_,this.paint.get("line-translate"),this.paint.get("line-translate-anchor"),le.angle,ve),Le=ve/2*wn(this.paint.get("line-width").evaluate(R,j),this.paint.get("line-gap-width").evaluate(R,j)),ze=this.paint.get("line-offset").evaluate(R,j);return ze&&($=function(Ke,lt){for(var Mt=[],Dt=new f(0,0),tr=0;tr=3){for(var qt=0;qt0?p+2*u:u}var vo=da([{name:"a_pos_offset",components:4,type:"Int16"},{name:"a_data",components:4,type:"Uint16"},{name:"a_pixeloffset",components:4,type:"Int16"}],4),Ro=da([{name:"a_projected_pos",components:3,type:"Float32"}],4),Yo=(da([{name:"a_fade_opacity",components:1,type:"Uint32"}],4),da([{name:"a_placed",components:2,type:"Uint8"},{name:"a_shift",components:2,type:"Float32"}])),ro=(da([{type:"Int16",name:"anchorPointX"},{type:"Int16",name:"anchorPointY"},{type:"Int16",name:"x1"},{type:"Int16",name:"y1"},{type:"Int16",name:"x2"},{type:"Int16",name:"y2"},{type:"Uint32",name:"featureIndex"},{type:"Uint16",name:"sourceLayerIndex"},{type:"Uint16",name:"bucketIndex"}]),da([{name:"a_pos",components:2,type:"Int16"},{name:"a_anchor_pos",components:2,type:"Int16"},{name:"a_extrude",components:2,type:"Int16"}],4)),kn=da([{name:"a_pos",components:2,type:"Float32"},{name:"a_radius",components:1,type:"Float32"},{name:"a_flags",components:2,type:"Int16"}],4);function Oi(u,p,_){return u.sections.forEach(function(R){R.text=function(j,$,J){var le=$.layout.get("text-transform").evaluate(J,{});return le==="uppercase"?j=j.toLocaleUpperCase():le==="lowercase"&&(j=j.toLocaleLowerCase()),gu.applyArabicShaping&&(j=gu.applyArabicShaping(j)),j}(R.text,p,_)}),u}da([{name:"triangle",components:3,type:"Uint16"}]),da([{type:"Int16",name:"anchorX"},{type:"Int16",name:"anchorY"},{type:"Uint16",name:"glyphStartIndex"},{type:"Uint16",name:"numGlyphs"},{type:"Uint32",name:"vertexStartIndex"},{type:"Uint32",name:"lineStartIndex"},{type:"Uint32",name:"lineLength"},{type:"Uint16",name:"segment"},{type:"Uint16",name:"lowerSize"},{type:"Uint16",name:"upperSize"},{type:"Float32",name:"lineOffsetX"},{type:"Float32",name:"lineOffsetY"},{type:"Uint8",name:"writingMode"},{type:"Uint8",name:"placedOrientation"},{type:"Uint8",name:"hidden"},{type:"Uint32",name:"crossTileID"},{type:"Int16",name:"associatedIconIndex"}]),da([{type:"Int16",name:"anchorX"},{type:"Int16",name:"anchorY"},{type:"Int16",name:"rightJustifiedTextSymbolIndex"},{type:"Int16",name:"centerJustifiedTextSymbolIndex"},{type:"Int16",name:"leftJustifiedTextSymbolIndex"},{type:"Int16",name:"verticalPlacedTextSymbolIndex"},{type:"Int16",name:"placedIconSymbolIndex"},{type:"Int16",name:"verticalPlacedIconSymbolIndex"},{type:"Uint16",name:"key"},{type:"Uint16",name:"textBoxStartIndex"},{type:"Uint16",name:"textBoxEndIndex"},{type:"Uint16",name:"verticalTextBoxStartIndex"},{type:"Uint16",name:"verticalTextBoxEndIndex"},{type:"Uint16",name:"iconBoxStartIndex"},{type:"Uint16",name:"iconBoxEndIndex"},{type:"Uint16",name:"verticalIconBoxStartIndex"},{type:"Uint16",name:"verticalIconBoxEndIndex"},{type:"Uint16",name:"featureIndex"},{type:"Uint16",name:"numHorizontalGlyphVertices"},{type:"Uint16",name:"numVerticalGlyphVertices"},{type:"Uint16",name:"numIconVertices"},{type:"Uint16",name:"numVerticalIconVertices"},{type:"Uint16",name:"useRuntimeCollisionCircles"},{type:"Uint32",name:"crossTileID"},{type:"Float32",name:"textBoxScale"},{type:"Float32",components:2,name:"textOffset"},{type:"Float32",name:"collisionCircleDiameter"}]),da([{type:"Float32",name:"offsetX"}]),da([{type:"Int16",name:"x"},{type:"Int16",name:"y"},{type:"Int16",name:"tileUnitDistanceFromAnchor"}]);var Ko={"!":"\uFE15","#":"\uFF03",$:"\uFF04","%":"\uFF05","&":"\uFF06","(":"\uFE35",")":"\uFE36","*":"\uFF0A","+":"\uFF0B",",":"\uFE10","-":"\uFE32",".":"\u30FB","/":"\uFF0F",":":"\uFE13",";":"\uFE14","<":"\uFE3F","=":"\uFF1D",">":"\uFE40","?":"\uFE16","@":"\uFF20","[":"\uFE47","\\":"\uFF3C","]":"\uFE48","^":"\uFF3E",_:"\uFE33","`":"\uFF40","{":"\uFE37","|":"\u2015","}":"\uFE38","~":"\uFF5E","\xA2":"\uFFE0","\xA3":"\uFFE1","\xA5":"\uFFE5","\xA6":"\uFFE4","\xAC":"\uFFE2","\xAF":"\uFFE3","\u2013":"\uFE32","\u2014":"\uFE31","\u2018":"\uFE43","\u2019":"\uFE44","\u201C":"\uFE41","\u201D":"\uFE42","\u2026":"\uFE19","\u2027":"\u30FB","\u20A9":"\uFFE6","\u3001":"\uFE11","\u3002":"\uFE12","\u3008":"\uFE3F","\u3009":"\uFE40","\u300A":"\uFE3D","\u300B":"\uFE3E","\u300C":"\uFE41","\u300D":"\uFE42","\u300E":"\uFE43","\u300F":"\uFE44","\u3010":"\uFE3B","\u3011":"\uFE3C","\u3014":"\uFE39","\u3015":"\uFE3A","\u3016":"\uFE17","\u3017":"\uFE18","\uFF01":"\uFE15","\uFF08":"\uFE35","\uFF09":"\uFE36","\uFF0C":"\uFE10","\uFF0D":"\uFE32","\uFF0E":"\u30FB","\uFF1A":"\uFE13","\uFF1B":"\uFE14","\uFF1C":"\uFE3F","\uFF1E":"\uFE40","\uFF1F":"\uFE16","\uFF3B":"\uFE47","\uFF3D":"\uFE48","\uFF3F":"\uFE33","\uFF5B":"\uFE37","\uFF5C":"\u2015","\uFF5D":"\uFE38","\uFF5F":"\uFE35","\uFF60":"\uFE36","\uFF61":"\uFE12","\uFF62":"\uFE41","\uFF63":"\uFE42"},Ca=function(u,p,_,R,j){var $,J,le=8*j-R-1,ve=(1<>1,Le=-7,ze=_?j-1:0,Ke=_?-1:1,lt=u[p+ze];for(ze+=Ke,$=lt&(1<<-Le)-1,lt>>=-Le,Le+=le;Le>0;$=256*$+u[p+ze],ze+=Ke,Le-=8);for(J=$&(1<<-Le)-1,$>>=-Le,Le+=R;Le>0;J=256*J+u[p+ze],ze+=Ke,Le-=8);if($===0)$=1-Ie;else{if($===ve)return J?NaN:1/0*(lt?-1:1);J+=Math.pow(2,R),$-=Ie}return(lt?-1:1)*J*Math.pow(2,$-R)},Qo=function(u,p,_,R,j,$){var J,le,ve,Ie=8*$-j-1,Le=(1<>1,Ke=j===23?Math.pow(2,-24)-Math.pow(2,-77):0,lt=R?0:$-1,Mt=R?1:-1,Dt=p<0||p===0&&1/p<0?1:0;for(p=Math.abs(p),isNaN(p)||p===1/0?(le=isNaN(p)?1:0,J=Le):(J=Math.floor(Math.log(p)/Math.LN2),p*(ve=Math.pow(2,-J))<1&&(J--,ve*=2),(p+=J+ze>=1?Ke/ve:Ke*Math.pow(2,1-ze))*ve>=2&&(J++,ve/=2),J+ze>=Le?(le=0,J=Le):J+ze>=1?(le=(p*ve-1)*Math.pow(2,j),J+=ze):(le=p*Math.pow(2,ze-1)*Math.pow(2,j),J=0));j>=8;u[_+lt]=255&le,lt+=Mt,le/=256,j-=8);for(J=J<0;u[_+lt]=255&J,lt+=Mt,J/=256,Ie-=8);u[_+lt-Mt]|=128*Dt},va=Bo;function Bo(u){this.buf=ArrayBuffer.isView&&ArrayBuffer.isView(u)?u:new Uint8Array(u||0),this.pos=0,this.type=0,this.length=this.buf.length}Bo.Varint=0,Bo.Fixed64=1,Bo.Bytes=2,Bo.Fixed32=5;var ib=typeof TextDecoder>"u"?null:new TextDecoder("utf8");function Sd(u){return u.type===Bo.Bytes?u.readVarint()+u.pos:u.pos+1}function i0(u,p,_){return _?4294967296*p+(u>>>0):4294967296*(p>>>0)+(u>>>0)}function nb(u,p,_){var R=p<=16383?1:p<=2097151?2:p<=268435455?3:Math.floor(Math.log(p)/(7*Math.LN2));_.realloc(R);for(var j=_.pos-1;j>=u;j--)_.buf[j+R]=_.buf[j]}function s8(u,p){for(var _=0;_>>8,u[_+2]=p>>>16,u[_+3]=p>>>24}function GC(u,p){return(u[p]|u[p+1]<<8|u[p+2]<<16)+(u[p+3]<<24)}function VL(u,p,_){u===1&&_.readMessage(h8,p)}function h8(u,p,_){if(u===3){var R=_.readMessage(WC,{}),j=R.width,$=R.height,J=R.left,le=R.top,ve=R.advance;p.push({id:R.id,bitmap:new Fu({width:j+6,height:$+6},R.bitmap),metrics:{width:j,height:$,left:J,top:le,advance:ve}})}}function WC(u,p,_){u===1?p.id=_.readVarint():u===2?p.bitmap=_.readBytes():u===3?p.width=_.readVarint():u===4?p.height=_.readVarint():u===5?p.left=_.readSVarint():u===6?p.top=_.readSVarint():u===7&&(p.advance=_.readVarint())}function qC(u){for(var p=0,_=0,R=0,j=u;R=0;Ke--){var lt=J[Ke];if(!(ze.w>lt.w||ze.h>lt.h)){if(ze.x=lt.x,ze.y=lt.y,ve=Math.max(ve,ze.y+ze.h),le=Math.max(le,ze.x+ze.w),ze.w===lt.w&&ze.h===lt.h){var Mt=J.pop();Ke>3,$=this.pos;this.type=7&R,u(j,p,this),this.pos===$&&this.skip(R)}return p},readMessage:function(u,p){return this.readFields(u,p,this.readVarint()+this.pos)},readFixed32:function(){var u=m2(this.buf,this.pos);return this.pos+=4,u},readSFixed32:function(){var u=GC(this.buf,this.pos);return this.pos+=4,u},readFixed64:function(){var u=m2(this.buf,this.pos)+4294967296*m2(this.buf,this.pos+4);return this.pos+=8,u},readSFixed64:function(){var u=m2(this.buf,this.pos)+4294967296*GC(this.buf,this.pos+4);return this.pos+=8,u},readFloat:function(){var u=Ca(this.buf,this.pos,!0,23,4);return this.pos+=4,u},readDouble:function(){var u=Ca(this.buf,this.pos,!0,52,8);return this.pos+=8,u},readVarint:function(u){var p,_,R=this.buf;return p=127&(_=R[this.pos++]),_<128?p:(p|=(127&(_=R[this.pos++]))<<7,_<128?p:(p|=(127&(_=R[this.pos++]))<<14,_<128?p:(p|=(127&(_=R[this.pos++]))<<21,_<128?p:function(j,$,J){var le,ve,Ie=J.buf;if(le=(112&(ve=Ie[J.pos++]))>>4,ve<128||(le|=(127&(ve=Ie[J.pos++]))<<3,ve<128)||(le|=(127&(ve=Ie[J.pos++]))<<10,ve<128)||(le|=(127&(ve=Ie[J.pos++]))<<17,ve<128)||(le|=(127&(ve=Ie[J.pos++]))<<24,ve<128)||(le|=(1&(ve=Ie[J.pos++]))<<31,ve<128))return i0(j,le,$);throw new Error("Expected varint not more than 10 bytes")}(p|=(15&(_=R[this.pos]))<<28,u,this))))},readVarint64:function(){return this.readVarint(!0)},readSVarint:function(){var u=this.readVarint();return u%2==1?(u+1)/-2:u/2},readBoolean:function(){return Boolean(this.readVarint())},readString:function(){var u=this.readVarint()+this.pos,p=this.pos;return this.pos=u,u-p>=12&&ib?function(_,R,j){return ib.decode(_.subarray(R,j))}(this.buf,p,u):function(_,R,j){for(var $="",J=R;J239?4:Le>223?3:Le>191?2:1;if(J+Ke>j)break;Ke===1?Le<128&&(ze=Le):Ke===2?(192&(le=_[J+1]))==128&&(ze=(31&Le)<<6|63&le)<=127&&(ze=null):Ke===3?(ve=_[J+2],(192&(le=_[J+1]))==128&&(192&ve)==128&&((ze=(15&Le)<<12|(63&le)<<6|63&ve)<=2047||ze>=55296&&ze<=57343)&&(ze=null)):Ke===4&&(ve=_[J+2],Ie=_[J+3],(192&(le=_[J+1]))==128&&(192&ve)==128&&(192&Ie)==128&&((ze=(15&Le)<<18|(63&le)<<12|(63&ve)<<6|63&Ie)<=65535||ze>=1114112)&&(ze=null)),ze===null?(ze=65533,Ke=1):ze>65535&&(ze-=65536,$+=String.fromCharCode(ze>>>10&1023|55296),ze=56320|1023&ze),$+=String.fromCharCode(ze),J+=Ke}return $}(this.buf,p,u)},readBytes:function(){var u=this.readVarint()+this.pos,p=this.buf.subarray(this.pos,u);return this.pos=u,p},readPackedVarint:function(u,p){if(this.type!==Bo.Bytes)return u.push(this.readVarint(p));var _=Sd(this);for(u=u||[];this.pos<_;)u.push(this.readVarint(p));return u},readPackedSVarint:function(u){if(this.type!==Bo.Bytes)return u.push(this.readSVarint());var p=Sd(this);for(u=u||[];this.pos127;);else if(p===Bo.Bytes)this.pos=this.readVarint()+this.pos;else if(p===Bo.Fixed32)this.pos+=4;else{if(p!==Bo.Fixed64)throw new Error("Unimplemented type: "+p);this.pos+=8}},writeTag:function(u,p){this.writeVarint(u<<3|p)},realloc:function(u){for(var p=this.length||16;p268435455||u<0?function(p,_){var R,j;if(p>=0?(R=p%4294967296|0,j=p/4294967296|0):(j=~(-p/4294967296),4294967295^(R=~(-p%4294967296))?R=R+1|0:(R=0,j=j+1|0)),p>=18446744073709552e3||p<-18446744073709552e3)throw new Error("Given varint doesn't fit into 10 bytes");_.realloc(10),function($,J,le){le.buf[le.pos++]=127&$|128,$>>>=7,le.buf[le.pos++]=127&$|128,$>>>=7,le.buf[le.pos++]=127&$|128,$>>>=7,le.buf[le.pos++]=127&$|128,le.buf[le.pos]=127&($>>>=7)}(R,0,_),function($,J){var le=(7&$)<<4;J.buf[J.pos++]|=le|(($>>>=3)?128:0),$&&(J.buf[J.pos++]=127&$|(($>>>=7)?128:0),$&&(J.buf[J.pos++]=127&$|(($>>>=7)?128:0),$&&(J.buf[J.pos++]=127&$|(($>>>=7)?128:0),$&&(J.buf[J.pos++]=127&$|(($>>>=7)?128:0),$&&(J.buf[J.pos++]=127&$)))))}(j,_)}(u,this):(this.realloc(4),this.buf[this.pos++]=127&u|(u>127?128:0),u<=127||(this.buf[this.pos++]=127&(u>>>=7)|(u>127?128:0),u<=127||(this.buf[this.pos++]=127&(u>>>=7)|(u>127?128:0),u<=127||(this.buf[this.pos++]=u>>>7&127))))},writeSVarint:function(u){this.writeVarint(u<0?2*-u-1:2*u)},writeBoolean:function(u){this.writeVarint(Boolean(u))},writeString:function(u){u=String(u),this.realloc(4*u.length),this.pos++;var p=this.pos;this.pos=function(R,j,$){for(var J,le,ve=0;ve55295&&J<57344){if(!le){J>56319||ve+1===j.length?(R[$++]=239,R[$++]=191,R[$++]=189):le=J;continue}if(J<56320){R[$++]=239,R[$++]=191,R[$++]=189,le=J;continue}J=le-55296<<10|J-56320|65536,le=null}else le&&(R[$++]=239,R[$++]=191,R[$++]=189,le=null);J<128?R[$++]=J:(J<2048?R[$++]=J>>6|192:(J<65536?R[$++]=J>>12|224:(R[$++]=J>>18|240,R[$++]=J>>12&63|128),R[$++]=J>>6&63|128),R[$++]=63&J|128)}return $}(this.buf,u,this.pos);var _=this.pos-p;_>=128&&nb(p,_,this),this.pos=p-1,this.writeVarint(_),this.pos+=_},writeFloat:function(u){this.realloc(4),Qo(this.buf,u,this.pos,!0,23,4),this.pos+=4},writeDouble:function(u){this.realloc(8),Qo(this.buf,u,this.pos,!0,52,8),this.pos+=8},writeBytes:function(u){var p=u.length;this.writeVarint(p),this.realloc(p);for(var _=0;_=128&&nb(_,R,this),this.pos=_-1,this.writeVarint(R),this.pos+=R},writeMessage:function(u,p,_){this.writeTag(u,Bo.Bytes),this.writeRawMessage(p,_)},writePackedVarint:function(u,p){p.length&&this.writeMessage(u,s8,p)},writePackedSVarint:function(u,p){p.length&&this.writeMessage(u,a8,p)},writePackedBoolean:function(u,p){p.length&&this.writeMessage(u,u8,p)},writePackedFloat:function(u,p){p.length&&this.writeMessage(u,l8,p)},writePackedDouble:function(u,p){p.length&&this.writeMessage(u,c8,p)},writePackedFixed32:function(u,p){p.length&&this.writeMessage(u,NL,p)},writePackedSFixed32:function(u,p){p.length&&this.writeMessage(u,HC,p)},writePackedFixed64:function(u,p){p.length&&this.writeMessage(u,zL,p)},writePackedSFixed64:function(u,p){p.length&&this.writeMessage(u,UL,p)},writeBytesField:function(u,p){this.writeTag(u,Bo.Bytes),this.writeBytes(p)},writeFixed32Field:function(u,p){this.writeTag(u,Bo.Fixed32),this.writeFixed32(p)},writeSFixed32Field:function(u,p){this.writeTag(u,Bo.Fixed32),this.writeSFixed32(p)},writeFixed64Field:function(u,p){this.writeTag(u,Bo.Fixed64),this.writeFixed64(p)},writeSFixed64Field:function(u,p){this.writeTag(u,Bo.Fixed64),this.writeSFixed64(p)},writeVarintField:function(u,p){this.writeTag(u,Bo.Varint),this.writeVarint(p)},writeSVarintField:function(u,p){this.writeTag(u,Bo.Varint),this.writeSVarint(p)},writeStringField:function(u,p){this.writeTag(u,Bo.Bytes),this.writeString(p)},writeFloatField:function(u,p){this.writeTag(u,Bo.Fixed32),this.writeFloat(p)},writeDoubleField:function(u,p){this.writeTag(u,Bo.Fixed64),this.writeDouble(p)},writeBooleanField:function(u,p){this.writeVarintField(u,Boolean(p))}};var uv=function(u,p){var _=p.pixelRatio,R=p.version,j=p.stretchX,$=p.stretchY,J=p.content;this.paddedRect=u,this.pixelRatio=_,this.stretchX=j,this.stretchY=$,this.content=J,this.version=R},n0={tl:{configurable:!0},br:{configurable:!0},tlbr:{configurable:!0},displaySize:{configurable:!0}};n0.tl.get=function(){return[this.paddedRect.x+1,this.paddedRect.y+1]},n0.br.get=function(){return[this.paddedRect.x+this.paddedRect.w-1,this.paddedRect.y+this.paddedRect.h-1]},n0.tlbr.get=function(){return this.tl.concat(this.br)},n0.displaySize.get=function(){return[(this.paddedRect.w-2)/this.pixelRatio,(this.paddedRect.h-2)/this.pixelRatio]},Object.defineProperties(uv.prototype,n0);var rh=function(u,p){var _={},R={};this.haveRenderCallbacks=[];var j=[];this.addImages(u,_,j),this.addImages(p,R,j);var $=qC(j),J=new Vl({width:$.w||1,height:$.h||1});for(var le in u){var ve=u[le],Ie=_[le].paddedRect;Vl.copy(ve.data,J,{x:0,y:0},{x:Ie.x+1,y:Ie.y+1},ve.data)}for(var Le in p){var ze=p[Le],Ke=R[Le].paddedRect,lt=Ke.x+1,Mt=Ke.y+1,Dt=ze.data.width,tr=ze.data.height;Vl.copy(ze.data,J,{x:0,y:0},{x:lt,y:Mt},ze.data),Vl.copy(ze.data,J,{x:0,y:tr-1},{x:lt,y:Mt-1},{width:Dt,height:1}),Vl.copy(ze.data,J,{x:0,y:0},{x:lt,y:Mt+tr},{width:Dt,height:1}),Vl.copy(ze.data,J,{x:Dt-1,y:0},{x:lt-1,y:Mt},{width:1,height:tr}),Vl.copy(ze.data,J,{x:0,y:0},{x:lt+Dt,y:Mt},{width:1,height:tr})}this.image=J,this.iconPositions=_,this.patternPositions=R};rh.prototype.addImages=function(u,p,_){for(var R in u){var j=u[R],$={x:0,y:0,w:j.data.width+2,h:j.data.height+2};_.push($),p[R]=new uv($,j),j.hasRenderCallback&&this.haveRenderCallbacks.push(R)}},rh.prototype.patchUpdatedImages=function(u,p){for(var _ in u.dispatchRenderCallbacks(this.haveRenderCallbacks),u.updatedImages)this.patchUpdatedImage(this.iconPositions[_],u.getImage(_),p),this.patchUpdatedImage(this.patternPositions[_],u.getImage(_),p)},rh.prototype.patchUpdatedImage=function(u,p,_){if(u&&p&&u.version!==p.version){u.version=p.version;var R=u.tl;_.update(p.data,void 0,{x:R[0],y:R[1]})}},Yi("ImagePosition",uv),Yi("ImageAtlas",rh);var Qf={horizontal:1,vertical:2,horizontalOnly:3},rA=function(){this.scale=1,this.fontStack="",this.imageName=null};rA.forText=function(u,p){var _=new rA;return _.scale=u||1,_.fontStack=p,_},rA.forImage=function(u){var p=new rA;return p.imageName=u,p};var wh=function(){this.text="",this.sectionIndex=[],this.sections=[],this.imageSectionID=null};function ob(u,p,_,R,j,$,J,le,ve,Ie,Le,ze,Ke,lt,Mt,Dt){var tr,qt=wh.fromFeature(u,j);ze===Qf.vertical&&qt.verticalizePunctuation();var ur=gu.processBidirectionalText,Tr=gu.processStyledBidirectionalText;if(ur&&qt.sections.length===1){tr=[];for(var Nr=0,Vr=ur(qt.toString(),A2(qt,Ie,$,p,R,lt,Mt));Nr0&&Jd>dl&&(dl=Jd)}else{var mb=xo[$s.fontStack],V_=mb&&mb[ed];if(V_&&V_.rect)ug=V_.rect,oc=V_.metrics;else{var _v=Jo[$s.fontStack],gb=_v&&_v[ed];if(!gb)continue;oc=gb.metrics}Qd=24*(Bs-$s.scale)}U_?(pn.verticalizable=!0,Na.push({glyph:ed,imageName:Op,x:ou,y:ih+Qd,vertical:U_,scale:$s.scale,fontStack:$s.fontStack,sectionIndex:Dp,metrics:oc,rect:ug}),ou+=gv*$s.scale+fl):(Na.push({glyph:ed,imageName:Op,x:ou,y:ih+Qd,vertical:U_,scale:$s.scale,fontStack:$s.fontStack,sectionIndex:Dp,metrics:oc,rect:ug}),ou+=oc.advance*$s.scale+fl)}Na.length!==0&&(su=Math.max(ou-fl,su),f8(Na,0,Na.length-1,ka,dl)),ou=0;var Ab=js*Bs+dl;xu.lineOffset=Math.max(dl,rf),ih+=Ab,nc=Math.max(Ab,nc),++au}else ih+=js,++au}var hg,sA=ih- -17,j_=YC(hl),Fp=j_.horizontalAlign,H_=j_.verticalAlign;(function(yv,_b,nf,fg,aA,yb,vv,xv,vb){var ym,G_=(_b-nf)*aA;ym=yb!==vv?-xv*fg- -17:(-fg*vb+.5)*vv;for(var lA=0,W_=yv;lA=0&&R>=u&&g2[this.text.charCodeAt(R)];R--)_--;this.text=this.text.substring(u,_),this.sectionIndex=this.sectionIndex.slice(u,_)},wh.prototype.substring=function(u,p){var _=new wh;return _.text=this.text.substring(u,p),_.sectionIndex=this.sectionIndex.slice(u,p),_.sections=this.sections,_},wh.prototype.toString=function(){return this.text},wh.prototype.getMaxScale=function(){var u=this;return this.sectionIndex.reduce(function(p,_){return Math.max(p,u.sections[_].scale)},0)},wh.prototype.addTextSection=function(u,p){this.text+=u.text,this.sections.push(rA.forText(u.scale,u.fontStack||p));for(var _=this.sections.length-1,R=0;R=63743?null:++this.imageSectionID:(this.imageSectionID=57344,this.imageSectionID)};var g2={9:!0,10:!0,11:!0,12:!0,13:!0,32:!0},Jf={};function $C(u,p,_,R,j,$){if(p.imageName){var J=R[p.imageName];return J?J.displaySize[0]*p.scale*24/$+j:0}var le=_[p.fontStack],ve=le&&le[u];return ve?ve.metrics.advance*p.scale+j:0}function jL(u,p,_,R){var j=Math.pow(u-p,2);return R?u=0,ze=0,Ke=0;Ke-_/2;){if(--J<0)return!1;le-=u[J].dist($),$=u[J]}le+=u[J].dist(u[J+1]),J++;for(var ve=[],Ie=0;le<_/2;){var Le=u[J],ze=u[J+1];if(!ze)return!1;var Ke=u[J-1].angleTo(Le)-Le.angleTo(ze);for(Ke=Math.abs((Ke+3*Math.PI)%(2*Math.PI)-Math.PI),ve.push({distance:le,angleDelta:Ke}),Ie+=Ke;le-ve[0].distance>R;)Ie-=ve.shift().angleDelta;if(Ie>j)return!1;J++,le+=Le.dist(ze)}return!0}function qL(u){for(var p=0,_=0;_Ie){var Mt=(Ie-ve)/lt,Dt=Ws(ze.x,Ke.x,Mt),tr=Ws(ze.y,Ke.y,Mt),qt=new o0(Dt,tr,Ke.angleTo(ze),Le);return qt._round(),!J||WL(u,qt,le,J,p)?qt:void 0}ve+=lt}}function p8(u,p,_,R,j,$,J,le,ve){var Ie=$L(R,$,J),Le=XL(R,j),ze=Le*J,Ke=u[0].x===0||u[0].x===ve||u[0].y===0||u[0].y===ve;return p-ze

=0&&es=0&&In=0&&Ki+Ei<=Ui){var js=new o0(es,In,Jo,en);js._round(),qt&&!WL(Mt,js,Tr,qt,ur)||Bn.push(js)}}Cn+=pn}return Vr||Bn.length||Nr||(Bn=lt(Mt,Cn/2,tr,qt,ur,Tr,Nr,!0,ri)),Bn}(u,Ke?p/2*le%p:(Le/2+2*$)*J*le%p,p,Ie,_,ze,Ke,!1,ve)}function ZL(u,p,_,R,j){for(var $=[],J=0;J=R&&ze.x>=R||(Le.x>=R?Le=new f(R,Le.y+(R-Le.x)/(ze.x-Le.x)*(ze.y-Le.y))._round():ze.x>=R&&(ze=new f(R,Le.y+(R-Le.x)/(ze.x-Le.x)*(ze.y-Le.y))._round()),Le.y>=j&&ze.y>=j||(Le.y>=j?Le=new f(Le.x+(j-Le.y)/(ze.y-Le.y)*(ze.x-Le.x),j)._round():ze.y>=j&&(ze=new f(Le.x+(j-Le.y)/(ze.y-Le.y)*(ze.x-Le.x),j)._round()),ve&&Le.equals(ve[ve.length-1])||$.push(ve=[Le]),ve.push(ze)))))}return $}function _2(u,p,_,R){var j=[],$=u.image,J=$.pixelRatio,le=$.paddedRect.w-2,ve=$.paddedRect.h-2,Ie=u.right-u.left,Le=u.bottom-u.top,ze=$.stretchX||[[0,le]],Ke=$.stretchY||[[0,ve]],lt=function(es,In){return es+In[1]-In[0]},Mt=ze.reduce(lt,0),Dt=Ke.reduce(lt,0),tr=le-Mt,qt=ve-Dt,ur=0,Tr=Mt,Nr=0,Vr=Dt,ri=0,Ei=tr,Ui=0,Cn=qt;if($.content&&R){var Ki=$.content;ur=y2(ze,0,Ki[0]),Nr=y2(Ke,0,Ki[1]),Tr=y2(ze,Ki[0],Ki[2]),Vr=y2(Ke,Ki[1],Ki[3]),ri=Ki[0]-ur,Ui=Ki[1]-Nr,Ei=Ki[2]-Ki[0]-Tr,Cn=Ki[3]-Ki[1]-Vr}var Bn=function(es,In,js,hl){var Gl=nA(es.stretch-ur,Tr,Ie,u.left),Wl=v2(es.fixed-ri,Ei,es.stretch,Mt),fl=nA(In.stretch-Nr,Vr,Le,u.top),ic=v2(In.fixed-Ui,Cn,In.stretch,Dt),nu=nA(js.stretch-ur,Tr,Ie,u.left),ou=v2(js.fixed-ri,Ei,js.stretch,Mt),ih=nA(hl.stretch-Nr,Vr,Le,u.top),su=v2(hl.fixed-Ui,Cn,hl.stretch,Dt),nc=new f(Gl,fl),ka=new f(nu,fl),au=new f(nu,ih),hs=new f(Gl,ih),Ra=new f(Wl/J,ic/J),ea=new f(ou/J,su/J),Bs=p*Math.PI/180;if(Bs){var rf=Math.sin(Bs),xu=Math.cos(Bs),Na=[xu,-rf,rf,xu];nc._matMult(Na),ka._matMult(Na),hs._matMult(Na),au._matMult(Na)}var dl=es.stretch+es.fixed,ku=In.stretch+In.fixed;return{tl:nc,tr:ka,bl:hs,br:au,tex:{x:$.paddedRect.x+1+dl,y:$.paddedRect.y+1+ku,w:js.stretch+js.fixed-dl,h:hl.stretch+hl.fixed-ku},writingMode:void 0,glyphOffset:[0,0],sectionIndex:0,pixelOffsetTL:Ra,pixelOffsetBR:ea,minFontScaleX:Ei/J/Ie,minFontScaleY:Cn/J/Le,isSDF:_}};if(R&&($.stretchX||$.stretchY))for(var en=QC(ze,tr,Mt),Wo=QC(Ke,qt,Dt),Xn=0;Xn0&&(lt=Math.max(10,lt),this.circleDiameter=lt)}else{var Mt=$.top*J-le,Dt=$.bottom*J+le,tr=$.left*J-le,qt=$.right*J+le,ur=$.collisionPadding;if(ur&&(tr-=ur[0]*J,Mt-=ur[1]*J,qt+=ur[2]*J,Dt+=ur[3]*J),Ie){var Tr=new f(tr,Mt),Nr=new f(qt,Mt),Vr=new f(tr,Dt),ri=new f(qt,Dt),Ei=Ie*Math.PI/180;Tr._rotate(Ei),Nr._rotate(Ei),Vr._rotate(Ei),ri._rotate(Ei),tr=Math.min(Tr.x,Nr.x,Vr.x,ri.x),qt=Math.max(Tr.x,Nr.x,Vr.x,ri.x),Mt=Math.min(Tr.y,Nr.y,Vr.y,ri.y),Dt=Math.max(Tr.y,Nr.y,Vr.y,ri.y)}u.emplaceBack(p.x,p.y,tr,Mt,qt,Dt,_,R,j)}this.boxEndIndex=u.length},Am=function(u,p){if(u===void 0&&(u=[]),p===void 0&&(p=YL),this.data=u,this.length=this.data.length,this.compare=p,this.length>0)for(var _=(this.length>>1)-1;_>=0;_--)this._down(_)};function YL(u,p){return up?1:0}function x2(u,p,_){p===void 0&&(p=1),_===void 0&&(_=!1);for(var R=1/0,j=1/0,$=-1/0,J=-1/0,le=u[0],ve=0;ve$)&&($=Ie.x),(!ve||Ie.y>J)&&(J=Ie.y)}var Le=Math.min($-R,J-j),ze=Le/2,Ke=new Am([],b2);if(Le===0)return new f(R,j);for(var lt=R;lt<$;lt+=Le)for(var Mt=j;MtDt.d||!Dt.d)&&(Dt=qt,_&&console.log("found best %d after %d probes",Math.round(1e4*qt.d)/1e4,tr)),qt.max-Dt.d<=p||(Ke.push(new ag(qt.p.x-(ze=qt.h/2),qt.p.y-ze,ze,u)),Ke.push(new ag(qt.p.x+ze,qt.p.y-ze,ze,u)),Ke.push(new ag(qt.p.x-ze,qt.p.y+ze,ze,u)),Ke.push(new ag(qt.p.x+ze,qt.p.y+ze,ze,u)),tr+=4)}return _&&(console.log("num probes: "+tr),console.log("best distance: "+Dt.d)),Dt.p}function b2(u,p){return p.max-u.max}function ag(u,p,_,R){this.p=new f(u,p),this.h=_,this.d=function(j,$){for(var J=!1,le=1/0,ve=0;ve<$.length;ve++)for(var Ie=$[ve],Le=0,ze=Ie.length,Ke=ze-1;Lej.y!=Mt.y>j.y&&j.x<(Mt.x-lt.x)*(j.y-lt.y)/(Mt.y-lt.y)+lt.x&&(J=!J),le=Math.min(le,Td(j,lt,Mt))}return(J?1:-1)*Math.sqrt(le)}(this.p,R),this.max=this.d+this.h*Math.SQRT2}Am.prototype.push=function(u){this.data.push(u),this.length++,this._up(this.length-1)},Am.prototype.pop=function(){if(this.length!==0){var u=this.data[0],p=this.data.pop();return this.length--,this.length>0&&(this.data[0]=p,this._down(0)),u}},Am.prototype.peek=function(){return this.data[0]},Am.prototype._up=function(u){for(var p=this.data,_=this.compare,R=p[u];u>0;){var j=u-1>>1,$=p[j];if(_(R,$)>=0)break;p[u]=$,u=j}p[u]=R},Am.prototype._down=function(u){for(var p=this.data,_=this.compare,R=this.length>>1,j=p[u];u=0)break;p[u]=J,u=$}p[u]=j};var w2=Number.POSITIVE_INFINITY;function JC(u,p){return p[1]!==w2?function(_,R,j){var $=0,J=0;switch(R=Math.abs(R),j=Math.abs(j),_){case"top-right":case"top-left":case"top":J=j-7;break;case"bottom-right":case"bottom-left":case"bottom":J=7-j}switch(_){case"top-right":case"bottom-right":case"right":$=-R;break;case"top-left":case"bottom-left":case"left":$=R}return[$,J]}(u,p[0],p[1]):function(_,R){var j=0,$=0;R<0&&(R=0);var J=R/Math.sqrt(2);switch(_){case"top-right":case"top-left":$=J-7;break;case"bottom-right":case"bottom-left":$=7-J;break;case"bottom":$=7-R;break;case"top":$=R-7}switch(_){case"top-right":case"bottom-right":j=-J;break;case"top-left":case"bottom-left":j=J;break;case"left":j=R;break;case"right":j=-R}return[j,$]}(u,p[0])}function B_(u){switch(u){case"right":case"top-right":case"bottom-right":return"right";case"left":case"top-left":case"bottom-left":return"left"}return"center"}function T2(u,p,_,R,j,$,J,le,ve,Ie,Le,ze,Ke,lt,Mt){var Dt=function(Nr,Vr,ri,Ei,Ui,Cn,Ki,Bn){for(var en=Ei.layout.get("text-rotate").evaluate(Cn,{})*Math.PI/180,Wo=[],Xn=0,pn=Vr.positionedLines;Xn32640&&Je(u.layerIds[0]+': Value for "text-size" is >= 255. Reduce your "text-size".'):tr.kind==="composite"&&((qt=[128*lt.compositeTextSizes[0].evaluate(J,{},Mt),128*lt.compositeTextSizes[1].evaluate(J,{},Mt)])[0]>32640||qt[1]>32640)&&Je(u.layerIds[0]+': Value for "text-size" is >= 255. Reduce your "text-size".'),u.addSymbols(u.text,Dt,qt,le,$,J,Ie,p,ve.lineStartIndex,ve.lineLength,Ke,Mt);for(var ur=0,Tr=Le;ur=0;J--)if(R.dist($[J])<_)return!0}else j[p]=[];return j[p].push(R),!1}var hv=B.VectorTileFeature.types,lb=[{name:"a_fade_opacity",components:1,type:"Uint8",offset:0}];function E2(u,p,_,R,j,$,J,le,ve,Ie,Le,ze,Ke){var lt=le?Math.min(32640,Math.round(le[0])):0,Mt=le?Math.min(32640,Math.round(le[1])):0;u.emplaceBack(p,_,Math.round(32*R),Math.round(32*j),$,J,(lt<<1)+(ve?1:0),Mt,16*Ie,16*Le,256*ze,256*Ke)}function C2(u,p,_){u.emplaceBack(p.x,p.y,_),u.emplaceBack(p.x,p.y,_),u.emplaceBack(p.x,p.y,_),u.emplaceBack(p.x,p.y,_)}function D_(u){for(var p=0,_=u.sections;p<_.length;p+=1)if(rg(_[p].text))return!0;return!1}var fv=function(u){this.layoutVertexArray=new Zf,this.indexArray=new Kh,this.programConfigurations=u,this.segments=new ft,this.dynamicLayoutVertexArray=new Zd,this.opacityVertexArray=new xd,this.placedSymbolArray=new L};fv.prototype.isEmpty=function(){return this.layoutVertexArray.length===0&&this.indexArray.length===0&&this.dynamicLayoutVertexArray.length===0&&this.opacityVertexArray.length===0},fv.prototype.upload=function(u,p,_,R){this.isEmpty()||(_&&(this.layoutVertexBuffer=u.createVertexBuffer(this.layoutVertexArray,vo.members),this.indexBuffer=u.createIndexBuffer(this.indexArray,p),this.dynamicLayoutVertexBuffer=u.createVertexBuffer(this.dynamicLayoutVertexArray,Ro.members,!0),this.opacityVertexBuffer=u.createVertexBuffer(this.opacityVertexArray,lb,!0),this.opacityVertexBuffer.itemSize=1),(_||R)&&this.programConfigurations.upload(u))},fv.prototype.destroy=function(){this.layoutVertexBuffer&&(this.layoutVertexBuffer.destroy(),this.indexBuffer.destroy(),this.programConfigurations.destroy(),this.segments.destroy(),this.dynamicLayoutVertexBuffer.destroy(),this.opacityVertexBuffer.destroy())},Yi("SymbolBuffers",fv);var dv=function(u,p,_){this.layoutVertexArray=new u,this.layoutAttributes=p,this.indexArray=new _,this.segments=new ft,this.collisionVertexArray=new Yd};dv.prototype.upload=function(u){this.layoutVertexBuffer=u.createVertexBuffer(this.layoutVertexArray,this.layoutAttributes),this.indexBuffer=u.createIndexBuffer(this.indexArray),this.collisionVertexBuffer=u.createVertexBuffer(this.collisionVertexArray,Yo.members,!0)},dv.prototype.destroy=function(){this.layoutVertexBuffer&&(this.layoutVertexBuffer.destroy(),this.indexBuffer.destroy(),this.segments.destroy(),this.collisionVertexBuffer.destroy())},Yi("CollisionBuffers",dv);var Js=function(u){this.collisionBoxArray=u.collisionBoxArray,this.zoom=u.zoom,this.overscaling=u.overscaling,this.layers=u.layers,this.layerIds=this.layers.map(function($){return $.id}),this.index=u.index,this.pixelRatio=u.pixelRatio,this.sourceLayerIndex=u.sourceLayerIndex,this.hasPattern=!1,this.hasRTLText=!1,this.sortKeyRanges=[],this.collisionCircleArray=[],this.placementInvProjMatrix=yu([]),this.placementViewportMatrix=yu([]);var p=this.layers[0]._unevaluatedLayout._values;this.textSizeData=sb(this.zoom,p["text-size"]),this.iconSizeData=sb(this.zoom,p["icon-size"]);var _=this.layers[0].layout,R=_.get("symbol-sort-key"),j=_.get("symbol-z-order");this.canOverlap=_.get("text-allow-overlap")||_.get("icon-allow-overlap")||_.get("text-ignore-placement")||_.get("icon-ignore-placement"),this.sortFeaturesByKey=j!=="viewport-y"&&R.constantOr(1)!==void 0,this.sortFeaturesByY=(j==="viewport-y"||j==="auto"&&!this.sortFeaturesByKey)&&this.canOverlap,_.get("symbol-placement")==="point"&&(this.writingModes=_.get("text-writing-mode").map(function($){return Qf[$]})),this.stateDependentLayerIds=this.layers.filter(function($){return $.isStateDependent()}).map(function($){return $.id}),this.sourceID=u.sourceID};Js.prototype.createArrays=function(){this.text=new fv(new Rn(this.layers,this.zoom,function(u){return/^text/.test(u)})),this.icon=new fv(new Rn(this.layers,this.zoom,function(u){return/^icon/.test(u)})),this.glyphOffsetArray=new ae,this.lineVertexArray=new ge,this.symbolInstances=new ie},Js.prototype.calculateGlyphDependencies=function(u,p,_,R,j){for(var $=0;$0)&&($.value.kind!=="constant"||$.value.value.length>0),Ie=le.value.kind!=="constant"||!!le.value.value||Object.keys(le.parameters).length>0,Le=j.get("symbol-sort-key");if(this.features=[],ve||Ie){for(var ze=p.iconDependencies,Ke=p.glyphDependencies,lt=p.availableImages,Mt=new So(this.zoom),Dt=0,tr=u;Dt=0;for(var Jo=0,xo=Ui.sections;Jo=0;le--)$[le]={x:p[le].x,y:p[le].y,tileUnitDistanceFromAnchor:j},le>0&&(j+=p[le-1].dist(p[le]));for(var ve=0;ve0},Js.prototype.hasIconData=function(){return this.icon.segments.get().length>0},Js.prototype.hasDebugData=function(){return this.textCollisionBox&&this.iconCollisionBox},Js.prototype.hasTextCollisionBoxData=function(){return this.hasDebugData()&&this.textCollisionBox.segments.get().length>0},Js.prototype.hasIconCollisionBoxData=function(){return this.hasDebugData()&&this.iconCollisionBox.segments.get().length>0},Js.prototype.addIndicesForPlacedSymbol=function(u,p){for(var _=u.placedSymbolArray.get(p),R=_.vertexStartIndex+4*_.numGlyphs,j=_.vertexStartIndex;j1||this.icon.segments.get().length>1)){this.symbolInstanceIndexes=this.getSortedSymbolIndexes(u),this.sortedAngle=u,this.text.indexArray.clear(),this.icon.indexArray.clear(),this.featureSortOrder=[];for(var _=0,R=this.symbolInstanceIndexes;_=0&&le.indexOf($)===J&&p.addIndicesForPlacedSymbol(p.text,$)}),j.verticalPlacedTextSymbolIndex>=0&&this.addIndicesForPlacedSymbol(this.text,j.verticalPlacedTextSymbolIndex),j.placedIconSymbolIndex>=0&&this.addIndicesForPlacedSymbol(this.icon,j.placedIconSymbolIndex),j.verticalPlacedIconSymbolIndex>=0&&this.addIndicesForPlacedSymbol(this.icon,j.verticalPlacedIconSymbolIndex)}this.text.indexBuffer&&this.text.indexBuffer.updateData(this.text.indexArray),this.icon.indexBuffer&&this.icon.indexBuffer.updateData(this.icon.indexArray)}},Yi("SymbolBucket",Js,{omit:["layers","collisionBoxArray","features","compareText"]}),Js.MAX_GLYPHS=65535,Js.addDynamicAttributes=C2;var eI=new Cl({"symbol-placement":new An(ht.layout_symbol["symbol-placement"]),"symbol-spacing":new An(ht.layout_symbol["symbol-spacing"]),"symbol-avoid-edges":new An(ht.layout_symbol["symbol-avoid-edges"]),"symbol-sort-key":new nn(ht.layout_symbol["symbol-sort-key"]),"symbol-z-order":new An(ht.layout_symbol["symbol-z-order"]),"icon-allow-overlap":new An(ht.layout_symbol["icon-allow-overlap"]),"icon-ignore-placement":new An(ht.layout_symbol["icon-ignore-placement"]),"icon-optional":new An(ht.layout_symbol["icon-optional"]),"icon-rotation-alignment":new An(ht.layout_symbol["icon-rotation-alignment"]),"icon-size":new nn(ht.layout_symbol["icon-size"]),"icon-text-fit":new An(ht.layout_symbol["icon-text-fit"]),"icon-text-fit-padding":new An(ht.layout_symbol["icon-text-fit-padding"]),"icon-image":new nn(ht.layout_symbol["icon-image"]),"icon-rotate":new nn(ht.layout_symbol["icon-rotate"]),"icon-padding":new An(ht.layout_symbol["icon-padding"]),"icon-keep-upright":new An(ht.layout_symbol["icon-keep-upright"]),"icon-offset":new nn(ht.layout_symbol["icon-offset"]),"icon-anchor":new nn(ht.layout_symbol["icon-anchor"]),"icon-pitch-alignment":new An(ht.layout_symbol["icon-pitch-alignment"]),"text-pitch-alignment":new An(ht.layout_symbol["text-pitch-alignment"]),"text-rotation-alignment":new An(ht.layout_symbol["text-rotation-alignment"]),"text-field":new nn(ht.layout_symbol["text-field"]),"text-font":new nn(ht.layout_symbol["text-font"]),"text-size":new nn(ht.layout_symbol["text-size"]),"text-max-width":new nn(ht.layout_symbol["text-max-width"]),"text-line-height":new An(ht.layout_symbol["text-line-height"]),"text-letter-spacing":new nn(ht.layout_symbol["text-letter-spacing"]),"text-justify":new nn(ht.layout_symbol["text-justify"]),"text-radial-offset":new nn(ht.layout_symbol["text-radial-offset"]),"text-variable-anchor":new An(ht.layout_symbol["text-variable-anchor"]),"text-anchor":new nn(ht.layout_symbol["text-anchor"]),"text-max-angle":new An(ht.layout_symbol["text-max-angle"]),"text-writing-mode":new An(ht.layout_symbol["text-writing-mode"]),"text-rotate":new nn(ht.layout_symbol["text-rotate"]),"text-padding":new An(ht.layout_symbol["text-padding"]),"text-keep-upright":new An(ht.layout_symbol["text-keep-upright"]),"text-transform":new nn(ht.layout_symbol["text-transform"]),"text-offset":new nn(ht.layout_symbol["text-offset"]),"text-allow-overlap":new An(ht.layout_symbol["text-allow-overlap"]),"text-ignore-placement":new An(ht.layout_symbol["text-ignore-placement"]),"text-optional":new An(ht.layout_symbol["text-optional"])}),I2={paint:new Cl({"icon-opacity":new nn(ht.paint_symbol["icon-opacity"]),"icon-color":new nn(ht.paint_symbol["icon-color"]),"icon-halo-color":new nn(ht.paint_symbol["icon-halo-color"]),"icon-halo-width":new nn(ht.paint_symbol["icon-halo-width"]),"icon-halo-blur":new nn(ht.paint_symbol["icon-halo-blur"]),"icon-translate":new An(ht.paint_symbol["icon-translate"]),"icon-translate-anchor":new An(ht.paint_symbol["icon-translate-anchor"]),"text-opacity":new nn(ht.paint_symbol["text-opacity"]),"text-color":new nn(ht.paint_symbol["text-color"],{runtimeType:Mi,getOverride:function(u){return u.textColor},hasOverride:function(u){return!!u.textColor}}),"text-halo-color":new nn(ht.paint_symbol["text-halo-color"]),"text-halo-width":new nn(ht.paint_symbol["text-halo-width"]),"text-halo-blur":new nn(ht.paint_symbol["text-halo-blur"]),"text-translate":new An(ht.paint_symbol["text-translate"]),"text-translate-anchor":new An(ht.paint_symbol["text-translate-anchor"])}),layout:eI},O_=function(u){this.type=u.property.overrides?u.property.overrides.runtimeType:fi,this.defaultValue=u};O_.prototype.evaluate=function(u){if(u.formattedSection){var p=this.defaultValue.property.overrides;if(p&&p.hasOverride(u.formattedSection))return p.getOverride(u.formattedSection)}return u.feature&&u.featureState?this.defaultValue.evaluate(u.feature,u.featureState):this.defaultValue.property.specification.default},O_.prototype.eachChild=function(u){this.defaultValue.isConstant()||u(this.defaultValue.value._styleExpression.expression)},O_.prototype.outputDefined=function(){return!1},O_.prototype.serialize=function(){return null},Yi("FormatSectionOverride",O_,{omit:["defaultValue"]});var m8=function(u){function p(_){u.call(this,_,I2)}return u&&(p.__proto__=u),(p.prototype=Object.create(u&&u.prototype)).constructor=p,p.prototype.recalculate=function(_,R){if(u.prototype.recalculate.call(this,_,R),this.layout.get("icon-rotation-alignment")==="auto"&&(this.layout._values["icon-rotation-alignment"]=this.layout.get("symbol-placement")!=="point"?"map":"viewport"),this.layout.get("text-rotation-alignment")==="auto"&&(this.layout._values["text-rotation-alignment"]=this.layout.get("symbol-placement")!=="point"?"map":"viewport"),this.layout.get("text-pitch-alignment")==="auto"&&(this.layout._values["text-pitch-alignment"]=this.layout.get("text-rotation-alignment")),this.layout.get("icon-pitch-alignment")==="auto"&&(this.layout._values["icon-pitch-alignment"]=this.layout.get("icon-rotation-alignment")),this.layout.get("symbol-placement")==="point"){var j=this.layout.get("text-writing-mode");if(j){for(var $=[],J=0,le=j;J",targetMapId:R,sourceMapId:$.mapId})}}},lg.prototype.receive=function(u){var p=u.data,_=p.id;if(_&&(!p.targetMapId||this.mapId===p.targetMapId))if(p.type===""){delete this.tasks[_];var R=this.cancelCallbacks[_];delete this.cancelCallbacks[_],R&&R()}else xt()||p.mustQueue?(this.tasks[_]=p,this.taskQueue.push(_),this.invoker.trigger()):this.processTask(_,p)},lg.prototype.process=function(){if(this.taskQueue.length){var u=this.taskQueue.shift(),p=this.tasks[u];delete this.tasks[u],this.taskQueue.length&&this.invoker.trigger(),p&&this.processTask(u,p)}},lg.prototype.processTask=function(u,p){var _=this;if(p.type===""){var R=this.callbacks[u];delete this.callbacks[u],R&&(p.error?R(kl(p.error)):R(null,kl(p.data)))}else{var j=!1,$=hr(this.globalScope)?void 0:[],J=p.hasCallback?function(Le,ze){j=!0,delete _.cancelCallbacks[u],_.target.postMessage({id:u,type:"",sourceMapId:_.mapId,error:Le?ru(Le):null,data:ru(ze,$)},$)}:function(Le){j=!0},le=null,ve=kl(p.data);if(this.parent[p.type])le=this.parent[p.type](p.sourceMapId,ve,J);else if(this.parent.getWorkerSource){var Ie=p.type.split(".");le=this.parent.getWorkerSource(p.sourceMapId,Ie[0],ve.source)[Ie[1]](ve,J)}else J(new Error("Could not find function "+p.type));!j&&le&&le.cancel&&(this.cancelCallbacks[u]=le.cancel)}},lg.prototype.remove=function(){this.invoker.remove(),this.target.removeEventListener("message",this.receive,!1)};var Wc=function(u,p){u&&(p?this.setSouthWest(u).setNorthEast(p):u.length===4?this.setSouthWest([u[0],u[1]]).setNorthEast([u[2],u[3]]):this.setSouthWest(u[0]).setNorthEast(u[1]))};Wc.prototype.setNorthEast=function(u){return this._ne=u instanceof ul?new ul(u.lng,u.lat):ul.convert(u),this},Wc.prototype.setSouthWest=function(u){return this._sw=u instanceof ul?new ul(u.lng,u.lat):ul.convert(u),this},Wc.prototype.extend=function(u){var p,_,R=this._sw,j=this._ne;if(u instanceof ul)p=u,_=u;else{if(!(u instanceof Wc))return Array.isArray(u)?u.length===4||u.every(Array.isArray)?this.extend(Wc.convert(u)):this.extend(ul.convert(u)):this;if(_=u._ne,!(p=u._sw)||!_)return this}return R||j?(R.lng=Math.min(p.lng,R.lng),R.lat=Math.min(p.lat,R.lat),j.lng=Math.max(_.lng,j.lng),j.lat=Math.max(_.lat,j.lat)):(this._sw=new ul(p.lng,p.lat),this._ne=new ul(_.lng,_.lat)),this},Wc.prototype.getCenter=function(){return new ul((this._sw.lng+this._ne.lng)/2,(this._sw.lat+this._ne.lat)/2)},Wc.prototype.getSouthWest=function(){return this._sw},Wc.prototype.getNorthEast=function(){return this._ne},Wc.prototype.getNorthWest=function(){return new ul(this.getWest(),this.getNorth())},Wc.prototype.getSouthEast=function(){return new ul(this.getEast(),this.getSouth())},Wc.prototype.getWest=function(){return this._sw.lng},Wc.prototype.getSouth=function(){return this._sw.lat},Wc.prototype.getEast=function(){return this._ne.lng},Wc.prototype.getNorth=function(){return this._ne.lat},Wc.prototype.toArray=function(){return[this._sw.toArray(),this._ne.toArray()]},Wc.prototype.toString=function(){return"LngLatBounds("+this._sw.toString()+", "+this._ne.toString()+")"},Wc.prototype.isEmpty=function(){return!(this._sw&&this._ne)},Wc.prototype.contains=function(u){var p=ul.convert(u),_=p.lng,R=p.lat,j=this._sw.lng<=_&&_<=this._ne.lng;return this._sw.lng>this._ne.lng&&(j=this._sw.lng>=_&&_>=this._ne.lng),this._sw.lat<=R&&R<=this._ne.lat&&j},Wc.convert=function(u){return!u||u instanceof Wc?u:new Wc(u)};var ul=function(u,p){if(isNaN(u)||isNaN(p))throw new Error("Invalid LngLat object: ("+u+", "+p+")");if(this.lng=+u,this.lat=+p,this.lat>90||this.lat<-90)throw new Error("Invalid LngLat latitude value: must be between -90 and 90")};ul.prototype.wrap=function(){return new ul(K(this.lng,-180,180),this.lat)},ul.prototype.toArray=function(){return[this.lng,this.lat]},ul.prototype.toString=function(){return"LngLat("+this.lng+", "+this.lat+")"},ul.prototype.distanceTo=function(u){var p=Math.PI/180,_=this.lat*p,R=u.lat*p,j=Math.sin(_)*Math.sin(R)+Math.cos(_)*Math.cos(R)*Math.cos((u.lng-this.lng)*p);return 63710088e-1*Math.acos(Math.min(j,1))},ul.prototype.toBounds=function(u){u===void 0&&(u=0);var p=360*u/40075017,_=p/Math.cos(Math.PI/180*this.lat);return new Wc(new ul(this.lng-_,this.lat-p),new ul(this.lng+_,this.lat+p))},ul.convert=function(u){if(u instanceof ul)return u;if(Array.isArray(u)&&(u.length===2||u.length===3))return new ul(Number(u[0]),Number(u[1]));if(!Array.isArray(u)&&typeof u=="object"&&u!==null)return new ul(Number("lng"in u?u.lng:u.lon),Number(u.lat));throw new Error("`LngLatLike` argument must be specified as a LngLat instance, an object {lng: , lat: }, an object {lon: , lat: }, or an array of [, ]")};var rI=2*Math.PI*63710088e-1;function iI(u){return rI*Math.cos(u*Math.PI/180)}function eD(u){return(180+u)/360}function tD(u){return(180-180/Math.PI*Math.log(Math.tan(Math.PI/4+u*Math.PI/360)))/360}function pv(u,p){return u/iI(p)}function P2(u){return 360/Math.PI*Math.atan(Math.exp((180-360*u)*Math.PI/180))-90}var k_=function(u,p,_){_===void 0&&(_=0),this.x=+u,this.y=+p,this.z=+_};k_.fromLngLat=function(u,p){p===void 0&&(p=0);var _=ul.convert(u);return new k_(eD(_.lng),tD(_.lat),pv(p,_.lat))},k_.prototype.toLngLat=function(){return new ul(360*this.x-180,P2(this.y))},k_.prototype.toAltitude=function(){return this.z*iI(P2(this.y))},k_.prototype.meterInMercatorCoordinateUnits=function(){return 1/rI*(u=P2(this.y),1/Math.cos(u*Math.PI/180));var u};var N_=function(u,p,_){this.z=u,this.x=p,this.y=_,this.key=fb(0,u,u,p,_)};N_.prototype.equals=function(u){return this.z===u.z&&this.x===u.x&&this.y===u.y},N_.prototype.url=function(u,p){var _,R,j,$,J,le=(R=this.y,j=this.z,$=M2(256*(_=this.x),256*(R=Math.pow(2,j)-R-1),j),J=M2(256*(_+1),256*(R+1),j),$[0]+","+$[1]+","+J[0]+","+J[1]),ve=function(Ie,Le,ze){for(var Ke,lt="",Mt=Ie;Mt>0;Mt--)lt+=(Le&(Ke=1<this.canonical.z?new qc(u,this.wrap,this.canonical.z,this.canonical.x,this.canonical.y):new qc(u,this.wrap,u,this.canonical.x>>p,this.canonical.y>>p)},qc.prototype.calculateScaledKey=function(u,p){var _=this.canonical.z-u;return u>this.canonical.z?fb(this.wrap*+p,u,this.canonical.z,this.canonical.x,this.canonical.y):fb(this.wrap*+p,u,u,this.canonical.x>>_,this.canonical.y>>_)},qc.prototype.isChildOf=function(u){if(u.wrap!==this.wrap)return!1;var p=this.canonical.z-u.canonical.z;return u.overscaledZ===0||u.overscaledZ>p&&u.canonical.y===this.canonical.y>>p},qc.prototype.children=function(u){if(this.overscaledZ>=u)return[new qc(this.overscaledZ+1,this.wrap,this.canonical.z,this.canonical.x,this.canonical.y)];var p=this.canonical.z+1,_=2*this.canonical.x,R=2*this.canonical.y;return[new qc(p,this.wrap,p,_,R),new qc(p,this.wrap,p,_+1,R),new qc(p,this.wrap,p,_,R+1),new qc(p,this.wrap,p,_+1,R+1)]},qc.prototype.isLessThan=function(u){return this.wrapu.wrap)&&(this.overscaledZu.overscaledZ)&&(this.canonical.xu.canonical.x)&&this.canonical.y=this.dim+1||p<-1||p>=this.dim+1)throw new RangeError("out of range source coordinates for DEM data");return(p+1)*this.stride+(u+1)},cg.prototype._unpackMapbox=function(u,p,_){return(256*u*256+256*p+_)/10-1e4},cg.prototype._unpackTerrarium=function(u,p,_){return 256*u+p+_/256-32768},cg.prototype.getPixels=function(){return new Vl({width:this.stride,height:this.stride},new Uint8Array(this.data.buffer))},cg.prototype.backfillBorder=function(u,p,_){if(this.dim!==u.dim)throw new Error("dem dimension mismatch");var R=p*this.dim,j=p*this.dim+this.dim,$=_*this.dim,J=_*this.dim+this.dim;switch(p){case-1:R=j-1;break;case 1:j=R+1}switch(_){case-1:$=J-1;break;case 1:J=$+1}for(var le=-p*this.dim,ve=-_*this.dim,Ie=$;Ie=0&&Le[3]>=0&&le.insert(J,Le[0],Le[1],Le[2],Le[3])}},s0.prototype.loadVTLayers=function(){return this.vtLayers||(this.vtLayers=new B.VectorTile(new va(this.rawTileData)).layers,this.sourceLayerCoder=new mv(this.vtLayers?Object.keys(this.vtLayers).sort():["_geojsonTileLayer"])),this.vtLayers},s0.prototype.query=function(u,p,_,R){var j=this;this.loadVTLayers();for(var $=u.params||{},J=8192/u.tileSize/u.scale,le=Wd($.filter),ve=u.queryGeometry,Ie=u.queryPadding*J,Le=iD(ve),ze=this.grid.query(Le.minX-Ie,Le.minY-Ie,Le.maxX+Ie,Le.maxY+Ie),Ke=iD(u.cameraQueryGeometry),lt=this.grid3D.query(Ke.minX-Ie,Ke.minY-Ie,Ke.maxX+Ie,Ke.maxY+Ie,function(Nr,Vr,ri,Ei){return function(Ui,Cn,Ki,Bn,en){for(var Wo=0,Xn=Ui;Wo=pn.x&&en>=pn.y)return!0}var Jo=[new f(Cn,Ki),new f(Cn,en),new f(Bn,en),new f(Bn,Ki)];if(Ui.length>2){for(var xo=0,es=Jo;xo=0)return!0;return!1}($,ze)){var Ke=this.sourceLayerCoder.decode(_),lt=this.vtLayers[Ke].feature(R);if(j.needGeometry){var Mt=Ta(lt,!0);if(!j.filter(new So(this.tileID.overscaledZ),Mt,this.tileID.canonical))return}else if(!j.filter(new So(this.tileID.overscaledZ),lt))return;for(var Dt=this.getId(lt,Ke),tr=0;trR)j=!1;else if(p)if(this.expirationTimeyr&&(u.getActor().send("enforceCacheSizeLimit",Gt),ti=0)},n.clamp=U,n.clearTileCache=function(u){var p=y.caches.delete("mapbox-tiles");u&&p.catch(u).then(function(){return u()})},n.clipLine=ZL,n.clone=function(u){var p=new _s(16);return p[0]=u[0],p[1]=u[1],p[2]=u[2],p[3]=u[3],p[4]=u[4],p[5]=u[5],p[6]=u[6],p[7]=u[7],p[8]=u[8],p[9]=u[9],p[10]=u[10],p[11]=u[11],p[12]=u[12],p[13]=u[13],p[14]=u[14],p[15]=u[15],p},n.clone$1=Ce,n.clone$2=function(u){var p=new _s(3);return p[0]=u[0],p[1]=u[1],p[2]=u[2],p},n.collisionCircleLayout=kn,n.config=nt,n.create=function(){var u=new _s(16);return _s!=Float32Array&&(u[1]=0,u[2]=0,u[3]=0,u[4]=0,u[6]=0,u[7]=0,u[8]=0,u[9]=0,u[11]=0,u[12]=0,u[13]=0,u[14]=0),u[0]=1,u[5]=1,u[10]=1,u[15]=1,u},n.create$1=function(){var u=new _s(9);return _s!=Float32Array&&(u[1]=0,u[2]=0,u[3]=0,u[5]=0,u[6]=0,u[7]=0),u[0]=1,u[4]=1,u[8]=1,u},n.create$2=function(){var u=new _s(4);return _s!=Float32Array&&(u[1]=0,u[2]=0),u[0]=1,u[3]=1,u},n.createCommonjsModule=o,n.createExpression=mc,n.createLayout=da,n.createStyleLayer=function(u){return u.type==="custom"?new cb(u):new v8[u.type](u)},n.cross=function(u,p,_){var R=p[0],j=p[1],$=p[2],J=_[0],le=_[1],ve=_[2];return u[0]=j*ve-$*le,u[1]=$*J-R*ve,u[2]=R*le-j*J,u},n.deepEqual=function u(p,_){if(Array.isArray(p)){if(!Array.isArray(_)||p.length!==_.length)return!1;for(var R=0;R0&&($=1/Math.sqrt($)),u[0]=p[0]*$,u[1]=p[1]*$,u[2]=p[2]*$,u},n.number=Ws,n.offscreenCanvasSupported=Jr,n.ortho=function(u,p,_,R,j,$,J){var le=1/(p-_),ve=1/(R-j),Ie=1/($-J);return u[0]=-2*le,u[1]=0,u[2]=0,u[3]=0,u[4]=0,u[5]=-2*ve,u[6]=0,u[7]=0,u[8]=0,u[9]=0,u[10]=2*Ie,u[11]=0,u[12]=(p+_)*le,u[13]=(j+R)*ve,u[14]=(J+$)*Ie,u[15]=1,u},n.parseGlyphPBF=function(u){return new va(u).readFields(VL,[])},n.pbf=va,n.performSymbolLayout=function(u,p,_,R,j,$,J){u.createArrays(),u.tilePixelRatio=8192/(512*u.overscaling),u.compareText={},u.iconsNeedLinear=!1;var le=u.layers[0].layout,ve=u.layers[0]._unevaluatedLayout._values,Ie={};if(u.textSizeData.kind==="composite"){var Le=u.textSizeData,ze=Le.maxZoom;Ie.compositeTextSizes=[ve["text-size"].possiblyEvaluate(new So(Le.minZoom),J),ve["text-size"].possiblyEvaluate(new So(ze),J)]}if(u.iconSizeData.kind==="composite"){var Ke=u.iconSizeData,lt=Ke.maxZoom;Ie.compositeIconSizes=[ve["icon-size"].possiblyEvaluate(new So(Ke.minZoom),J),ve["icon-size"].possiblyEvaluate(new So(lt),J)]}Ie.layoutTextSize=ve["text-size"].possiblyEvaluate(new So(u.zoom+1),J),Ie.layoutIconSize=ve["icon-size"].possiblyEvaluate(new So(u.zoom+1),J),Ie.textMaxSize=ve["text-size"].possiblyEvaluate(new So(18));for(var Mt=24*le.get("text-line-height"),Dt=le.get("text-rotation-alignment")==="map"&&le.get("symbol-placement")!=="point",tr=le.get("text-keep-upright"),qt=le.get("text-size"),ur=function(){var Vr=Nr[Tr],ri=le.get("text-font").evaluate(Vr,{},J).join(","),Ei=qt.evaluate(Vr,{},J),Ui=Ie.layoutTextSize.evaluate(Vr,{},J),Cn=Ie.layoutIconSize.evaluate(Vr,{},J),Ki={horizontal:{},vertical:void 0},Bn=Vr.text,en=[0,0];if(Bn){var Wo=Bn.toString(),Xn=24*le.get("text-letter-spacing").evaluate(Vr,{},J),pn=function(hs){for(var Ra=0,ea=hs;Ra=8192||xm.y<0||xm.y>=8192||function(ta,el,zu,a0,td,Uu,$_,pg,xb,bm,l0,B2,L2,oI,bv,D2,sI,O2,of,kp,pl,wm,bb,Np,aD){var aI,hA,X_,fA,c0,Z_=ta.addToLineVertexArray(el,zu),lI=0,Y_=0,F2=0,cI=0,uI=-1,k2=-1,zp={},wb=St(""),wv=0,Tb=0;if(pg._unevaluatedLayout.getValue("text-radial-offset")===void 0?(wv=(aI=pg.layout.get("text-offset").evaluate(pl,{},Np).map(function(mg){return 24*mg}))[0],Tb=aI[1]):(wv=24*pg.layout.get("text-radial-offset").evaluate(pl,{},Np),Tb=w2),ta.allowVerticalPlacement&&a0.vertical){var N2=pg.layout.get("text-rotate").evaluate(pl,{},Np)+90;fA=new rc(xb,el,bm,l0,B2,a0.vertical,L2,oI,bv,N2),$_&&(c0=new rc(xb,el,bm,l0,B2,$_,sI,O2,bv,N2))}if(td){var Sb=pg.layout.get("icon-rotate").evaluate(pl,{}),hI=pg.layout.get("icon-text-fit")!=="none",fI=_2(td,Sb,bb,hI),z2=$_?_2($_,Sb,bb,hI):void 0;X_=new rc(xb,el,bm,l0,B2,td,sI,O2,!1,Sb),lI=4*fI.length;var dI=ta.iconSizeData,Tv=null;dI.kind==="source"?(Tv=[128*pg.layout.get("icon-size").evaluate(pl,{})])[0]>32640&&Je(ta.layerIds[0]+': Value for "icon-size" is >= 255. Reduce your "icon-size".'):dI.kind==="composite"&&((Tv=[128*wm.compositeIconSizes[0].evaluate(pl,{},Np),128*wm.compositeIconSizes[1].evaluate(pl,{},Np)])[0]>32640||Tv[1]>32640)&&Je(ta.layerIds[0]+': Value for "icon-size" is >= 255. Reduce your "icon-size".'),ta.addSymbols(ta.icon,fI,Tv,kp,of,pl,!1,el,Z_.lineStartIndex,Z_.lineLength,-1,Np),uI=ta.icon.placedSymbolArray.length-1,z2&&(Y_=4*z2.length,ta.addSymbols(ta.icon,z2,Tv,kp,of,pl,Qf.vertical,el,Z_.lineStartIndex,Z_.lineLength,-1,Np),k2=ta.icon.placedSymbolArray.length-1)}for(var lD in a0.horizontal){var Eb=a0.horizontal[lD];if(!hA){wb=St(Eb.text);var x8=pg.layout.get("text-rotate").evaluate(pl,{},Np);hA=new rc(xb,el,bm,l0,B2,Eb,L2,oI,bv,x8)}var cD=Eb.positionedLines.length===1;if(F2+=T2(ta,el,Eb,Uu,pg,bv,pl,D2,Z_,a0.vertical?Qf.horizontal:Qf.horizontalOnly,cD?Object.keys(a0.horizontal):[lD],zp,uI,wm,Np),cD)break}a0.vertical&&(cI+=T2(ta,el,a0.vertical,Uu,pg,bv,pl,D2,Z_,Qf.vertical,["vertical"],zp,k2,wm,Np));var pI=hA?hA.boxStartIndex:ta.collisionBoxArray.length,uD=hA?hA.boxEndIndex:ta.collisionBoxArray.length,b8=fA?fA.boxStartIndex:ta.collisionBoxArray.length,w8=fA?fA.boxEndIndex:ta.collisionBoxArray.length,hD=X_?X_.boxStartIndex:ta.collisionBoxArray.length,Cb=X_?X_.boxEndIndex:ta.collisionBoxArray.length,fD=c0?c0.boxStartIndex:ta.collisionBoxArray.length,T8=c0?c0.boxEndIndex:ta.collisionBoxArray.length,Up=-1,Sv=function(mg,gI){return mg&&mg.circleDiameter?Math.max(mg.circleDiameter,gI):gI};Up=Sv(hA,Up),Up=Sv(fA,Up),Up=Sv(X_,Up);var mI=(Up=Sv(c0,Up))>-1?1:0;mI&&(Up*=aD/24),ta.glyphOffsetArray.length>=Js.MAX_GLYPHS&&Je("Too many glyphs being rendered in a tile. See https://github.com/mapbox/mapbox-gl-js/issues/2907"),pl.sortKey!==void 0&&ta.addToSortKeyRanges(ta.symbolInstances.length,pl.sortKey),ta.symbolInstances.emplaceBack(el.x,el.y,zp.right>=0?zp.right:-1,zp.center>=0?zp.center:-1,zp.left>=0?zp.left:-1,zp.vertical||-1,uI,k2,wb,pI,uD,b8,w8,hD,Cb,fD,T8,bm,F2,cI,lI,Y_,mI,0,L2,wv,Tb,Up)}(hs,xm,vm,ea,Bs,rf,Qd,hs.layers[0],hs.collisionBoxArray,Ra.index,Ra.sourceLayerIndex,hs.index,U_,mb,gb,ku,_m,V_,Ab,ug,Ra,xu,$s,Dp,Na)};if(hg==="line")for(var H_=0,yv=ZL(Ra.geometry,0,0,8192,8192);H_1){var vb=d8(xv,_v,ea.vertical||Op,Bs,24,Av);vb&&Fp(xv,vb)}}else if(Ra.type==="Polygon")for(var ym=0,G_=_i(Ra.geometry,0);ym=No.maxzoom||No.visibility!=="none"&&(y(co,this.zoom,it),(Hr[No.id]=No.createBucket({index:ht.bucketLayerIDs.length,layers:co,zoom:this.zoom,pixelRatio:this.pixelRatio,overscaling:this.overscaling,collisionBoxArray:this.collisionBoxArray,sourceLayerIndex:Di,sourceID:this.source})).populate(Ii,si,this.tileID.canonical),ht.bucketLayerIDs.push(co.map(function(Ds){return Ds.id})))}}}var wo=n.mapObject(si.glyphDependencies,function(Ds){return Object.keys(Ds).map(Number)});Object.keys(wo).length?mt.send("getGlyphs",{uid:this.uid,stacks:wo},function(Ds,ho){Ot||(Ot=Ds,Ct=ho,Qn.call($t))}):Ct={};var Al=Object.keys(si.iconDependencies);Al.length?mt.send("getImages",{icons:Al,source:this.source,tileID:this.tileID,type:"icons"},function(Ds,ho){Ot||(Ot=Ds,ei=ho,Qn.call($t))}):ei={};var uo=Object.keys(si.patternDependencies);function Qn(){if(Ot)return Qe(Ot);if(Ct&&ei&&ui){var Ds=new f(Ct),ho=new n.ImageAtlas(ei,ui);for(var cs in Hr){var _l=Hr[cs];_l instanceof n.SymbolBucket?(y(_l.layers,this.zoom,it),n.performSymbolLayout(_l,Ct,Ds.positions,ei,ho.iconPositions,this.showCollisionBoxes,this.tileID.canonical)):_l.hasPattern&&(_l instanceof n.LineBucket||_l instanceof n.FillBucket||_l instanceof n.FillExtrusionBucket)&&(y(_l.layers,this.zoom,it),_l.addFeatures(si,this.tileID.canonical,ho.patternPositions))}this.status="done",Qe(null,{buckets:n.values(Hr).filter(function(zc){return!zc.isEmpty()}),featureIndex:ht,collisionBoxArray:this.collisionBoxArray,glyphAtlasImage:Ds.image,imageAtlas:ho,glyphMap:this.returnDependencies?Ct:null,iconMap:this.returnDependencies?ei:null,glyphPositions:this.returnDependencies?Ds.positions:null})}}uo.length?mt.send("getImages",{icons:uo,source:this.source,tileID:this.tileID,type:"patterns"},function(Ds,ho){Ot||(Ot=Ds,ui=ho,Qn.call($t))}):ui={},Qn.call(this)};var F=function(Be,$e,it,mt){this.actor=Be,this.layerIndex=$e,this.availableImages=it,this.loadVectorData=mt||I,this.loading={},this.loaded={}};F.prototype.loadTile=function(Be,$e){var it=this,mt=Be.uid;this.loading||(this.loading={});var Qe=!!(Be&&Be.request&&Be.request.collectResourceTiming)&&new n.RequestPerformance(Be.request),$t=this.loading[mt]=new g(Be);$t.abort=this.loadVectorData(Be,function(Jt,ht){if(delete it.loading[mt],Jt||!ht)return $t.status="done",it.loaded[mt]=$t,$e(Jt);var Ot=ht.rawData,Ct={};ht.expires&&(Ct.expires=ht.expires),ht.cacheControl&&(Ct.cacheControl=ht.cacheControl);var ei={};if(Qe){var ui=Qe.finish();ui&&(ei.resourceTiming=JSON.parse(JSON.stringify(ui)))}$t.vectorTile=ht.vectorTile,$t.parse(ht.vectorTile,it.layerIndex,it.availableImages,it.actor,function(Hr,si){if(Hr||!si)return $e(Hr);$e(null,n.extend({rawTileData:Ot.slice(0)},si,Ct,ei))}),it.loaded=it.loaded||{},it.loaded[mt]=$t})},F.prototype.reloadTile=function(Be,$e){var it=this,mt=this.loaded,Qe=Be.uid,$t=this;if(mt&&mt[Qe]){var Jt=mt[Qe];Jt.showCollisionBoxes=Be.showCollisionBoxes;var ht=function(Ot,Ct){var ei=Jt.reloadCallback;ei&&(delete Jt.reloadCallback,Jt.parse(Jt.vectorTile,$t.layerIndex,it.availableImages,$t.actor,ei)),$e(Ot,Ct)};Jt.status==="parsing"?Jt.reloadCallback=ht:Jt.status==="done"&&(Jt.vectorTile?Jt.parse(Jt.vectorTile,this.layerIndex,this.availableImages,this.actor,ht):ht())}},F.prototype.abortTile=function(Be,$e){var it=this.loading,mt=Be.uid;it&&it[mt]&&it[mt].abort&&(it[mt].abort(),delete it[mt]),$e()},F.prototype.removeTile=function(Be,$e){var it=this.loaded,mt=Be.uid;it&&it[mt]&&delete it[mt],$e()};var k=n.window.ImageBitmap,U=function(){this.loaded={}};function K(Be,$e){if(Be.length!==0){ee(Be[0],$e);for(var it=1;it=Math.abs(ht)?it-Ot+ht:ht-Ot+it,it=Ot}it+mt>=0!=!!$e&&Be.reverse()}U.prototype.loadTile=function(Be,$e){var it=Be.uid,mt=Be.encoding,Qe=Be.rawImageData,$t=k&&Qe instanceof k?this.getImageData(Qe):Qe,Jt=new n.DEMData(it,$t,mt);this.loaded=this.loaded||{},this.loaded[it]=Jt,$e(null,Jt)},U.prototype.getImageData=function(Be){this.offscreenCanvas&&this.offscreenCanvasContext||(this.offscreenCanvas=new OffscreenCanvas(Be.width,Be.height),this.offscreenCanvasContext=this.offscreenCanvas.getContext("2d")),this.offscreenCanvas.width=Be.width,this.offscreenCanvas.height=Be.height,this.offscreenCanvasContext.drawImage(Be,0,0,Be.width,Be.height);var $e=this.offscreenCanvasContext.getImageData(-1,-1,Be.width+2,Be.height+2);return this.offscreenCanvasContext.clearRect(0,0,this.offscreenCanvas.width,this.offscreenCanvas.height),new n.RGBAImage({width:$e.width,height:$e.height},$e.data)},U.prototype.removeTile=function(Be){var $e=this.loaded,it=Be.uid;$e&&$e[it]&&delete $e[it]};var he=n.vectorTile.VectorTileFeature.prototype.toGeoJSON,xe=function(Be){this._feature=Be,this.extent=n.EXTENT,this.type=Be.type,this.properties=Be.tags,"id"in Be&&!isNaN(Be.id)&&(this.id=parseInt(Be.id,10))};xe.prototype.loadGeometry=function(){if(this._feature.type===1){for(var Be=[],$e=0,it=this._feature.geometry;$e>31}function Mr(Be,$e){for(var it=Be.loadGeometry(),mt=Be.type,Qe=0,$t=0,Jt=it.length,ht=0;ht>1;(function Di(Ii,Mi,Ni,zi,po,Ls){for(;po>zi;){if(po-zi>600){var co=po-zi+1,No=Ni-zi+1,wo=Math.log(co),Al=.5*Math.exp(2*wo/3),uo=.5*Math.sqrt(wo*Al*(co-Al)/co)*(No-co/2<0?-1:1);Di(Ii,Mi,Ni,Math.max(zi,Math.floor(Ni-No*Al/co+uo)),Math.min(po,Math.floor(Ni+(co-No)*Al/co+uo)),Ls)}var Qn=Mi[2*Ni+Ls],Ds=zi,ho=po;for(mi(Ii,Mi,zi,Ni),Mi[2*po+Ls]>Qn&&mi(Ii,Mi,zi,po);DsQn;)ho--}Mi[2*zi+Ls]===Qn?mi(Ii,Mi,zi,ho):mi(Ii,Mi,++ho,po),ho<=Ni&&(zi=ho+1),Ni<=ho&&(po=ho-1)}})(ei,ui,pr,si,Or,fi%2),Ct(ei,ui,Hr,si,pr-1,fi+1),Ct(ei,ui,Hr,pr+1,Or,fi+1)}})(Jt,ht,mt,0,Jt.length-1,0)};xi.prototype.range=function(Be,$e,it,mt){return function(Qe,$t,Jt,ht,Ot,Ct,ei){for(var ui,Hr,si=[0,Qe.length-1,0],Or=[];si.length;){var fi=si.pop(),pr=si.pop(),Di=si.pop();if(pr-Di<=ei)for(var Ii=Di;Ii<=pr;Ii++)Hr=$t[2*Ii+1],(ui=$t[2*Ii])>=Jt&&ui<=Ot&&Hr>=ht&&Hr<=Ct&&Or.push(Qe[Ii]);else{var Mi=Math.floor((Di+pr)/2);Hr=$t[2*Mi+1],(ui=$t[2*Mi])>=Jt&&ui<=Ot&&Hr>=ht&&Hr<=Ct&&Or.push(Qe[Mi]);var Ni=(fi+1)%2;(fi===0?Jt<=ui:ht<=Hr)&&(si.push(Di),si.push(Mi-1),si.push(Ni)),(fi===0?Ot>=ui:Ct>=Hr)&&(si.push(Mi+1),si.push(pr),si.push(Ni))}}return Or}(this.ids,this.coords,Be,$e,it,mt,this.nodeSize)},xi.prototype.within=function(Be,$e,it){return function(mt,Qe,$t,Jt,ht,Ot){for(var Ct=[0,mt.length-1,0],ei=[],ui=ht*ht;Ct.length;){var Hr=Ct.pop(),si=Ct.pop(),Or=Ct.pop();if(si-Or<=Ot)for(var fi=Or;fi<=si;fi++)un(Qe[2*fi],Qe[2*fi+1],$t,Jt)<=ui&&ei.push(mt[fi]);else{var pr=Math.floor((Or+si)/2),Di=Qe[2*pr],Ii=Qe[2*pr+1];un(Di,Ii,$t,Jt)<=ui&&ei.push(mt[pr]);var Mi=(Hr+1)%2;(Hr===0?$t-ht<=Di:Jt-ht<=Ii)&&(Ct.push(Or),Ct.push(pr-1),Ct.push(Mi)),(Hr===0?$t+ht>=Di:Jt+ht>=Ii)&&(Ct.push(pr+1),Ct.push(si),Ct.push(Mi))}}return ei}(this.ids,this.coords,Be,$e,it,this.nodeSize)};var ii={minZoom:0,maxZoom:16,minPoints:2,radius:40,extent:512,nodeSize:64,log:!1,generateId:!1,reduce:null,map:function(Be){return Be}},Gn=function(Be){this.options=ln(Object.create(ii),Be),this.trees=new Array(this.options.maxZoom+1)};function Ve(Be,$e,it,mt,Qe){return{x:Be,y:$e,zoom:1/0,id:it,parentId:-1,numPoints:mt,properties:Qe}}function nt(Be,$e){var it=Be.geometry.coordinates,mt=it[1];return{x:Xr(it[0]),y:zr(mt),zoom:1/0,index:$e,parentId:-1}}function Ft(Be){return{type:"Feature",id:Be.id,properties:mr(Be),geometry:{type:"Point",coordinates:[(mt=Be.x,360*(mt-.5)),($e=Be.y,it=(180-360*$e)*Math.PI/180,360*Math.atan(Math.exp(it))/Math.PI-90)]}};var $e,it,mt}function mr(Be){var $e=Be.numPoints,it=$e>=1e4?Math.round($e/1e3)+"k":$e>=1e3?Math.round($e/100)/10+"k":$e;return ln(ln({},Be.properties),{cluster:!0,cluster_id:Be.id,point_count:$e,point_count_abbreviated:it})}function Xr(Be){return Be/360+.5}function zr(Be){var $e=Math.sin(Be*Math.PI/180),it=.5-.25*Math.log((1+$e)/(1-$e))/Math.PI;return it<0?0:it>1?1:it}function ln(Be,$e){for(var it in $e)Be[it]=$e[it];return Be}function Nn(Be){return Be.x}function Co(Be){return Be.y}function Ho(Be,$e,it,mt,Qe,$t){var Jt=Qe-it,ht=$t-mt;if(Jt!==0||ht!==0){var Ot=((Be-it)*Jt+($e-mt)*ht)/(Jt*Jt+ht*ht);Ot>1?(it=Qe,mt=$t):Ot>0&&(it+=Jt*Ot,mt+=ht*Ot)}return(Jt=Be-it)*Jt+(ht=$e-mt)*ht}function is(Be,$e,it,mt){var Qe={id:Be===void 0?null:Be,type:$e,geometry:it,tags:mt,minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0};return function($t){var Jt=$t.geometry,ht=$t.type;if(ht==="Point"||ht==="MultiPoint"||ht==="LineString")mo($t,Jt);else if(ht==="Polygon"||ht==="MultiLineString")for(var Ot=0;Ot0&&(Jt+=mt?(Qe*Ct-Ot*$t)/2:Math.sqrt(Math.pow(Ot-Qe,2)+Math.pow(Ct-$t,2))),Qe=Ot,$t=Ct}var ei=$e.length-3;$e[2]=1,function ui(Hr,si,Or,fi){for(var pr,Di=fi,Ii=Or-si>>1,Mi=Or-si,Ni=Hr[si],zi=Hr[si+1],po=Hr[Or],Ls=Hr[Or+1],co=si+3;coDi)pr=co,Di=No;else if(No===Di){var wo=Math.abs(co-Ii);wofi&&(pr-si>3&&ui(Hr,si,pr,fi),Hr[pr+2]=Di,Or-pr>3&&ui(Hr,pr,Or,fi))}($e,0,ei,it),$e[ei+2]=1,$e.size=Math.abs(Jt),$e.start=0,$e.end=$e.size}function so(Be,$e,it,mt){for(var Qe=0;Qe1?1:it}function Yt(Be,$e,it,mt,Qe,$t,Jt,ht){if(mt/=$e,$t>=(it/=$e)&&Jt=mt)return null;for(var Ot=[],Ct=0;Ct=it&&Or=mt)){var fi=[];if(Hr==="Point"||Hr==="MultiPoint")Fe(ui,fi,it,mt,Qe);else if(Hr==="LineString")Ne(ui,fi,it,mt,Qe,!1,ht.lineMetrics);else if(Hr==="MultiLineString")Vt(ui,fi,it,mt,Qe,!1);else if(Hr==="Polygon")Vt(ui,fi,it,mt,Qe,!0);else if(Hr==="MultiPolygon")for(var pr=0;pr=it&&Jt<=mt&&($e.push(Be[$t]),$e.push(Be[$t+1]),$e.push(Be[$t+2]))}}function Ne(Be,$e,it,mt,Qe,$t,Jt){for(var ht,Ot,Ct=rt(Be),ei=Qe===0?yr:fr,ui=Be.start,Hr=0;Hrit&&(Ot=ei(Ct,si,Or,pr,Di,it),Jt&&(Ct.start=ui+ht*Ot)):Ii>mt?Mi=it&&(Ot=ei(Ct,si,Or,pr,Di,it),Ni=!0),Mi>mt&&Ii<=mt&&(Ot=ei(Ct,si,Or,pr,Di,mt),Ni=!0),!$t&&Ni&&(Jt&&(Ct.end=ui+ht*Ot),$e.push(Ct),Ct=rt(Be)),Jt&&(ui+=ht)}var zi=Be.length-3;si=Be[zi],Or=Be[zi+1],fi=Be[zi+2],(Ii=Qe===0?si:Or)>=it&&Ii<=mt&&Gt(Ct,si,Or,fi),zi=Ct.length-3,$t&&zi>=3&&(Ct[zi]!==Ct[0]||Ct[zi+1]!==Ct[1])&&Gt(Ct,Ct[0],Ct[1],Ct[2]),Ct.length&&$e.push(Ct)}function rt(Be){var $e=[];return $e.size=Be.size,$e.start=Be.start,$e.end=Be.end,$e}function Vt(Be,$e,it,mt,Qe,$t){for(var Jt=0;JtJt.maxX&&(Jt.maxX=ei),ui>Jt.maxY&&(Jt.maxY=ui)}return Jt}function fn(Be,$e,it,mt){var Qe=$e.geometry,$t=$e.type,Jt=[];if($t==="Point"||$t==="MultiPoint")for(var ht=0;ht0&&$e.size<(Qe?Jt:mt))it.numPoints+=$e.length/3;else{for(var ht=[],Ot=0;Ot<$e.length;Ot+=3)(mt===0||$e[Ot+2]>Jt)&&(it.numSimplified++,ht.push($e[Ot]),ht.push($e[Ot+1])),it.numPoints++;Qe&&function(Ct,ei){for(var ui=0,Hr=0,si=Ct.length,Or=si-2;Hr0===ei)for(Hr=0,si=Ct.length;Hr24)throw new Error("maxZoom should be in the 0-24 range");if($e.promoteId&&$e.generateId)throw new Error("promoteId and generateId cannot be used together.");var mt=function(Qe,$t){var Jt=[];if(Qe.type==="FeatureCollection")for(var ht=0;ht=mt;Ct--){var ei=+Date.now();ht=this._cluster(ht,Ct),this.trees[Ct]=new xi(ht,Nn,Co,$t,Float32Array),it&&console.log("z%d: %d clusters in %dms",Ct,ht.length,+Date.now()-ei)}return it&&console.timeEnd("total time"),this},Gn.prototype.getClusters=function(Be,$e){var it=((Be[0]+180)%360+360)%360-180,mt=Math.max(-90,Math.min(90,Be[1])),Qe=Be[2]===180?180:((Be[2]+180)%360+360)%360-180,$t=Math.max(-90,Math.min(90,Be[3]));if(Be[2]-Be[0]>=360)it=-180,Qe=180;else if(it>Qe){var Jt=this.getClusters([it,mt,180,$t],$e),ht=this.getClusters([-180,mt,Qe,$t],$e);return Jt.concat(ht)}for(var Ot=this.trees[this._limitZoom($e)],Ct=[],ei=0,ui=Ot.range(Xr(it),zr($t),Xr(Qe),zr(mt));ei$e&&(Hr+=fi.numPoints||1)}if(Hr>=$t){for(var pr=Ot.x*ui,Di=Ot.y*ui,Ii=Qe&&ui>1?this._map(Ot,!0):null,Mi=(ht<<5)+($e+1)+this.points.length,Ni=0,zi=ei;Ni1)for(var co=0,No=ei;co>5},Gn.prototype._getOriginZoom=function(Be){return(Be-this.points.length)%32},Gn.prototype._map=function(Be,$e){if(Be.numPoints)return $e?ln({},Be.properties):Be.properties;var it=this.points[Be.index].properties,mt=this.options.map(it);return $e&&mt===it?ln({},mt):mt},bs.prototype.options={maxZoom:14,indexMaxZoom:5,indexMaxPoints:1e5,tolerance:3,extent:4096,buffer:64,lineMetrics:!1,promoteId:null,generateId:!1,debug:0},bs.prototype.splitTile=function(Be,$e,it,mt,Qe,$t,Jt){for(var ht=[Be,$e,it,mt],Ot=this.options,Ct=Ot.debug;ht.length;){mt=ht.pop(),it=ht.pop(),$e=ht.pop(),Be=ht.pop();var ei=1<<$e,ui=go($e,it,mt),Hr=this.tiles[ui];if(!Hr&&(Ct>1&&console.time("creation"),Hr=this.tiles[ui]=Wi(Be,$e,it,mt,Ot),this.tileCoords.push({z:$e,x:it,y:mt}),Ct)){Ct>1&&(console.log("tile z%d-%d-%d (features: %d, points: %d, simplified: %d)",$e,it,mt,Hr.numFeatures,Hr.numPoints,Hr.numSimplified),console.timeEnd("creation"));var si="z"+$e;this.stats[si]=(this.stats[si]||0)+1,this.total++}if(Hr.source=Be,Qe){if($e===Ot.maxZoom||$e===Qe)continue;var Or=1<1&&console.time("clipping");var fi,pr,Di,Ii,Mi,Ni,zi=.5*Ot.buffer/Ot.extent,po=.5-zi,Ls=.5+zi,co=1+zi;fi=pr=Di=Ii=null,Mi=Yt(Be,ei,it-zi,it+Ls,0,Hr.minX,Hr.maxX,Ot),Ni=Yt(Be,ei,it+po,it+co,0,Hr.minX,Hr.maxX,Ot),Be=null,Mi&&(fi=Yt(Mi,ei,mt-zi,mt+Ls,1,Hr.minY,Hr.maxY,Ot),pr=Yt(Mi,ei,mt+po,mt+co,1,Hr.minY,Hr.maxY,Ot),Mi=null),Ni&&(Di=Yt(Ni,ei,mt-zi,mt+Ls,1,Hr.minY,Hr.maxY,Ot),Ii=Yt(Ni,ei,mt+po,mt+co,1,Hr.minY,Hr.maxY,Ot),Ni=null),Ct>1&&console.timeEnd("clipping"),ht.push(fi||[],$e+1,2*it,2*mt),ht.push(pr||[],$e+1,2*it,2*mt+1),ht.push(Di||[],$e+1,2*it+1,2*mt),ht.push(Ii||[],$e+1,2*it+1,2*mt+1)}}},bs.prototype.getTile=function(Be,$e,it){var mt=this.options,Qe=mt.extent,$t=mt.debug;if(Be<0||Be>24)return null;var Jt=1<1&&console.log("drilling down to z%d-%d-%d",Be,$e,it);for(var Ot,Ct=Be,ei=$e,ui=it;!Ot&&Ct>0;)Ct--,ei=Math.floor(ei/2),ui=Math.floor(ui/2),Ot=this.tiles[go(Ct,ei,ui)];return Ot&&Ot.source?($t>1&&console.log("found parent tile z%d-%d-%d",Ct,ei,ui),$t>1&&console.time("drilling down"),this.splitTile(Ot.source,Ct,ei,ui,Be,$e,it),$t>1&&console.timeEnd("drilling down"),this.tiles[ht]?ti(this.tiles[ht],Qe):null):null};var Us=function(Be){function $e(it,mt,Qe,$t){Be.call(this,it,mt,Qe,wr),$t&&(this.loadGeoJSON=$t)}return Be&&($e.__proto__=Be),($e.prototype=Object.create(Be&&Be.prototype)).constructor=$e,$e.prototype.loadData=function(it,mt){this._pendingCallback&&this._pendingCallback(null,{abandoned:!0}),this._pendingCallback=mt,this._pendingLoadDataParams=it,this._state&&this._state!=="Idle"?this._state="NeedsLoadData":(this._state="Coalescing",this._loadData())},$e.prototype._loadData=function(){var it=this;if(this._pendingCallback&&this._pendingLoadDataParams){var mt=this._pendingCallback,Qe=this._pendingLoadDataParams;delete this._pendingCallback,delete this._pendingLoadDataParams;var $t=!!(Qe&&Qe.request&&Qe.request.collectResourceTiming)&&new n.RequestPerformance(Qe.request);this.loadGeoJSON(Qe,function(Jt,ht){if(Jt||!ht)return mt(Jt);if(typeof ht!="object")return mt(new Error("Input data given to '"+Qe.source+"' is not a valid GeoJSON object."));(function Hr(si,Or){var fi,pr=si&&si.type;if(pr==="FeatureCollection")for(fi=0;fi"u"||typeof document>"u"?"not a browser":Array.prototype&&Array.prototype.every&&Array.prototype.filter&&Array.prototype.forEach&&Array.prototype.indexOf&&Array.prototype.lastIndexOf&&Array.prototype.map&&Array.prototype.some&&Array.prototype.reduce&&Array.prototype.reduceRight&&Array.isArray?Function.prototype&&Function.prototype.bind?Object.keys&&Object.create&&Object.getPrototypeOf&&Object.getOwnPropertyNames&&Object.isSealed&&Object.isFrozen&&Object.isExtensible&&Object.getOwnPropertyDescriptor&&Object.defineProperty&&Object.defineProperties&&Object.seal&&Object.freeze&&Object.preventExtensions?"JSON"in window&&"parse"in JSON&&"stringify"in JSON?function(){if(!("Worker"in window&&"Blob"in window&&"URL"in window))return!1;var ae,ge,Pe=new Blob([""],{type:"text/javascript"}),Ue=URL.createObjectURL(Pe);try{ge=new Worker(Ue),ae=!0}catch{ae=!1}return ge&&ge.terminate(),URL.revokeObjectURL(Ue),ae}()?"Uint8ClampedArray"in window?ArrayBuffer.isView?function(){var ae=document.createElement("canvas");ae.width=ae.height=1;var ge=ae.getContext("2d");if(!ge)return!1;var Pe=ge.getImageData(0,0,1,1);return Pe&&Pe.width===ae.width}()?(L[ie=Y&&Y.failIfMajorPerformanceCaveat]===void 0&&(L[ie]=function(ae){var ge=function(Ue){var ct=document.createElement("canvas"),ft=Object.create(M.webGLContextAttributes);return ft.failIfMajorPerformanceCaveat=Ue,ct.probablySupportsContext?ct.probablySupportsContext("webgl",ft)||ct.probablySupportsContext("experimental-webgl",ft):ct.supportsContext?ct.supportsContext("webgl",ft)||ct.supportsContext("experimental-webgl",ft):ct.getContext("webgl",ft)||ct.getContext("experimental-webgl",ft)}(ae);if(!ge)return!1;var Pe=ge.createShader(ge.VERTEX_SHADER);return!(!Pe||ge.isContextLost())&&(ge.shaderSource(Pe,"void main() {}"),ge.compileShader(Pe),ge.getShaderParameter(Pe,ge.COMPILE_STATUS)===!0)}(ie)),L[ie]?void 0:"insufficient WebGL support"):"insufficient Canvas/getImageData support":"insufficient ArrayBuffer support":"insufficient Uint8ClampedArray support":"insufficient worker support":"insufficient JSON support":"insufficient Object support":"insufficient Function support":"insufficent Array support";var ie}w.exports?w.exports=M:window&&(window.mapboxgl=window.mapboxgl||{},window.mapboxgl.supported=M,window.mapboxgl.notSupportedReason=S);var L={};M.webGLContextAttributes={antialias:!1,alpha:!0,stencil:!0,depth:!0}}),s={create:function(w,M,S){var L=n.window.document.createElement(w);return M!==void 0&&(L.className=M),S&&S.appendChild(L),L},createNS:function(w,M){return n.window.document.createElementNS(w,M)}},c=n.window.document&&n.window.document.documentElement.style;function f(w){if(!c)return w[0];for(var M=0;M=0?0:w.button},s.remove=function(w){w.parentNode&&w.parentNode.removeChild(w)};var ee=function(w){function M(){w.call(this),this.images={},this.updatedImages={},this.callbackDispatchedThisFrame={},this.loaded=!1,this.requestors=[],this.patterns={},this.atlasImage=new n.RGBAImage({width:1,height:1}),this.dirty=!0}return w&&(M.__proto__=w),(M.prototype=Object.create(w&&w.prototype)).constructor=M,M.prototype.isLoaded=function(){return this.loaded},M.prototype.setLoaded=function(S){if(this.loaded!==S&&(this.loaded=S,S)){for(var L=0,Y=this.requestors;L=0?1.2:1))}function Oe(w,M,S,L,Y,ie,ae){for(var ge=0;ge65535)Pe(new Error("glyphs > 65535 not supported"));else if(ft.ranges[ut])Pe(null,{stack:Ue,id:ct,glyph:gt});else{var Pt=ft.requests[ut];Pt||(Pt=ft.requests[ut]=[],Ge.loadGlyphRange(Ue,ut,S.url,S.requestManager,function(Wt,St){if(St){for(var Zt in St)S._doesCharSupportLocalGlyph(+Zt)||(ft.glyphs[+Zt]=St[+Zt]);ft.ranges[ut]=!0}for(var ir=0,dr=Pt;ir1&&(ge=w[++ae]);var Ue=Math.abs(Pe-ge.left),ct=Math.abs(Pe-ge.right),ft=Math.min(Ue,ct),gt=void 0,ut=Y/S*(L+1);if(ge.isDash){var Pt=L-Math.abs(ut);gt=Math.sqrt(ft*ft+Pt*Pt)}else gt=L-Math.sqrt(ft*ft+ut*ut);this.data[ie+Pe]=Math.max(0,Math.min(255,gt+128))}},Je.prototype.addRegularDash=function(w){for(var M=w.length-1;M>=0;--M){var S=w[M],L=w[M+1];S.zeroLength?w.splice(M,1):L&&L.isDash===S.isDash&&(L.left=S.left,w.splice(M,1))}var Y=w[0],ie=w[w.length-1];Y.isDash===ie.isDash&&(Y.left=ie.left-this.width,ie.right=Y.right+this.width);for(var ae=this.width*this.nextRow,ge=0,Pe=w[ge],Ue=0;Ue1&&(Pe=w[++ge]);var ct=Math.abs(Ue-Pe.left),ft=Math.abs(Ue-Pe.right),gt=Math.min(ct,ft);this.data[ae+Ue]=Math.max(0,Math.min(255,(Pe.isDash?gt:-gt)+128))}},Je.prototype.addDash=function(w,M){var S=M?7:0,L=2*S+1;if(this.nextRow+L>this.height)return n.warnOnce("LineAtlas out of space"),null;for(var Y=0,ie=0;ie=S&&w.x=L&&w.y0&&(Ue[new n.OverscaledTileID(S.overscaledZ,ae,L.z,ie,L.y-1).key]={backfilled:!1},Ue[new n.OverscaledTileID(S.overscaledZ,S.wrap,L.z,L.x,L.y-1).key]={backfilled:!1},Ue[new n.OverscaledTileID(S.overscaledZ,Pe,L.z,ge,L.y-1).key]={backfilled:!1}),L.y+10&&(Y.resourceTiming=S._resourceTiming,S._resourceTiming=[]),S.fire(new n.Event("data",Y))}})},M.prototype.onAdd=function(S){this.map=S,this.load()},M.prototype.setData=function(S){var L=this;return this._data=S,this.fire(new n.Event("dataloading",{dataType:"source"})),this._updateWorkerData(function(Y){if(Y)L.fire(new n.ErrorEvent(Y));else{var ie={dataType:"source",sourceDataType:"content"};L._collectResourceTiming&&L._resourceTiming&&L._resourceTiming.length>0&&(ie.resourceTiming=L._resourceTiming,L._resourceTiming=[]),L.fire(new n.Event("data",ie))}}),this},M.prototype.getClusterExpansionZoom=function(S,L){return this.actor.send("geojson.getClusterExpansionZoom",{clusterId:S,source:this.id},L),this},M.prototype.getClusterChildren=function(S,L){return this.actor.send("geojson.getClusterChildren",{clusterId:S,source:this.id},L),this},M.prototype.getClusterLeaves=function(S,L,Y,ie){return this.actor.send("geojson.getClusterLeaves",{source:this.id,clusterId:S,limit:L,offset:Y},ie),this},M.prototype._updateWorkerData=function(S){var L=this;this._loaded=!1;var Y=n.extend({},this.workerOptions),ie=this._data;typeof ie=="string"?(Y.request=this.map._requestManager.transformRequest(n.browser.resolveURL(ie),n.ResourceType.Source),Y.request.collectResourceTiming=this._collectResourceTiming):Y.data=JSON.stringify(ie),this.actor.send(this.type+".loadData",Y,function(ae,ge){L._removed||ge&&ge.abandoned||(L._loaded=!0,ge&&ge.resourceTiming&&ge.resourceTiming[L.id]&&(L._resourceTiming=ge.resourceTiming[L.id].slice(0)),L.actor.send(L.type+".coalesce",{source:Y.source},null),S(ae))})},M.prototype.loaded=function(){return this._loaded},M.prototype.loadTile=function(S,L){var Y=this,ie=S.actor?"reloadTile":"loadTile";S.actor=this.actor,S.request=this.actor.send(ie,{type:this.type,uid:S.uid,tileID:S.tileID,zoom:S.tileID.overscaledZ,maxZoom:this.maxzoom,tileSize:this.tileSize,source:this.id,pixelRatio:n.browser.devicePixelRatio,showCollisionBoxes:this.map.showCollisionBoxes,promoteId:this.promoteId},function(ae,ge){return delete S.request,S.unloadVectorData(),S.aborted?L(null):ae?L(ae):(S.loadVectorData(ge,Y.map.painter,ie==="reloadTile"),L(null))})},M.prototype.abortTile=function(S){S.request&&(S.request.cancel(),delete S.request),S.aborted=!0},M.prototype.unloadTile=function(S){S.unloadVectorData(),this.actor.send("removeTile",{uid:S.uid,type:this.type,source:this.id})},M.prototype.onRemove=function(){this._removed=!0,this.actor.send("removeSource",{type:this.type,source:this.id})},M.prototype.serialize=function(){return n.extend({},this._options,{type:this.type,data:this._data})},M.prototype.hasTransition=function(){return!1},M}(n.Evented),bi=n.createLayout([{name:"a_pos",type:"Int16",components:2},{name:"a_texture_pos",type:"Int16",components:2}]),un=function(w){function M(S,L,Y,ie){w.call(this),this.id=S,this.dispatcher=Y,this.coordinates=L.coordinates,this.type="image",this.minzoom=0,this.maxzoom=22,this.tileSize=512,this.tiles={},this._loaded=!1,this.setEventedParent(ie),this.options=L}return w&&(M.__proto__=w),(M.prototype=Object.create(w&&w.prototype)).constructor=M,M.prototype.load=function(S,L){var Y=this;this._loaded=!1,this.fire(new n.Event("dataloading",{dataType:"source"})),this.url=this.options.url,n.getImage(this.map._requestManager.transformRequest(this.url,n.ResourceType.Image),function(ie,ae){Y._loaded=!0,ie?Y.fire(new n.ErrorEvent(ie)):ae&&(Y.image=ae,S&&(Y.coordinates=S),L&&L(),Y._finishLoading())})},M.prototype.loaded=function(){return this._loaded},M.prototype.updateImage=function(S){var L=this;return this.image&&S.url?(this.options.url=S.url,this.load(S.coordinates,function(){L.texture=null}),this):this},M.prototype._finishLoading=function(){this.map&&(this.setCoordinates(this.coordinates),this.fire(new n.Event("data",{dataType:"source",sourceDataType:"metadata"})))},M.prototype.onAdd=function(S){this.map=S,this.load()},M.prototype.setCoordinates=function(S){var L=this;this.coordinates=S;var Y=S.map(n.MercatorCoordinate.fromLngLat);this.tileID=function(ae){for(var ge=1/0,Pe=1/0,Ue=-1/0,ct=-1/0,ft=0,gt=ae;ftL.end(0)?this.fire(new n.ErrorEvent(new n.ValidationError("sources."+this.id,null,"Playback for this video can be set only between the "+L.start(0)+" and "+L.end(0)+"-second mark."))):this.video.currentTime=S}},M.prototype.getVideo=function(){return this.video},M.prototype.onAdd=function(S){this.map||(this.map=S,this.load(),this.video&&(this.video.play(),this.setCoordinates(this.coordinates)))},M.prototype.prepare=function(){if(!(Object.keys(this.tiles).length===0||this.video.readyState<2)){var S=this.map.painter.context,L=S.gl;for(var Y in this.boundsBuffer||(this.boundsBuffer=S.createVertexBuffer(this._boundsArray,bi.members)),this.boundsSegments||(this.boundsSegments=n.SegmentVector.simpleSegment(0,0,4,2)),this.texture?this.video.paused||(this.texture.bind(L.LINEAR,L.CLAMP_TO_EDGE),L.texSubImage2D(L.TEXTURE_2D,0,0,0,L.RGBA,L.UNSIGNED_BYTE,this.video)):(this.texture=new n.Texture(S,this.video,L.RGBA),this.texture.bind(L.LINEAR,L.CLAMP_TO_EDGE)),this.tiles){var ie=this.tiles[Y];ie.state!=="loaded"&&(ie.state="loaded",ie.texture=this.texture)}}},M.prototype.serialize=function(){return{type:"video",urls:this.urls,coordinates:this.coordinates}},M.prototype.hasTransition=function(){return this.video&&!this.video.paused},M}(un),Xi=function(w){function M(S,L,Y,ie){w.call(this,S,L,Y,ie),L.coordinates?Array.isArray(L.coordinates)&&L.coordinates.length===4&&!L.coordinates.some(function(ae){return!Array.isArray(ae)||ae.length!==2||ae.some(function(ge){return typeof ge!="number"})})||this.fire(new n.ErrorEvent(new n.ValidationError("sources."+S,null,'"coordinates" property must be an array of 4 longitude/latitude array pairs'))):this.fire(new n.ErrorEvent(new n.ValidationError("sources."+S,null,'missing required property "coordinates"'))),L.animate&&typeof L.animate!="boolean"&&this.fire(new n.ErrorEvent(new n.ValidationError("sources."+S,null,'optional "animate" property must be a boolean value'))),L.canvas?typeof L.canvas=="string"||L.canvas instanceof n.window.HTMLCanvasElement||this.fire(new n.ErrorEvent(new n.ValidationError("sources."+S,null,'"canvas" must be either a string representing the ID of the canvas element from which to read, or an HTMLCanvasElement instance'))):this.fire(new n.ErrorEvent(new n.ValidationError("sources."+S,null,'missing required property "canvas"'))),this.options=L,this.animate=L.animate===void 0||L.animate}return w&&(M.__proto__=w),(M.prototype=Object.create(w&&w.prototype)).constructor=M,M.prototype.load=function(){this._loaded=!0,this.canvas||(this.canvas=this.options.canvas instanceof n.window.HTMLCanvasElement?this.options.canvas:n.window.document.getElementById(this.options.canvas)),this.width=this.canvas.width,this.height=this.canvas.height,this._hasInvalidDimensions()?this.fire(new n.ErrorEvent(new Error("Canvas dimensions cannot be less than or equal to zero."))):(this.play=function(){this._playing=!0,this.map.triggerRepaint()},this.pause=function(){this._playing&&(this.prepare(),this._playing=!1)},this._finishLoading())},M.prototype.getCanvas=function(){return this.canvas},M.prototype.onAdd=function(S){this.map=S,this.load(),this.canvas&&this.animate&&this.play()},M.prototype.onRemove=function(){this.pause()},M.prototype.prepare=function(){var S=!1;if(this.canvas.width!==this.width&&(this.width=this.canvas.width,S=!0),this.canvas.height!==this.height&&(this.height=this.canvas.height,S=!0),!this._hasInvalidDimensions()&&Object.keys(this.tiles).length!==0){var L=this.map.painter.context,Y=L.gl;for(var ie in this.boundsBuffer||(this.boundsBuffer=L.createVertexBuffer(this._boundsArray,bi.members)),this.boundsSegments||(this.boundsSegments=n.SegmentVector.simpleSegment(0,0,4,2)),this.texture?(S||this._playing)&&this.texture.update(this.canvas,{premultiply:!0}):this.texture=new n.Texture(L,this.canvas,Y.RGBA,{premultiply:!0}),this.tiles){var ae=this.tiles[ie];ae.state!=="loaded"&&(ae.state="loaded",ae.texture=this.texture)}}},M.prototype.serialize=function(){return{type:"canvas",coordinates:this.coordinates}},M.prototype.hasTransition=function(){return this._playing},M.prototype._hasInvalidDimensions=function(){for(var S=0,L=[this.canvas.width,this.canvas.height];Sthis.max){var ae=this._getAndRemoveByKey(this.order[0]);ae&&this.onRemove(ae)}return this},nt.prototype.has=function(w){return w.wrapped().key in this.data},nt.prototype.getAndRemove=function(w){return this.has(w)?this._getAndRemoveByKey(w.wrapped().key):null},nt.prototype._getAndRemoveByKey=function(w){var M=this.data[w].shift();return M.timeout&&clearTimeout(M.timeout),this.data[w].length===0&&delete this.data[w],this.order.splice(this.order.indexOf(w),1),M.value},nt.prototype.getByKey=function(w){var M=this.data[w];return M?M[0].value:null},nt.prototype.get=function(w){return this.has(w)?this.data[w.wrapped().key][0].value:null},nt.prototype.remove=function(w,M){if(!this.has(w))return this;var S=w.wrapped().key,L=M===void 0?0:this.data[S].indexOf(M),Y=this.data[S][L];return this.data[S].splice(L,1),Y.timeout&&clearTimeout(Y.timeout),this.data[S].length===0&&delete this.data[S],this.onRemove(Y.value),this.order.splice(this.order.indexOf(S),1),this},nt.prototype.setMaxSize=function(w){for(this.max=w;this.order.length>this.max;){var M=this._getAndRemoveByKey(this.order[0]);M&&this.onRemove(M)}return this},nt.prototype.filter=function(w){var M=[];for(var S in this.data)for(var L=0,Y=this.data[S];L1||(Math.abs(ct)>1&&(Math.abs(ct+gt)===1?ct+=gt:Math.abs(ct-gt)===1&&(ct-=gt)),Ue.dem&&Pe.dem&&(Pe.dem.backfillBorder(Ue.dem,ct,ft),Pe.neighboringTiles&&Pe.neighboringTiles[ut]&&(Pe.neighboringTiles[ut].backfilled=!0)))}},M.prototype.getTile=function(S){return this.getTileByID(S.key)},M.prototype.getTileByID=function(S){return this._tiles[S]},M.prototype._retainLoadedChildren=function(S,L,Y,ie){for(var ae in this._tiles){var ge=this._tiles[ae];if(!(ie[ae]||!ge.hasData()||ge.tileID.overscaledZ<=L||ge.tileID.overscaledZ>Y)){for(var Pe=ge.tileID;ge&&ge.tileID.overscaledZ>L+1;){var Ue=ge.tileID.scaledTo(ge.tileID.overscaledZ-1);(ge=this._tiles[Ue.key])&&ge.hasData()&&(Pe=Ue)}for(var ct=Pe;ct.overscaledZ>L;)if(S[(ct=ct.scaledTo(ct.overscaledZ-1)).key]){ie[Pe.key]=Pe;break}}}},M.prototype.findLoadedParent=function(S,L){if(S.key in this._loadedParentTiles){var Y=this._loadedParentTiles[S.key];return Y&&Y.tileID.overscaledZ>=L?Y:null}for(var ie=S.overscaledZ-1;ie>=L;ie--){var ae=S.scaledTo(ie),ge=this._getLoadedTile(ae);if(ge)return ge}},M.prototype._getLoadedTile=function(S){var L=this._tiles[S.key];return L&&L.hasData()?L:this._cache.getByKey(S.wrapped().key)},M.prototype.updateCacheSize=function(S){var L=Math.ceil(S.width/this._source.tileSize)+1,Y=Math.ceil(S.height/this._source.tileSize)+1,ie=Math.floor(L*Y*5),ae=typeof this._maxTileCacheSize=="number"?Math.min(this._maxTileCacheSize,ie):ie;this._cache.setMaxSize(ae)},M.prototype.handleWrapJump=function(S){var L=Math.round((S-(this._prevLng===void 0?S:this._prevLng))/360);if(this._prevLng=S,L){var Y={};for(var ie in this._tiles){var ae=this._tiles[ie];ae.tileID=ae.tileID.unwrapTo(ae.tileID.wrap+L),Y[ae.tileID.key]=ae}for(var ge in this._tiles=Y,this._timers)clearTimeout(this._timers[ge]),delete this._timers[ge];for(var Pe in this._tiles)this._setTileReloadTimer(Pe,this._tiles[Pe])}},M.prototype.update=function(S){var L=this;if(this.transform=S,this._sourceLoaded&&!this._paused){var Y;this.updateCacheSize(S),this.handleWrapJump(this.transform.center.lng),this._coveredTiles={},this.used?this._source.tileID?Y=S.getVisibleUnwrappedCoordinates(this._source.tileID).map(function(ai){return new n.OverscaledTileID(ai.canonical.z,ai.wrap,ai.canonical.z,ai.canonical.x,ai.canonical.y)}):(Y=S.coveringTiles({tileSize:this._source.tileSize,minzoom:this._source.minzoom,maxzoom:this._source.maxzoom,roundZoom:this._source.roundZoom,reparseOverscaled:this._source.reparseOverscaled}),this._source.hasTile&&(Y=Y.filter(function(ai){return L._source.hasTile(ai)}))):Y=[];var ie=S.coveringZoomLevel(this._source),ae=Math.max(ie-M.maxOverzooming,this._source.minzoom),ge=Math.max(ie+M.maxUnderzooming,this._source.minzoom),Pe=this._updateRetainedTiles(Y,ie);if(ei(this._source.type)){for(var Ue={},ct={},ft=0,gt=Object.keys(Pe);ftthis._source.maxzoom){var Zt=Wt.children(this._source.maxzoom)[0],ir=this.getTile(Zt);if(ir&&ir.hasData()){Y[Zt.key]=Zt;continue}}else{var dr=Wt.children(this._source.maxzoom);if(Y[dr[0].key]&&Y[dr[1].key]&&Y[dr[2].key]&&Y[dr[3].key])continue}for(var kr=St.wasRequested(),Lr=Wt.overscaledZ-1;Lr>=ae;--Lr){var Wr=Wt.scaledTo(Lr);if(ie[Wr.key]||(ie[Wr.key]=!0,!(St=this.getTile(Wr))&&kr&&(St=this._addTile(Wr)),St&&(Y[Wr.key]=Wr,kr=St.wasRequested(),St.hasData())))break}}}return Y},M.prototype._updateLoadedParentTileCache=function(){for(var S in this._loadedParentTiles={},this._tiles){for(var L=[],Y=void 0,ie=this._tiles[S].tileID;ie.overscaledZ>0;){if(ie.key in this._loadedParentTiles){Y=this._loadedParentTiles[ie.key];break}L.push(ie.key);var ae=ie.scaledTo(ie.overscaledZ-1);if(Y=this._getLoadedTile(ae))break;ie=ae}for(var ge=0,Pe=L;ge0||(L.hasData()&&L.state!=="reloading"?this._cache.add(L.tileID,L,L.getExpiryTimeout()):(L.aborted=!0,this._abortTile(L),this._unloadTile(L))))},M.prototype.clearTiles=function(){for(var S in this._shouldReloadOnResume=!1,this._paused=!1,this._tiles)this._removeTile(S);this._cache.reset()},M.prototype.tilesIn=function(S,L,Y){var ie=this,ae=[],ge=this.transform;if(!ge)return ae;for(var Pe=Y?ge.getCameraQueryGeometry(S):S,Ue=S.map(function(Lr){return ge.pointCoordinate(Lr)}),ct=Pe.map(function(Lr){return ge.pointCoordinate(Lr)}),ft=this.getIds(),gt=1/0,ut=1/0,Pt=-1/0,Wt=-1/0,St=0,Zt=ct;St=0&&$i[1].y+Si>=0){var bn=Ue.map(function(xn){return ai.getTilePoint(xn)}),Tn=ct.map(function(xn){return ai.getTilePoint(xn)});ae.push({tile:Wr,tileID:ai,queryGeometry:bn,cameraQueryGeometry:Tn,scale:Ci})}}},kr=0;kr=n.browser.now())return!0}return!1},M.prototype.setFeatureState=function(S,L,Y){this._state.updateState(S=S||"_geojsonTileLayer",L,Y)},M.prototype.removeFeatureState=function(S,L,Y){this._state.removeFeatureState(S=S||"_geojsonTileLayer",L,Y)},M.prototype.getFeatureState=function(S,L){return this._state.getState(S=S||"_geojsonTileLayer",L)},M.prototype.setDependencies=function(S,L,Y){var ie=this._tiles[S];ie&&ie.setDependencies(L,Y)},M.prototype.reloadTilesForDependencies=function(S,L){for(var Y in this._tiles)this._tiles[Y].hasDependency(S,L)&&this._reloadTile(Y,"reloading");this._cache.filter(function(ie){return!ie.hasDependency(S,L)})},M}(n.Evented);function Ct(w,M){var S=Math.abs(2*w.wrap)-+(w.wrap<0),L=Math.abs(2*M.wrap)-+(M.wrap<0);return w.overscaledZ-M.overscaledZ||L-S||M.canonical.y-w.canonical.y||M.canonical.x-w.canonical.x}function ei(w){return w==="raster"||w==="image"||w==="video"}function ui(){return new n.window.Worker(Qh.workerUrl)}Ot.maxOverzooming=10,Ot.maxUnderzooming=3;var Hr="mapboxgl_preloaded_worker_pool",si=function(){this.active={}};si.prototype.acquire=function(w){if(!this.workers)for(this.workers=[];this.workers.length0?(L-ie)/ae:0;return this.points[Y].mult(1-ge).add(this.points[M].mult(ge))};var uo=function(w,M,S){var L=this.boxCells=[],Y=this.circleCells=[];this.xCellCount=Math.ceil(w/S),this.yCellCount=Math.ceil(M/S);for(var ie=0;ie=-M[0]&&S<=M[0]&&L>=-M[1]&&L<=M[1]}function zc(w,M,S,L,Y,ie,ae,ge){var Pe=L?w.textSizeData:w.iconSizeData,Ue=n.evaluateSizeForZoom(Pe,S.transform.zoom),ct=[256/S.width*2+1,256/S.height*2+1],ft=L?w.text.dynamicLayoutVertexArray:w.icon.dynamicLayoutVertexArray;ft.clear();for(var gt=w.lineVertexArray,ut=L?w.text.placedSymbolArray:w.icon.placedSymbolArray,Pt=S.transform.width/S.transform.height,Wt=!1,St=0;StMath.abs(S.x-M.x)*L?{useVertical:!0}:(w===n.WritingMode.vertical?M.yS.x)?{needsFlipping:!0}:null}function md(w,M,S,L,Y,ie,ae,ge,Pe,Ue,ct,ft,gt,ut){var Pt,Wt=M/24,St=w.lineOffsetX*Wt,Zt=w.lineOffsetY*Wt;if(w.numGlyphs>1){var ir=w.glyphStartIndex+w.numGlyphs,dr=w.lineStartIndex,kr=w.lineStartIndex+w.lineLength,Lr=yl(Wt,ge,St,Zt,S,ct,ft,w,Pe,ie,gt);if(!Lr)return{notEnoughRoom:!0};var Wr=ho(Lr.first.point,ae).point,ai=ho(Lr.last.point,ae).point;if(L&&!S){var Ci=Ya(w.writingMode,Wr,ai,ut);if(Ci)return Ci}Pt=[Lr.first];for(var Si=w.glyphStartIndex+1;Si0?xn.point:os(ft,Tn,$i,1,Y),qi=Ya(w.writingMode,$i,zo,ut);if(qi)return qi}var Sn=ca(Wt*ge.getoffsetX(w.glyphStartIndex),St,Zt,S,ct,ft,w.segment,w.lineStartIndex,w.lineStartIndex+w.lineLength,Pe,ie,gt);if(!Sn)return{notEnoughRoom:!0};Pt=[Sn]}for(var $n=0,Gi=Pt;$n0?1:-1,Pt=0;L&&(ut*=-1,Pt=Math.PI),ut<0&&(Pt+=Math.PI);for(var Wt=ut>0?ge+ae:ge+ae+1,St=Y,Zt=Y,ir=0,dr=0,kr=Math.abs(gt),Lr=[];ir+dr<=kr;){if((Wt+=ut)=Pe)return null;if(Zt=St,Lr.push(St),(St=ft[Wt])===void 0){var Wr=new n.Point(Ue.getx(Wt),Ue.gety(Wt)),ai=ho(Wr,ct);if(ai.signedDistanceFromCamera>0)St=ft[Wt]=ai.point;else{var Ci=Wt-ut;St=os(ir===0?ie:new n.Point(Ue.getx(Ci),Ue.gety(Ci)),Wr,Zt,kr-ir+1,ct)}}ir+=dr,dr=Zt.dist(St)}var Si=(kr-ir)/dr,$i=St.sub(Zt),bn=$i.mult(Si)._add(Zt);bn._add($i._unit()._perp()._mult(S*ut));var Tn=Pt+Math.atan2(St.y-Zt.y,St.x-Zt.x);return Lr.push(bn),{point:bn,angle:Tn,path:Lr}}uo.prototype.keysLength=function(){return this.boxKeys.length+this.circleKeys.length},uo.prototype.insert=function(w,M,S,L,Y){this._forEachCell(M,S,L,Y,this._insertBoxCell,this.boxUid++),this.boxKeys.push(w),this.bboxes.push(M),this.bboxes.push(S),this.bboxes.push(L),this.bboxes.push(Y)},uo.prototype.insertCircle=function(w,M,S,L){this._forEachCell(M-L,S-L,M+L,S+L,this._insertCircleCell,this.circleUid++),this.circleKeys.push(w),this.circles.push(M),this.circles.push(S),this.circles.push(L)},uo.prototype._insertBoxCell=function(w,M,S,L,Y,ie){this.boxCells[Y].push(ie)},uo.prototype._insertCircleCell=function(w,M,S,L,Y,ie){this.circleCells[Y].push(ie)},uo.prototype._query=function(w,M,S,L,Y,ie){if(S<0||w>this.width||L<0||M>this.height)return!Y&&[];var ae=[];if(w<=0&&M<=0&&this.width<=S&&this.height<=L){if(Y)return!0;for(var ge=0;ge0:ae},uo.prototype._queryCircle=function(w,M,S,L,Y){var ie=w-S,ae=w+S,ge=M-S,Pe=M+S;if(ae<0||ie>this.width||Pe<0||ge>this.height)return!L&&[];var Ue=[];return this._forEachCell(ie,ge,ae,Pe,this._queryCellCircle,Ue,{hitTest:L,circle:{x:w,y:M,radius:S},seenUids:{box:{},circle:{}}},Y),L?Ue.length>0:Ue},uo.prototype.query=function(w,M,S,L,Y){return this._query(w,M,S,L,!1,Y)},uo.prototype.hitTest=function(w,M,S,L,Y){return this._query(w,M,S,L,!0,Y)},uo.prototype.hitTestCircle=function(w,M,S,L){return this._queryCircle(w,M,S,!0,L)},uo.prototype._queryCell=function(w,M,S,L,Y,ie,ae,ge){var Pe=ae.seenUids,Ue=this.boxCells[Y];if(Ue!==null)for(var ct=this.bboxes,ft=0,gt=Ue;ft=ct[Pt+0]&&L>=ct[Pt+1]&&(!ge||ge(this.boxKeys[ut]))){if(ae.hitTest)return ie.push(!0),!0;ie.push({key:this.boxKeys[ut],x1:ct[Pt],y1:ct[Pt+1],x2:ct[Pt+2],y2:ct[Pt+3]})}}}var Wt=this.circleCells[Y];if(Wt!==null)for(var St=this.circles,Zt=0,ir=Wt;Ztae*ae+ge*ge},uo.prototype._circleAndRectCollide=function(w,M,S,L,Y,ie,ae){var ge=(ie-L)/2,Pe=Math.abs(w-(L+ge));if(Pe>ge+S)return!1;var Ue=(ae-Y)/2,ct=Math.abs(M-(Y+Ue));if(ct>Ue+S)return!1;if(Pe<=ge||ct<=Ue)return!0;var ft=Pe-ge,gt=ct-Ue;return ft*ft+gt*gt<=S*S};var mf=new Float32Array([-1/0,-1/0,0,-1/0,-1/0,0,-1/0,-1/0,0,-1/0,-1/0,0]);function Ll(w,M){for(var S=0;S=1;zo--)xn.push(bn.path[zo]);for(var qi=1;qi0){for(var Hn=xn[0].clone(),eo=xn[0].clone(),Dn=1;Dn=Ci.x&&eo.x<=Si.x&&Hn.y>=Ci.y&&eo.y<=Si.y?[xn]:eo.xSi.x||eo.ySi.y?[]:n.clipLine([xn],Ci.x,Ci.y,Si.x,Si.y)}for(var Rn=0,Il=Gi;Rn=this.screenRightBoundary||L<100||M>this.screenBottomBoundary},eu.prototype.isInsideGrid=function(w,M,S,L){return S>=0&&w=0&&M0?(this.prevPlacement&&this.prevPlacement.variableOffsets[ft.crossTileID]&&this.prevPlacement.placements[ft.crossTileID]&&this.prevPlacement.placements[ft.crossTileID].text&&(Wt=this.prevPlacement.variableOffsets[ft.crossTileID].anchor),this.variableOffsets[ft.crossTileID]={textOffset:St,width:S,height:L,anchor:w,textBoxScale:Y,prevAnchor:Wt},this.markUsedJustification(gt,w,ft,ut),gt.allowVerticalPlacement&&(this.markUsedOrientation(gt,ut,ft),this.placedOrientations[ft.crossTileID]=ut),{shift:Zt,placedGlyphBoxes:ir}):void 0},Sc.prototype.placeLayerBucketPart=function(w,M,S){var L=this,Y=w.parameters,ie=Y.bucket,ae=Y.layout,ge=Y.posMatrix,Pe=Y.textLabelPlaneMatrix,Ue=Y.labelToScreenMatrix,ct=Y.textPixelRatio,ft=Y.holdingForFade,gt=Y.collisionBoxArray,ut=Y.partiallyEvaluatedTextSize,Pt=Y.collisionGroup,Wt=ae.get("text-optional"),St=ae.get("icon-optional"),Zt=ae.get("text-allow-overlap"),ir=ae.get("icon-allow-overlap"),dr=ae.get("text-rotation-alignment")==="map",kr=ae.get("text-pitch-alignment")==="map",Lr=ae.get("icon-text-fit")!=="none",Wr=ae.get("symbol-z-order")==="viewport-y",ai=Zt&&(ir||!ie.hasIconData()||St),Ci=ir&&(Zt||!ie.hasTextData()||Wt);!ie.collisionArrays&>&&ie.deserializeCollisionBoxes(gt);var Si=function(qi,Sn){if(!M[qi.crossTileID])if(ft)L.placements[qi.crossTileID]=new pm(!1,!1,!1);else{var $n,Gi=!1,Hn=!1,eo=!0,Dn=null,Rn={box:null,offscreen:null},Il={box:null,offscreen:null},Ga=null,yc=null,cl=0,Vs=0,Ta=0;Sn.textFeatureIndex?cl=Sn.textFeatureIndex:qi.useRuntimeCollisionCircles&&(cl=qi.featureIndex),Sn.verticalTextFeatureIndex&&(Vs=Sn.verticalTextFeatureIndex);var tn=Sn.textBox;if(tn){var _n=function(_s){var yu=n.WritingMode.horizontal;if(ie.allowVerticalPlacement&&!_s&&L.prevPlacement){var Ml=L.prevPlacement.placedOrientations[qi.crossTileID];Ml&&(L.placedOrientations[qi.crossTileID]=Ml,L.markUsedOrientation(ie,yu=Ml,qi))}return yu},Ju=function(_s,yu){if(ie.allowVerticalPlacement&&qi.numVerticalGlyphVertices>0&&Sn.verticalTextBox)for(var Ml=0,ef=ie.writingModes;Ml0&&(jc=jc.filter(function(_s){return _s!==Hc.anchor})).unshift(Hc.anchor)}var Fa=function(_s,yu,Ml){for(var ef=_s.x2-_s.x1,t0=_s.y2-_s.y1,Lp=qi.textBoxScale,th=Lr&&!ir?yu:null,Kf={box:[],offscreen:!1},wf=Zt?2*jc.length:jc.length,tf=0;tf=jc.length,qi,ie,Ml,th);if(Tf&&(Kf=Tf.placedGlyphBoxes)&&Kf.box&&Kf.box.length){Gi=!0,Dn=Tf.shift;break}}return Kf};Ju(function(){return Fa(tn,Sn.iconBox,n.WritingMode.horizontal)},function(){var _s=Sn.verticalTextBox;return ie.allowVerticalPlacement&&!(Rn&&Rn.box&&Rn.box.length)&&qi.numVerticalGlyphVertices>0&&_s?Fa(_s,Sn.verticalIconBox,n.WritingMode.vertical):{box:null,offscreen:null}}),Rn&&(Gi=Rn.box,eo=Rn.offscreen);var Gc=_n(Rn&&Rn.box);if(!Gi&&L.prevPlacement){var bd=L.prevPlacement.variableOffsets[qi.crossTileID];bd&&(L.variableOffsets[qi.crossTileID]=bd,L.markUsedJustification(ie,bd.anchor,qi,Gc))}}else{var wd=function(_s,yu){var Ml=L.collisionIndex.placeCollisionBox(_s,Zt,ct,ge,Pt.predicate);return Ml&&Ml.box&&Ml.box.length&&(L.markUsedOrientation(ie,yu,qi),L.placedOrientations[qi.crossTileID]=yu),Ml};Ju(function(){return wd(tn,n.WritingMode.horizontal)},function(){var _s=Sn.verticalTextBox;return ie.allowVerticalPlacement&&qi.numVerticalGlyphVertices>0&&_s?wd(_s,n.WritingMode.vertical):{box:null,offscreen:null}}),_n(Rn&&Rn.box&&Rn.box.length)}}if(Gi=($n=Rn)&&$n.box&&$n.box.length>0,eo=$n&&$n.offscreen,qi.useRuntimeCollisionCircles){var Td=ie.text.placedSymbolArray.get(qi.centerJustifiedTextSymbolIndex),Ou=n.evaluateSizeForFeature(ie.textSizeData,ut,Td),iu=ae.get("text-padding");Ga=L.collisionIndex.placeCollisionCircles(Zt,Td,ie.lineVertexArray,ie.glyphOffsetArray,Ou,ge,Pe,Ue,S,kr,Pt.predicate,qi.collisionCircleDiameter,iu),Gi=Zt||Ga.circles.length>0&&!Ga.collisionDetected,eo=eo&&Ga.offscreen}if(Sn.iconFeatureIndex&&(Ta=Sn.iconFeatureIndex),Sn.iconBox){var Sa=function(_s){var yu=Lr&&Dn?Mu(_s,Dn.x,Dn.y,dr,kr,L.transform.angle):_s;return L.collisionIndex.placeCollisionBox(yu,ir,ct,ge,Pt.predicate)};Hn=Il&&Il.box&&Il.box.length&&Sn.verticalIconBox?(yc=Sa(Sn.verticalIconBox)).box.length>0:(yc=Sa(Sn.iconBox)).box.length>0,eo=eo&&yc.offscreen}var na=Wt||qi.numHorizontalGlyphVertices===0&&qi.numVerticalGlyphVertices===0,zl=St||qi.numIconVertices===0;if(na||zl?zl?na||(Hn=Hn&&Gi):Gi=Hn&&Gi:Hn=Gi=Hn&&Gi,Gi&&$n&&$n.box&&L.collisionIndex.insertCollisionBox($n.box,ae.get("text-ignore-placement"),ie.bucketInstanceId,Il&&Il.box&&Vs?Vs:cl,Pt.ID),Hn&&yc&&L.collisionIndex.insertCollisionBox(yc.box,ae.get("icon-ignore-placement"),ie.bucketInstanceId,Ta,Pt.ID),Ga&&(Gi&&L.collisionIndex.insertCollisionCircles(Ga.circles,ae.get("text-ignore-placement"),ie.bucketInstanceId,cl,Pt.ID),S)){var eh=ie.bucketInstanceId,Jh=L.collisionCircleArrays[eh];Jh===void 0&&(Jh=L.collisionCircleArrays[eh]=new pu);for(var Ul=0;Ul=0;--bn){var Tn=$i[bn];Si(ie.symbolInstances.get(Tn),ie.collisionArrays[Tn])}else for(var xn=w.symbolInstanceStart;xn=0&&(w.text.placedSymbolArray.get(ge).crossTileID=Y>=0&&ge!==Y?0:S.crossTileID)}},Sc.prototype.markUsedOrientation=function(w,M,S){for(var L=M===n.WritingMode.horizontal||M===n.WritingMode.horizontalOnly?M:0,Y=M===n.WritingMode.vertical?M:0,ie=0,ae=[S.leftJustifiedTextSymbolIndex,S.centerJustifiedTextSymbolIndex,S.rightJustifiedTextSymbolIndex];ie0,Ci=L.placedOrientations[ir.crossTileID],Si=Ci===n.WritingMode.vertical,$i=Ci===n.WritingMode.horizontal||Ci===n.WritingMode.horizontalOnly;if(dr>0||kr>0){var bn=Ep(Wr.text);ut(w.text,dr,Si?Ql:bn),ut(w.text,kr,$i?Ql:bn);var Tn=Wr.text.isHidden();[ir.rightJustifiedTextSymbolIndex,ir.centerJustifiedTextSymbolIndex,ir.leftJustifiedTextSymbolIndex].forEach(function(Rn){Rn>=0&&(w.text.placedSymbolArray.get(Rn).hidden=Tn||Si?1:0)}),ir.verticalPlacedTextSymbolIndex>=0&&(w.text.placedSymbolArray.get(ir.verticalPlacedTextSymbolIndex).hidden=Tn||$i?1:0);var xn=L.variableOffsets[ir.crossTileID];xn&&L.markUsedJustification(w,xn.anchor,ir,Ci);var zo=L.placedOrientations[ir.crossTileID];zo&&(L.markUsedJustification(w,"left",ir,zo),L.markUsedOrientation(w,zo,ir))}if(ai){var qi=Ep(Wr.icon),Sn=!(ft&&ir.verticalPlacedIconSymbolIndex&&Si);ir.placedIconSymbolIndex>=0&&(ut(w.icon,ir.numIconVertices,Sn?qi:Ql),w.icon.placedSymbolArray.get(ir.placedIconSymbolIndex).hidden=Wr.icon.isHidden()),ir.verticalPlacedIconSymbolIndex>=0&&(ut(w.icon,ir.numVerticalIconVertices,Sn?Ql:qi),w.icon.placedSymbolArray.get(ir.verticalPlacedIconSymbolIndex).hidden=Wr.icon.isHidden())}if(w.hasIconCollisionBoxData()||w.hasTextCollisionBoxData()){var $n=w.collisionArrays[Zt];if($n){var Gi=new n.Point(0,0);if($n.textBox||$n.verticalTextBox){var Hn=!0;if(Pe){var eo=L.variableOffsets[Lr];eo?(Gi=Ma(eo.anchor,eo.width,eo.height,eo.textOffset,eo.textBoxScale),Ue&&Gi._rotate(ct?L.transform.angle:-L.transform.angle)):Hn=!1}$n.textBox&&pc(w.textCollisionBox.collisionVertexArray,Wr.text.placed,!Hn||Si,Gi.x,Gi.y),$n.verticalTextBox&&pc(w.textCollisionBox.collisionVertexArray,Wr.text.placed,!Hn||$i,Gi.x,Gi.y)}var Dn=Boolean(!$i&&$n.verticalIconBox);$n.iconBox&&pc(w.iconCollisionBox.collisionVertexArray,Wr.icon.placed,Dn,ft?Gi.x:0,ft?Gi.y:0),$n.verticalIconBox&&pc(w.iconCollisionBox.collisionVertexArray,Wr.icon.placed,!Dn,ft?Gi.x:0,ft?Gi.y:0)}}},Wt=0;Wtw},Sc.prototype.setStale=function(){this.stale=!0};var gf=Math.pow(2,25),gd=Math.pow(2,24),jh=Math.pow(2,17),Hh=Math.pow(2,16),Io=Math.pow(2,9),Sp=Math.pow(2,8),eg=Math.pow(2,1);function Ep(w){if(w.opacity===0&&!w.placed)return 0;if(w.opacity===1&&w.placed)return 4294967295;var M=w.placed?1:0,S=Math.floor(127*w.opacity);return S*gf+M*gd+S*jh+M*Hh+S*Io+M*Sp+S*eg+M}var Ql=0,Jl=function(w){this._sortAcrossTiles=w.layout.get("symbol-z-order")!=="viewport-y"&&w.layout.get("symbol-sort-key").constantOr(1)!==void 0,this._currentTileIndex=0,this._currentPartIndex=0,this._seenCrossTileIDs={},this._bucketParts=[]};Jl.prototype.continuePlacement=function(w,M,S,L,Y){for(var ie=this._bucketParts;this._currentTileIndex2};this._currentPlacementIndex>=0;){var ae=M[w[this._currentPlacementIndex]],ge=this.placement.collisionIndex.transform.zoom;if(ae.type==="symbol"&&(!ae.minzoom||ae.minzoom<=ge)&&(!ae.maxzoom||ae.maxzoom>ge)){if(this._inProgressLayer||(this._inProgressLayer=new Jl(ae)),this._inProgressLayer.continuePlacement(S[ae.source],this.placement,this._showCollisionBoxes,ae,ie))return;delete this._inProgressLayer}this._currentPlacementIndex--}this._done=!0},_a.prototype.commit=function(w){return this.placement.commit(w),this.placement};var Zn=512/n.EXTENT/2,Gs=function(w,M,S){this.tileID=w,this.indexedSymbolInstances={},this.bucketInstanceId=S;for(var L=0;Lw.overscaledZ)for(var ge in ae){var Pe=ae[ge];Pe.tileID.isChildOf(w)&&Pe.findMatches(M.symbolInstances,w,Y)}else{var Ue=ae[w.scaledTo(Number(ie)).key];Ue&&Ue.findMatches(M.symbolInstances,w,Y)}}for(var ct=0;ct1?"@2x":"",ft=n.getJSON(ie.transformRequest(ie.normalizeSpriteURL(Y,ct,".json"),n.ResourceType.SpriteJSON),function(Pt,Wt){ft=null,Ue||(Ue=Pt,ge=Wt,ut())}),gt=n.getImage(ie.transformRequest(ie.normalizeSpriteURL(Y,ct,".png"),n.ResourceType.SpriteImage),function(Pt,Wt){gt=null,Ue||(Ue=Pt,Pe=Wt,ut())});function ut(){if(Ue)ae(Ue);else if(ge&&Pe){var Pt=n.browser.getImageData(Pe),Wt={};for(var St in ge){var Zt=ge[St],ir=Zt.width,dr=Zt.height,kr=Zt.x,Lr=Zt.y,Wr=Zt.sdf,ai=Zt.pixelRatio,Ci=Zt.stretchX,Si=Zt.stretchY,$i=Zt.content,bn=new n.RGBAImage({width:ir,height:dr});n.RGBAImage.copy(Pt,bn,{x:kr,y:Lr},{x:0,y:0},{width:ir,height:dr}),Wt[St]={data:bn,pixelRatio:ai,sdf:Wr,stretchX:Ci,stretchY:Si,content:$i}}ae(null,Wt)}}return{cancel:function(){ft&&(ft.cancel(),ft=null),gt&&(gt.cancel(),gt=null)}}}(S,this.map._requestManager,function(Y,ie){if(L._spriteRequest=null,Y)L.fire(new n.ErrorEvent(Y));else if(ie)for(var ae in ie)L.imageManager.addImage(ae,ie[ae]);L.imageManager.setLoaded(!0),L._availableImages=L.imageManager.listImages(),L.dispatcher.broadcast("setImages",L._availableImages),L.fire(new n.Event("data",{dataType:"style"}))})},M.prototype._validateLayer=function(S){var L=this.sourceCaches[S.source];if(L){var Y=S.sourceLayer;if(Y){var ie=L.getSource();(ie.type==="geojson"||ie.vectorLayerIds&&ie.vectorLayerIds.indexOf(Y)===-1)&&this.fire(new n.ErrorEvent(new Error('Source layer "'+Y+'" does not exist on source "'+ie.id+'" as specified by style layer "'+S.id+'"')))}}},M.prototype.loaded=function(){if(!this._loaded||Object.keys(this._updatedSources).length)return!1;for(var S in this.sourceCaches)if(!this.sourceCaches[S].loaded())return!1;return!!this.imageManager.isLoaded()},M.prototype._serializeLayers=function(S){for(var L=[],Y=0,ie=S;Y0)throw new Error("Unimplemented: "+ie.map(function(ae){return ae.command}).join(", ")+".");return Y.forEach(function(ae){ae.command!=="setTransition"&&L[ae.command].apply(L,ae.args)}),this.stylesheet=S,!0},M.prototype.addImage=function(S,L){if(this.getImage(S))return this.fire(new n.ErrorEvent(new Error("An image with this name already exists.")));this.imageManager.addImage(S,L),this._afterImageUpdated(S)},M.prototype.updateImage=function(S,L){this.imageManager.updateImage(S,L)},M.prototype.getImage=function(S){return this.imageManager.getImage(S)},M.prototype.removeImage=function(S){if(!this.getImage(S))return this.fire(new n.ErrorEvent(new Error("No image with this name exists.")));this.imageManager.removeImage(S),this._afterImageUpdated(S)},M.prototype._afterImageUpdated=function(S){this._availableImages=this.imageManager.listImages(),this._changedImages[S]=!0,this._changed=!0,this.dispatcher.broadcast("setImages",this._availableImages),this.fire(new n.Event("data",{dataType:"style"}))},M.prototype.listImages=function(){return this._checkLoaded(),this.imageManager.listImages()},M.prototype.addSource=function(S,L,Y){var ie=this;if(Y===void 0&&(Y={}),this._checkLoaded(),this.sourceCaches[S]!==void 0)throw new Error("There is already a source with this ID");if(!L.type)throw new Error("The type property must be defined, but only the following properties were given: "+Object.keys(L).join(", ")+".");if(!(["vector","raster","geojson","video","image"].indexOf(L.type)>=0&&this._validate(n.validateStyle.source,"sources."+S,L,null,Y))){this.map&&this.map._collectResourceTiming&&(L.collectResourceTiming=!0);var ae=this.sourceCaches[S]=new Ot(S,L,this.dispatcher);ae.style=this,ae.setEventedParent(this,function(){return{isSourceLoaded:ie.loaded(),source:ae.serialize(),sourceId:S}}),ae.onAdd(this.map),this._changed=!0}},M.prototype.removeSource=function(S){if(this._checkLoaded(),this.sourceCaches[S]===void 0)throw new Error("There is no source with this ID");for(var L in this._layers)if(this._layers[L].source===S)return this.fire(new n.ErrorEvent(new Error('Source "'+S+'" cannot be removed while layer "'+L+'" is using it.')));var Y=this.sourceCaches[S];delete this.sourceCaches[S],delete this._updatedSources[S],Y.fire(new n.Event("data",{sourceDataType:"metadata",dataType:"source",sourceId:S})),Y.setEventedParent(null),Y.clearTiles(),Y.onRemove&&Y.onRemove(this.map),this._changed=!0},M.prototype.setGeoJSONSourceData=function(S,L){this._checkLoaded(),this.sourceCaches[S].getSource().setData(L),this._changed=!0},M.prototype.getSource=function(S){return this.sourceCaches[S]&&this.sourceCaches[S].getSource()},M.prototype.addLayer=function(S,L,Y){Y===void 0&&(Y={}),this._checkLoaded();var ie=S.id;if(this.getLayer(ie))this.fire(new n.ErrorEvent(new Error('Layer with id "'+ie+'" already exists on this map')));else{var ae;if(S.type==="custom"){if(vl(this,n.validateCustomStyleLayer(S)))return;ae=n.createStyleLayer(S)}else{if(typeof S.source=="object"&&(this.addSource(ie,S.source),S=n.clone$1(S),S=n.extend(S,{source:ie})),this._validate(n.validateStyle.layer,"layers."+ie,S,{arrayIndex:-1},Y))return;ae=n.createStyleLayer(S),this._validateLayer(ae),ae.setEventedParent(this,{layer:{id:ie}}),this._serializedLayers[ae.id]=ae.serialize()}var ge=L?this._order.indexOf(L):this._order.length;if(L&&ge===-1)this.fire(new n.ErrorEvent(new Error('Layer with id "'+L+'" does not exist on this map.')));else{if(this._order.splice(ge,0,ie),this._layerOrderChanged=!0,this._layers[ie]=ae,this._removedLayers[ie]&&ae.source&&ae.type!=="custom"){var Pe=this._removedLayers[ie];delete this._removedLayers[ie],Pe.type!==ae.type?this._updatedSources[ae.source]="clear":(this._updatedSources[ae.source]="reload",this.sourceCaches[ae.source].pause())}this._updateLayer(ae),ae.onAdd&&ae.onAdd(this.map)}}},M.prototype.moveLayer=function(S,L){if(this._checkLoaded(),this._changed=!0,this._layers[S]){if(S!==L){var Y=this._order.indexOf(S);this._order.splice(Y,1);var ie=L?this._order.indexOf(L):this._order.length;L&&ie===-1?this.fire(new n.ErrorEvent(new Error('Layer with id "'+L+'" does not exist on this map.'))):(this._order.splice(ie,0,S),this._layerOrderChanged=!0)}}else this.fire(new n.ErrorEvent(new Error("The layer '"+S+"' does not exist in the map's style and cannot be moved.")))},M.prototype.removeLayer=function(S){this._checkLoaded();var L=this._layers[S];if(L){L.setEventedParent(null);var Y=this._order.indexOf(S);this._order.splice(Y,1),this._layerOrderChanged=!0,this._changed=!0,this._removedLayers[S]=L,delete this._layers[S],delete this._serializedLayers[S],delete this._updatedLayers[S],delete this._updatedPaintProps[S],L.onRemove&&L.onRemove(this.map)}else this.fire(new n.ErrorEvent(new Error("The layer '"+S+"' does not exist in the map's style and cannot be removed.")))},M.prototype.getLayer=function(S){return this._layers[S]},M.prototype.hasLayer=function(S){return S in this._layers},M.prototype.setLayerZoomRange=function(S,L,Y){this._checkLoaded();var ie=this.getLayer(S);ie?ie.minzoom===L&&ie.maxzoom===Y||(L!=null&&(ie.minzoom=L),Y!=null&&(ie.maxzoom=Y),this._updateLayer(ie)):this.fire(new n.ErrorEvent(new Error("The layer '"+S+"' does not exist in the map's style and cannot have zoom extent.")))},M.prototype.setFilter=function(S,L,Y){Y===void 0&&(Y={}),this._checkLoaded();var ie=this.getLayer(S);if(ie){if(!n.deepEqual(ie.filter,L))return L==null?(ie.filter=void 0,void this._updateLayer(ie)):void(this._validate(n.validateStyle.filter,"layers."+ie.id+".filter",L,null,Y)||(ie.filter=n.clone$1(L),this._updateLayer(ie)))}else this.fire(new n.ErrorEvent(new Error("The layer '"+S+"' does not exist in the map's style and cannot be filtered.")))},M.prototype.getFilter=function(S){return n.clone$1(this.getLayer(S).filter)},M.prototype.setLayoutProperty=function(S,L,Y,ie){ie===void 0&&(ie={}),this._checkLoaded();var ae=this.getLayer(S);ae?n.deepEqual(ae.getLayoutProperty(L),Y)||(ae.setLayoutProperty(L,Y,ie),this._updateLayer(ae)):this.fire(new n.ErrorEvent(new Error("The layer '"+S+"' does not exist in the map's style and cannot be styled.")))},M.prototype.getLayoutProperty=function(S,L){var Y=this.getLayer(S);if(Y)return Y.getLayoutProperty(L);this.fire(new n.ErrorEvent(new Error("The layer '"+S+"' does not exist in the map's style.")))},M.prototype.setPaintProperty=function(S,L,Y,ie){ie===void 0&&(ie={}),this._checkLoaded();var ae=this.getLayer(S);ae?n.deepEqual(ae.getPaintProperty(L),Y)||(ae.setPaintProperty(L,Y,ie)&&this._updateLayer(ae),this._changed=!0,this._updatedPaintProps[S]=!0):this.fire(new n.ErrorEvent(new Error("The layer '"+S+"' does not exist in the map's style and cannot be styled.")))},M.prototype.getPaintProperty=function(S,L){return this.getLayer(S).getPaintProperty(L)},M.prototype.setFeatureState=function(S,L){this._checkLoaded();var Y=S.source,ie=S.sourceLayer,ae=this.sourceCaches[Y];if(ae!==void 0){var ge=ae.getSource().type;ge==="geojson"&&ie?this.fire(new n.ErrorEvent(new Error("GeoJSON sources cannot have a sourceLayer parameter."))):ge!=="vector"||ie?(S.id===void 0&&this.fire(new n.ErrorEvent(new Error("The feature id parameter must be provided."))),ae.setFeatureState(ie,S.id,L)):this.fire(new n.ErrorEvent(new Error("The sourceLayer parameter must be provided for vector source types.")))}else this.fire(new n.ErrorEvent(new Error("The source '"+Y+"' does not exist in the map's style.")))},M.prototype.removeFeatureState=function(S,L){this._checkLoaded();var Y=S.source,ie=this.sourceCaches[Y];if(ie!==void 0){var ae=ie.getSource().type,ge=ae==="vector"?S.sourceLayer:void 0;ae!=="vector"||ge?L&&typeof S.id!="string"&&typeof S.id!="number"?this.fire(new n.ErrorEvent(new Error("A feature id is required to remove its specific state property."))):ie.removeFeatureState(ge,S.id,L):this.fire(new n.ErrorEvent(new Error("The sourceLayer parameter must be provided for vector source types.")))}else this.fire(new n.ErrorEvent(new Error("The source '"+Y+"' does not exist in the map's style.")))},M.prototype.getFeatureState=function(S){this._checkLoaded();var L=S.source,Y=S.sourceLayer,ie=this.sourceCaches[L];if(ie!==void 0){if(ie.getSource().type!=="vector"||Y)return S.id===void 0&&this.fire(new n.ErrorEvent(new Error("The feature id parameter must be provided."))),ie.getFeatureState(Y,S.id);this.fire(new n.ErrorEvent(new Error("The sourceLayer parameter must be provided for vector source types.")))}else this.fire(new n.ErrorEvent(new Error("The source '"+L+"' does not exist in the map's style.")))},M.prototype.getTransition=function(){return n.extend({duration:300,delay:0},this.stylesheet&&this.stylesheet.transition)},M.prototype.serialize=function(){return n.filterObject({version:this.stylesheet.version,name:this.stylesheet.name,metadata:this.stylesheet.metadata,light:this.stylesheet.light,center:this.stylesheet.center,zoom:this.stylesheet.zoom,bearing:this.stylesheet.bearing,pitch:this.stylesheet.pitch,sprite:this.stylesheet.sprite,glyphs:this.stylesheet.glyphs,transition:this.stylesheet.transition,sources:n.mapObject(this.sourceCaches,function(S){return S.serialize()}),layers:this._serializeLayers(this._order)},function(S){return S!==void 0})},M.prototype._updateLayer=function(S){this._updatedLayers[S.id]=!0,S.source&&!this._updatedSources[S.source]&&this.sourceCaches[S.source].getSource().type!=="raster"&&(this._updatedSources[S.source]="reload",this.sourceCaches[S.source].pause()),this._changed=!0},M.prototype._flattenAndSortRenderedFeatures=function(S){for(var L=this,Y=function(Ci){return L._layers[Ci].type==="fill-extrusion"},ie={},ae=[],ge=this._order.length-1;ge>=0;ge--){var Pe=this._order[ge];if(Y(Pe)){ie[Pe]=ge;for(var Ue=0,ct=S;Ue=0;Wt--){var St=this._order[Wt];if(Y(St))for(var Zt=ae.length-1;Zt>=0;Zt--){var ir=ae[Zt].feature;if(ie[ir.layer.id] 0.5) {gl_FragColor=vec4(0.0,0.0,1.0,0.5)*alpha;}if (v_notUsed > 0.5) {gl_FragColor*=.1;}}","attribute vec2 a_pos;attribute vec2 a_anchor_pos;attribute vec2 a_extrude;attribute vec2 a_placed;attribute vec2 a_shift;uniform mat4 u_matrix;uniform vec2 u_extrude_scale;uniform float u_camera_to_center_distance;varying float v_placed;varying float v_notUsed;void main() {vec4 projectedPoint=u_matrix*vec4(a_anchor_pos,0,1);highp float camera_to_anchor_distance=projectedPoint.w;highp float collision_perspective_ratio=clamp(0.5+0.5*(u_camera_to_center_distance/camera_to_anchor_distance),0.0,4.0);gl_Position=u_matrix*vec4(a_pos,0.0,1.0);gl_Position.xy+=(a_extrude+a_shift)*u_extrude_scale*gl_Position.w*collision_perspective_ratio;v_placed=a_placed.x;v_notUsed=a_placed.y;}"),mh=vr("varying float v_radius;varying vec2 v_extrude;varying float v_perspective_ratio;varying float v_collision;void main() {float alpha=0.5*min(v_perspective_ratio,1.0);float stroke_radius=0.9*max(v_perspective_ratio,1.0);float distance_to_center=length(v_extrude);float distance_to_edge=abs(distance_to_center-v_radius);float opacity_t=smoothstep(-stroke_radius,0.0,-distance_to_edge);vec4 color=mix(vec4(0.0,0.0,1.0,0.5),vec4(1.0,0.0,0.0,1.0),v_collision);gl_FragColor=color*alpha*opacity_t;}","attribute vec2 a_pos;attribute float a_radius;attribute vec2 a_flags;uniform mat4 u_matrix;uniform mat4 u_inv_matrix;uniform vec2 u_viewport_size;uniform float u_camera_to_center_distance;varying float v_radius;varying vec2 v_extrude;varying float v_perspective_ratio;varying float v_collision;vec3 toTilePosition(vec2 screenPos) {vec4 rayStart=u_inv_matrix*vec4(screenPos,-1.0,1.0);vec4 rayEnd =u_inv_matrix*vec4(screenPos, 1.0,1.0);rayStart.xyz/=rayStart.w;rayEnd.xyz /=rayEnd.w;highp float t=(0.0-rayStart.z)/(rayEnd.z-rayStart.z);return mix(rayStart.xyz,rayEnd.xyz,t);}void main() {vec2 quadCenterPos=a_pos;float radius=a_radius;float collision=a_flags.x;float vertexIdx=a_flags.y;vec2 quadVertexOffset=vec2(mix(-1.0,1.0,float(vertexIdx >=2.0)),mix(-1.0,1.0,float(vertexIdx >=1.0 && vertexIdx <=2.0)));vec2 quadVertexExtent=quadVertexOffset*radius;vec3 tilePos=toTilePosition(quadCenterPos);vec4 clipPos=u_matrix*vec4(tilePos,1.0);highp float camera_to_anchor_distance=clipPos.w;highp float collision_perspective_ratio=clamp(0.5+0.5*(u_camera_to_center_distance/camera_to_anchor_distance),0.0,4.0);float padding_factor=1.2;v_radius=radius;v_extrude=quadVertexExtent*padding_factor;v_perspective_ratio=collision_perspective_ratio;v_collision=collision;gl_Position=vec4(clipPos.xyz/clipPos.w,1.0)+vec4(quadVertexExtent*padding_factor/u_viewport_size*2.0,0.0,0.0);}"),ms=vr("uniform highp vec4 u_color;uniform sampler2D u_overlay;varying vec2 v_uv;void main() {vec4 overlay_color=texture2D(u_overlay,v_uv);gl_FragColor=mix(u_color,overlay_color,overlay_color.a);}","attribute vec2 a_pos;varying vec2 v_uv;uniform mat4 u_matrix;uniform float u_overlay_scale;void main() {v_uv=a_pos/8192.0;gl_Position=u_matrix*vec4(a_pos*u_overlay_scale,0,1);}"),Ao=vr(`#pragma mapbox: define highp vec4 color +#pragma mapbox: define lowp float opacity +void main() { +#pragma mapbox: initialize highp vec4 color +#pragma mapbox: initialize lowp float opacity +gl_FragColor=color*opacity; +#ifdef OVERDRAW_INSPECTOR +gl_FragColor=vec4(1.0); +#endif +}`,`attribute vec2 a_pos;uniform mat4 u_matrix; +#pragma mapbox: define highp vec4 color +#pragma mapbox: define lowp float opacity +void main() { +#pragma mapbox: initialize highp vec4 color +#pragma mapbox: initialize lowp float opacity +gl_Position=u_matrix*vec4(a_pos,0,1);}`),qh=vr(`varying vec2 v_pos; +#pragma mapbox: define highp vec4 outline_color +#pragma mapbox: define lowp float opacity +void main() { +#pragma mapbox: initialize highp vec4 outline_color +#pragma mapbox: initialize lowp float opacity +float dist=length(v_pos-gl_FragCoord.xy);float alpha=1.0-smoothstep(0.0,1.0,dist);gl_FragColor=outline_color*(alpha*opacity); +#ifdef OVERDRAW_INSPECTOR +gl_FragColor=vec4(1.0); +#endif +}`,`attribute vec2 a_pos;uniform mat4 u_matrix;uniform vec2 u_world;varying vec2 v_pos; +#pragma mapbox: define highp vec4 outline_color +#pragma mapbox: define lowp float opacity +void main() { +#pragma mapbox: initialize highp vec4 outline_color +#pragma mapbox: initialize lowp float opacity +gl_Position=u_matrix*vec4(a_pos,0,1);v_pos=(gl_Position.xy/gl_Position.w+1.0)/2.0*u_world;}`),us=vr(`uniform vec2 u_texsize;uniform sampler2D u_image;uniform float u_fade;varying vec2 v_pos_a;varying vec2 v_pos_b;varying vec2 v_pos; +#pragma mapbox: define lowp float opacity +#pragma mapbox: define lowp vec4 pattern_from +#pragma mapbox: define lowp vec4 pattern_to +void main() { +#pragma mapbox: initialize lowp float opacity +#pragma mapbox: initialize mediump vec4 pattern_from +#pragma mapbox: initialize mediump vec4 pattern_to +vec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;vec2 imagecoord=mod(v_pos_a,1.0);vec2 pos=mix(pattern_tl_a/u_texsize,pattern_br_a/u_texsize,imagecoord);vec4 color1=texture2D(u_image,pos);vec2 imagecoord_b=mod(v_pos_b,1.0);vec2 pos2=mix(pattern_tl_b/u_texsize,pattern_br_b/u_texsize,imagecoord_b);vec4 color2=texture2D(u_image,pos2);float dist=length(v_pos-gl_FragCoord.xy);float alpha=1.0-smoothstep(0.0,1.0,dist);gl_FragColor=mix(color1,color2,u_fade)*alpha*opacity; +#ifdef OVERDRAW_INSPECTOR +gl_FragColor=vec4(1.0); +#endif +}`,`uniform mat4 u_matrix;uniform vec2 u_world;uniform vec2 u_pixel_coord_upper;uniform vec2 u_pixel_coord_lower;uniform vec3 u_scale;attribute vec2 a_pos;varying vec2 v_pos_a;varying vec2 v_pos_b;varying vec2 v_pos; +#pragma mapbox: define lowp float opacity +#pragma mapbox: define lowp vec4 pattern_from +#pragma mapbox: define lowp vec4 pattern_to +#pragma mapbox: define lowp float pixel_ratio_from +#pragma mapbox: define lowp float pixel_ratio_to +void main() { +#pragma mapbox: initialize lowp float opacity +#pragma mapbox: initialize mediump vec4 pattern_from +#pragma mapbox: initialize mediump vec4 pattern_to +#pragma mapbox: initialize lowp float pixel_ratio_from +#pragma mapbox: initialize lowp float pixel_ratio_to +vec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;float tileRatio=u_scale.x;float fromScale=u_scale.y;float toScale=u_scale.z;gl_Position=u_matrix*vec4(a_pos,0,1);vec2 display_size_a=(pattern_br_a-pattern_tl_a)/pixel_ratio_from;vec2 display_size_b=(pattern_br_b-pattern_tl_b)/pixel_ratio_to;v_pos_a=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,fromScale*display_size_a,tileRatio,a_pos);v_pos_b=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,toScale*display_size_b,tileRatio,a_pos);v_pos=(gl_Position.xy/gl_Position.w+1.0)/2.0*u_world;}`),Gd=vr(`uniform vec2 u_texsize;uniform float u_fade;uniform sampler2D u_image;varying vec2 v_pos_a;varying vec2 v_pos_b; +#pragma mapbox: define lowp float opacity +#pragma mapbox: define lowp vec4 pattern_from +#pragma mapbox: define lowp vec4 pattern_to +void main() { +#pragma mapbox: initialize lowp float opacity +#pragma mapbox: initialize mediump vec4 pattern_from +#pragma mapbox: initialize mediump vec4 pattern_to +vec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;vec2 imagecoord=mod(v_pos_a,1.0);vec2 pos=mix(pattern_tl_a/u_texsize,pattern_br_a/u_texsize,imagecoord);vec4 color1=texture2D(u_image,pos);vec2 imagecoord_b=mod(v_pos_b,1.0);vec2 pos2=mix(pattern_tl_b/u_texsize,pattern_br_b/u_texsize,imagecoord_b);vec4 color2=texture2D(u_image,pos2);gl_FragColor=mix(color1,color2,u_fade)*opacity; +#ifdef OVERDRAW_INSPECTOR +gl_FragColor=vec4(1.0); +#endif +}`,`uniform mat4 u_matrix;uniform vec2 u_pixel_coord_upper;uniform vec2 u_pixel_coord_lower;uniform vec3 u_scale;attribute vec2 a_pos;varying vec2 v_pos_a;varying vec2 v_pos_b; +#pragma mapbox: define lowp float opacity +#pragma mapbox: define lowp vec4 pattern_from +#pragma mapbox: define lowp vec4 pattern_to +#pragma mapbox: define lowp float pixel_ratio_from +#pragma mapbox: define lowp float pixel_ratio_to +void main() { +#pragma mapbox: initialize lowp float opacity +#pragma mapbox: initialize mediump vec4 pattern_from +#pragma mapbox: initialize mediump vec4 pattern_to +#pragma mapbox: initialize lowp float pixel_ratio_from +#pragma mapbox: initialize lowp float pixel_ratio_to +vec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;float tileZoomRatio=u_scale.x;float fromScale=u_scale.y;float toScale=u_scale.z;vec2 display_size_a=(pattern_br_a-pattern_tl_a)/pixel_ratio_from;vec2 display_size_b=(pattern_br_b-pattern_tl_b)/pixel_ratio_to;gl_Position=u_matrix*vec4(a_pos,0,1);v_pos_a=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,fromScale*display_size_a,tileZoomRatio,a_pos);v_pos_b=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,toScale*display_size_b,tileZoomRatio,a_pos);}`),q=vr(`varying vec4 v_color;void main() {gl_FragColor=v_color; +#ifdef OVERDRAW_INSPECTOR +gl_FragColor=vec4(1.0); +#endif +}`,`uniform mat4 u_matrix;uniform vec3 u_lightcolor;uniform lowp vec3 u_lightpos;uniform lowp float u_lightintensity;uniform float u_vertical_gradient;uniform lowp float u_opacity;attribute vec2 a_pos;attribute vec4 a_normal_ed;varying vec4 v_color; +#pragma mapbox: define highp float base +#pragma mapbox: define highp float height +#pragma mapbox: define highp vec4 color +void main() { +#pragma mapbox: initialize highp float base +#pragma mapbox: initialize highp float height +#pragma mapbox: initialize highp vec4 color +vec3 normal=a_normal_ed.xyz;base=max(0.0,base);height=max(0.0,height);float t=mod(normal.x,2.0);gl_Position=u_matrix*vec4(a_pos,t > 0.0 ? height : base,1);float colorvalue=color.r*0.2126+color.g*0.7152+color.b*0.0722;v_color=vec4(0.0,0.0,0.0,1.0);vec4 ambientlight=vec4(0.03,0.03,0.03,1.0);color+=ambientlight;float directional=clamp(dot(normal/16384.0,u_lightpos),0.0,1.0);directional=mix((1.0-u_lightintensity),max((1.0-colorvalue+u_lightintensity),1.0),directional);if (normal.y !=0.0) {directional*=((1.0-u_vertical_gradient)+(u_vertical_gradient*clamp((t+base)*pow(height/150.0,0.5),mix(0.7,0.98,1.0-u_lightintensity),1.0)));}v_color.r+=clamp(color.r*directional*u_lightcolor.r,mix(0.0,0.3,1.0-u_lightcolor.r),1.0);v_color.g+=clamp(color.g*directional*u_lightcolor.g,mix(0.0,0.3,1.0-u_lightcolor.g),1.0);v_color.b+=clamp(color.b*directional*u_lightcolor.b,mix(0.0,0.3,1.0-u_lightcolor.b),1.0);v_color*=u_opacity;}`),oe=vr(`uniform vec2 u_texsize;uniform float u_fade;uniform sampler2D u_image;varying vec2 v_pos_a;varying vec2 v_pos_b;varying vec4 v_lighting; +#pragma mapbox: define lowp float base +#pragma mapbox: define lowp float height +#pragma mapbox: define lowp vec4 pattern_from +#pragma mapbox: define lowp vec4 pattern_to +#pragma mapbox: define lowp float pixel_ratio_from +#pragma mapbox: define lowp float pixel_ratio_to +void main() { +#pragma mapbox: initialize lowp float base +#pragma mapbox: initialize lowp float height +#pragma mapbox: initialize mediump vec4 pattern_from +#pragma mapbox: initialize mediump vec4 pattern_to +#pragma mapbox: initialize lowp float pixel_ratio_from +#pragma mapbox: initialize lowp float pixel_ratio_to +vec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;vec2 imagecoord=mod(v_pos_a,1.0);vec2 pos=mix(pattern_tl_a/u_texsize,pattern_br_a/u_texsize,imagecoord);vec4 color1=texture2D(u_image,pos);vec2 imagecoord_b=mod(v_pos_b,1.0);vec2 pos2=mix(pattern_tl_b/u_texsize,pattern_br_b/u_texsize,imagecoord_b);vec4 color2=texture2D(u_image,pos2);vec4 mixedColor=mix(color1,color2,u_fade);gl_FragColor=mixedColor*v_lighting; +#ifdef OVERDRAW_INSPECTOR +gl_FragColor=vec4(1.0); +#endif +}`,`uniform mat4 u_matrix;uniform vec2 u_pixel_coord_upper;uniform vec2 u_pixel_coord_lower;uniform float u_height_factor;uniform vec3 u_scale;uniform float u_vertical_gradient;uniform lowp float u_opacity;uniform vec3 u_lightcolor;uniform lowp vec3 u_lightpos;uniform lowp float u_lightintensity;attribute vec2 a_pos;attribute vec4 a_normal_ed;varying vec2 v_pos_a;varying vec2 v_pos_b;varying vec4 v_lighting; +#pragma mapbox: define lowp float base +#pragma mapbox: define lowp float height +#pragma mapbox: define lowp vec4 pattern_from +#pragma mapbox: define lowp vec4 pattern_to +#pragma mapbox: define lowp float pixel_ratio_from +#pragma mapbox: define lowp float pixel_ratio_to +void main() { +#pragma mapbox: initialize lowp float base +#pragma mapbox: initialize lowp float height +#pragma mapbox: initialize mediump vec4 pattern_from +#pragma mapbox: initialize mediump vec4 pattern_to +#pragma mapbox: initialize lowp float pixel_ratio_from +#pragma mapbox: initialize lowp float pixel_ratio_to +vec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;float tileRatio=u_scale.x;float fromScale=u_scale.y;float toScale=u_scale.z;vec3 normal=a_normal_ed.xyz;float edgedistance=a_normal_ed.w;vec2 display_size_a=(pattern_br_a-pattern_tl_a)/pixel_ratio_from;vec2 display_size_b=(pattern_br_b-pattern_tl_b)/pixel_ratio_to;base=max(0.0,base);height=max(0.0,height);float t=mod(normal.x,2.0);float z=t > 0.0 ? height : base;gl_Position=u_matrix*vec4(a_pos,z,1);vec2 pos=normal.x==1.0 && normal.y==0.0 && normal.z==16384.0 +? a_pos +: vec2(edgedistance,z*u_height_factor);v_pos_a=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,fromScale*display_size_a,tileRatio,pos);v_pos_b=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,toScale*display_size_b,tileRatio,pos);v_lighting=vec4(0.0,0.0,0.0,1.0);float directional=clamp(dot(normal/16383.0,u_lightpos),0.0,1.0);directional=mix((1.0-u_lightintensity),max((0.5+u_lightintensity),1.0),directional);if (normal.y !=0.0) {directional*=((1.0-u_vertical_gradient)+(u_vertical_gradient*clamp((t+base)*pow(height/150.0,0.5),mix(0.7,0.98,1.0-u_lightintensity),1.0)));}v_lighting.rgb+=clamp(directional*u_lightcolor,mix(vec3(0.0),vec3(0.3),1.0-u_lightcolor),vec3(1.0));v_lighting*=u_opacity;}`),pe=vr(`#ifdef GL_ES +precision highp float; +#endif +uniform sampler2D u_image;varying vec2 v_pos;uniform vec2 u_dimension;uniform float u_zoom;uniform vec4 u_unpack;float getElevation(vec2 coord,float bias) {vec4 data=texture2D(u_image,coord)*255.0;data.a=-1.0;return dot(data,u_unpack)/4.0;}void main() {vec2 epsilon=1.0/u_dimension;float a=getElevation(v_pos+vec2(-epsilon.x,-epsilon.y),0.0);float b=getElevation(v_pos+vec2(0,-epsilon.y),0.0);float c=getElevation(v_pos+vec2(epsilon.x,-epsilon.y),0.0);float d=getElevation(v_pos+vec2(-epsilon.x,0),0.0);float e=getElevation(v_pos,0.0);float f=getElevation(v_pos+vec2(epsilon.x,0),0.0);float g=getElevation(v_pos+vec2(-epsilon.x,epsilon.y),0.0);float h=getElevation(v_pos+vec2(0,epsilon.y),0.0);float i=getElevation(v_pos+vec2(epsilon.x,epsilon.y),0.0);float exaggerationFactor=u_zoom < 2.0 ? 0.4 : u_zoom < 4.5 ? 0.35 : 0.3;float exaggeration=u_zoom < 15.0 ? (u_zoom-15.0)*exaggerationFactor : 0.0;vec2 deriv=vec2((c+f+f+i)-(a+d+d+g),(g+h+h+i)-(a+b+b+c))/pow(2.0,exaggeration+(19.2562-u_zoom));gl_FragColor=clamp(vec4(deriv.x/2.0+0.5,deriv.y/2.0+0.5,1.0,1.0),0.0,1.0); +#ifdef OVERDRAW_INSPECTOR +gl_FragColor=vec4(1.0); +#endif +}`,"uniform mat4 u_matrix;uniform vec2 u_dimension;attribute vec2 a_pos;attribute vec2 a_texture_pos;varying vec2 v_pos;void main() {gl_Position=u_matrix*vec4(a_pos,0,1);highp vec2 epsilon=1.0/u_dimension;float scale=(u_dimension.x-2.0)/u_dimension.x;v_pos=(a_texture_pos/8192.0)*scale+epsilon;}"),be=vr(`uniform sampler2D u_image;varying vec2 v_pos;uniform vec2 u_latrange;uniform vec2 u_light;uniform vec4 u_shadow;uniform vec4 u_highlight;uniform vec4 u_accent; +#define PI 3.141592653589793 +void main() {vec4 pixel=texture2D(u_image,v_pos);vec2 deriv=((pixel.rg*2.0)-1.0);float scaleFactor=cos(radians((u_latrange[0]-u_latrange[1])*(1.0-v_pos.y)+u_latrange[1]));float slope=atan(1.25*length(deriv)/scaleFactor);float aspect=deriv.x !=0.0 ? atan(deriv.y,-deriv.x) : PI/2.0*(deriv.y > 0.0 ? 1.0 :-1.0);float intensity=u_light.x;float azimuth=u_light.y+PI;float base=1.875-intensity*1.75;float maxValue=0.5*PI;float scaledSlope=intensity !=0.5 ? ((pow(base,slope)-1.0)/(pow(base,maxValue)-1.0))*maxValue : slope;float accent=cos(scaledSlope);vec4 accent_color=(1.0-accent)*u_accent*clamp(intensity*2.0,0.0,1.0);float shade=abs(mod((aspect+azimuth)/PI+0.5,2.0)-1.0);vec4 shade_color=mix(u_shadow,u_highlight,shade)*sin(scaledSlope)*clamp(intensity*2.0,0.0,1.0);gl_FragColor=accent_color*(1.0-shade_color.a)+shade_color; +#ifdef OVERDRAW_INSPECTOR +gl_FragColor=vec4(1.0); +#endif +}`,"uniform mat4 u_matrix;attribute vec2 a_pos;attribute vec2 a_texture_pos;varying vec2 v_pos;void main() {gl_Position=u_matrix*vec4(a_pos,0,1);v_pos=a_texture_pos/8192.0;}"),He=vr(`uniform lowp float u_device_pixel_ratio;varying vec2 v_width2;varying vec2 v_normal;varying float v_gamma_scale; +#pragma mapbox: define highp vec4 color +#pragma mapbox: define lowp float blur +#pragma mapbox: define lowp float opacity +void main() { +#pragma mapbox: initialize highp vec4 color +#pragma mapbox: initialize lowp float blur +#pragma mapbox: initialize lowp float opacity +float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);gl_FragColor=color*(alpha*opacity); +#ifdef OVERDRAW_INSPECTOR +gl_FragColor=vec4(1.0); +#endif +}`,` +#define scale 0.015873016 +attribute vec2 a_pos_normal;attribute vec4 a_data;uniform mat4 u_matrix;uniform mediump float u_ratio;uniform vec2 u_units_to_pixels;uniform lowp float u_device_pixel_ratio;varying vec2 v_normal;varying vec2 v_width2;varying float v_gamma_scale;varying highp float v_linesofar; +#pragma mapbox: define highp vec4 color +#pragma mapbox: define lowp float blur +#pragma mapbox: define lowp float opacity +#pragma mapbox: define mediump float gapwidth +#pragma mapbox: define lowp float offset +#pragma mapbox: define mediump float width +void main() { +#pragma mapbox: initialize highp vec4 color +#pragma mapbox: initialize lowp float blur +#pragma mapbox: initialize lowp float opacity +#pragma mapbox: initialize mediump float gapwidth +#pragma mapbox: initialize lowp float offset +#pragma mapbox: initialize mediump float width +float ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=a_data.xy-128.0;float a_direction=mod(a_data.z,4.0)-1.0;v_linesofar=(floor(a_data.z/4.0)+a_data.w*64.0)*2.0;vec2 pos=floor(a_pos_normal*0.5);mediump vec2 normal=a_pos_normal-2.0*pos;normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);vec4 projected_extrude=u_matrix*vec4(dist/u_ratio,0.0,0.0);gl_Position=u_matrix*vec4(pos+offset2/u_ratio,0.0,1.0)+projected_extrude;float extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length(projected_extrude.xy/gl_Position.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;v_width2=vec2(outset,inset);}`),We=vr(`uniform lowp float u_device_pixel_ratio;uniform sampler2D u_image;varying vec2 v_width2;varying vec2 v_normal;varying float v_gamma_scale;varying highp vec2 v_uv; +#pragma mapbox: define lowp float blur +#pragma mapbox: define lowp float opacity +void main() { +#pragma mapbox: initialize lowp float blur +#pragma mapbox: initialize lowp float opacity +float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);vec4 color=texture2D(u_image,v_uv);gl_FragColor=color*(alpha*opacity); +#ifdef OVERDRAW_INSPECTOR +gl_FragColor=vec4(1.0); +#endif +}`,` +#define scale 0.015873016 +attribute vec2 a_pos_normal;attribute vec4 a_data;attribute float a_uv_x;attribute float a_split_index;uniform mat4 u_matrix;uniform mediump float u_ratio;uniform lowp float u_device_pixel_ratio;uniform vec2 u_units_to_pixels;uniform float u_image_height;varying vec2 v_normal;varying vec2 v_width2;varying float v_gamma_scale;varying highp vec2 v_uv; +#pragma mapbox: define lowp float blur +#pragma mapbox: define lowp float opacity +#pragma mapbox: define mediump float gapwidth +#pragma mapbox: define lowp float offset +#pragma mapbox: define mediump float width +void main() { +#pragma mapbox: initialize lowp float blur +#pragma mapbox: initialize lowp float opacity +#pragma mapbox: initialize mediump float gapwidth +#pragma mapbox: initialize lowp float offset +#pragma mapbox: initialize mediump float width +float ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=a_data.xy-128.0;float a_direction=mod(a_data.z,4.0)-1.0;highp float texel_height=1.0/u_image_height;highp float half_texel_height=0.5*texel_height;v_uv=vec2(a_uv_x,a_split_index*texel_height-half_texel_height);vec2 pos=floor(a_pos_normal*0.5);mediump vec2 normal=a_pos_normal-2.0*pos;normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);vec4 projected_extrude=u_matrix*vec4(dist/u_ratio,0.0,0.0);gl_Position=u_matrix*vec4(pos+offset2/u_ratio,0.0,1.0)+projected_extrude;float extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length(projected_extrude.xy/gl_Position.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;v_width2=vec2(outset,inset);}`),ot=vr(`uniform lowp float u_device_pixel_ratio;uniform vec2 u_texsize;uniform float u_fade;uniform mediump vec3 u_scale;uniform sampler2D u_image;varying vec2 v_normal;varying vec2 v_width2;varying float v_linesofar;varying float v_gamma_scale;varying float v_width; +#pragma mapbox: define lowp vec4 pattern_from +#pragma mapbox: define lowp vec4 pattern_to +#pragma mapbox: define lowp float pixel_ratio_from +#pragma mapbox: define lowp float pixel_ratio_to +#pragma mapbox: define lowp float blur +#pragma mapbox: define lowp float opacity +void main() { +#pragma mapbox: initialize mediump vec4 pattern_from +#pragma mapbox: initialize mediump vec4 pattern_to +#pragma mapbox: initialize lowp float pixel_ratio_from +#pragma mapbox: initialize lowp float pixel_ratio_to +#pragma mapbox: initialize lowp float blur +#pragma mapbox: initialize lowp float opacity +vec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;float tileZoomRatio=u_scale.x;float fromScale=u_scale.y;float toScale=u_scale.z;vec2 display_size_a=(pattern_br_a-pattern_tl_a)/pixel_ratio_from;vec2 display_size_b=(pattern_br_b-pattern_tl_b)/pixel_ratio_to;vec2 pattern_size_a=vec2(display_size_a.x*fromScale/tileZoomRatio,display_size_a.y);vec2 pattern_size_b=vec2(display_size_b.x*toScale/tileZoomRatio,display_size_b.y);float aspect_a=display_size_a.y/v_width;float aspect_b=display_size_b.y/v_width;float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);float x_a=mod(v_linesofar/pattern_size_a.x*aspect_a,1.0);float x_b=mod(v_linesofar/pattern_size_b.x*aspect_b,1.0);float y=0.5*v_normal.y+0.5;vec2 texel_size=1.0/u_texsize;vec2 pos_a=mix(pattern_tl_a*texel_size-texel_size,pattern_br_a*texel_size+texel_size,vec2(x_a,y));vec2 pos_b=mix(pattern_tl_b*texel_size-texel_size,pattern_br_b*texel_size+texel_size,vec2(x_b,y));vec4 color=mix(texture2D(u_image,pos_a),texture2D(u_image,pos_b),u_fade);gl_FragColor=color*alpha*opacity; +#ifdef OVERDRAW_INSPECTOR +gl_FragColor=vec4(1.0); +#endif +}`,` +#define scale 0.015873016 +#define LINE_DISTANCE_SCALE 2.0 +attribute vec2 a_pos_normal;attribute vec4 a_data;uniform mat4 u_matrix;uniform vec2 u_units_to_pixels;uniform mediump float u_ratio;uniform lowp float u_device_pixel_ratio;varying vec2 v_normal;varying vec2 v_width2;varying float v_linesofar;varying float v_gamma_scale;varying float v_width; +#pragma mapbox: define lowp float blur +#pragma mapbox: define lowp float opacity +#pragma mapbox: define lowp float offset +#pragma mapbox: define mediump float gapwidth +#pragma mapbox: define mediump float width +#pragma mapbox: define lowp float floorwidth +#pragma mapbox: define lowp vec4 pattern_from +#pragma mapbox: define lowp vec4 pattern_to +#pragma mapbox: define lowp float pixel_ratio_from +#pragma mapbox: define lowp float pixel_ratio_to +void main() { +#pragma mapbox: initialize lowp float blur +#pragma mapbox: initialize lowp float opacity +#pragma mapbox: initialize lowp float offset +#pragma mapbox: initialize mediump float gapwidth +#pragma mapbox: initialize mediump float width +#pragma mapbox: initialize lowp float floorwidth +#pragma mapbox: initialize mediump vec4 pattern_from +#pragma mapbox: initialize mediump vec4 pattern_to +#pragma mapbox: initialize lowp float pixel_ratio_from +#pragma mapbox: initialize lowp float pixel_ratio_to +float ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=a_data.xy-128.0;float a_direction=mod(a_data.z,4.0)-1.0;float a_linesofar=(floor(a_data.z/4.0)+a_data.w*64.0)*LINE_DISTANCE_SCALE;vec2 pos=floor(a_pos_normal*0.5);mediump vec2 normal=a_pos_normal-2.0*pos;normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);vec4 projected_extrude=u_matrix*vec4(dist/u_ratio,0.0,0.0);gl_Position=u_matrix*vec4(pos+offset2/u_ratio,0.0,1.0)+projected_extrude;float extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length(projected_extrude.xy/gl_Position.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;v_linesofar=a_linesofar;v_width2=vec2(outset,inset);v_width=floorwidth;}`),rr=vr(`uniform lowp float u_device_pixel_ratio;uniform sampler2D u_image;uniform float u_sdfgamma;uniform float u_mix;varying vec2 v_normal;varying vec2 v_width2;varying vec2 v_tex_a;varying vec2 v_tex_b;varying float v_gamma_scale; +#pragma mapbox: define highp vec4 color +#pragma mapbox: define lowp float blur +#pragma mapbox: define lowp float opacity +#pragma mapbox: define mediump float width +#pragma mapbox: define lowp float floorwidth +void main() { +#pragma mapbox: initialize highp vec4 color +#pragma mapbox: initialize lowp float blur +#pragma mapbox: initialize lowp float opacity +#pragma mapbox: initialize mediump float width +#pragma mapbox: initialize lowp float floorwidth +float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);float sdfdist_a=texture2D(u_image,v_tex_a).a;float sdfdist_b=texture2D(u_image,v_tex_b).a;float sdfdist=mix(sdfdist_a,sdfdist_b,u_mix);alpha*=smoothstep(0.5-u_sdfgamma/floorwidth,0.5+u_sdfgamma/floorwidth,sdfdist);gl_FragColor=color*(alpha*opacity); +#ifdef OVERDRAW_INSPECTOR +gl_FragColor=vec4(1.0); +#endif +}`,` +#define scale 0.015873016 +#define LINE_DISTANCE_SCALE 2.0 +attribute vec2 a_pos_normal;attribute vec4 a_data;uniform mat4 u_matrix;uniform mediump float u_ratio;uniform lowp float u_device_pixel_ratio;uniform vec2 u_patternscale_a;uniform float u_tex_y_a;uniform vec2 u_patternscale_b;uniform float u_tex_y_b;uniform vec2 u_units_to_pixels;varying vec2 v_normal;varying vec2 v_width2;varying vec2 v_tex_a;varying vec2 v_tex_b;varying float v_gamma_scale; +#pragma mapbox: define highp vec4 color +#pragma mapbox: define lowp float blur +#pragma mapbox: define lowp float opacity +#pragma mapbox: define mediump float gapwidth +#pragma mapbox: define lowp float offset +#pragma mapbox: define mediump float width +#pragma mapbox: define lowp float floorwidth +void main() { +#pragma mapbox: initialize highp vec4 color +#pragma mapbox: initialize lowp float blur +#pragma mapbox: initialize lowp float opacity +#pragma mapbox: initialize mediump float gapwidth +#pragma mapbox: initialize lowp float offset +#pragma mapbox: initialize mediump float width +#pragma mapbox: initialize lowp float floorwidth +float ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=a_data.xy-128.0;float a_direction=mod(a_data.z,4.0)-1.0;float a_linesofar=(floor(a_data.z/4.0)+a_data.w*64.0)*LINE_DISTANCE_SCALE;vec2 pos=floor(a_pos_normal*0.5);mediump vec2 normal=a_pos_normal-2.0*pos;normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);vec4 projected_extrude=u_matrix*vec4(dist/u_ratio,0.0,0.0);gl_Position=u_matrix*vec4(pos+offset2/u_ratio,0.0,1.0)+projected_extrude;float extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length(projected_extrude.xy/gl_Position.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;v_tex_a=vec2(a_linesofar*u_patternscale_a.x/floorwidth,normal.y*u_patternscale_a.y+u_tex_y_a);v_tex_b=vec2(a_linesofar*u_patternscale_b.x/floorwidth,normal.y*u_patternscale_b.y+u_tex_y_b);v_width2=vec2(outset,inset);}`),Ut=vr(`uniform float u_fade_t;uniform float u_opacity;uniform sampler2D u_image0;uniform sampler2D u_image1;varying vec2 v_pos0;varying vec2 v_pos1;uniform float u_brightness_low;uniform float u_brightness_high;uniform float u_saturation_factor;uniform float u_contrast_factor;uniform vec3 u_spin_weights;void main() {vec4 color0=texture2D(u_image0,v_pos0);vec4 color1=texture2D(u_image1,v_pos1);if (color0.a > 0.0) {color0.rgb=color0.rgb/color0.a;}if (color1.a > 0.0) {color1.rgb=color1.rgb/color1.a;}vec4 color=mix(color0,color1,u_fade_t);color.a*=u_opacity;vec3 rgb=color.rgb;rgb=vec3(dot(rgb,u_spin_weights.xyz),dot(rgb,u_spin_weights.zxy),dot(rgb,u_spin_weights.yzx));float average=(color.r+color.g+color.b)/3.0;rgb+=(average-rgb)*u_saturation_factor;rgb=(rgb-0.5)*u_contrast_factor+0.5;vec3 u_high_vec=vec3(u_brightness_low,u_brightness_low,u_brightness_low);vec3 u_low_vec=vec3(u_brightness_high,u_brightness_high,u_brightness_high);gl_FragColor=vec4(mix(u_high_vec,u_low_vec,rgb)*color.a,color.a); +#ifdef OVERDRAW_INSPECTOR +gl_FragColor=vec4(1.0); +#endif +}`,"uniform mat4 u_matrix;uniform vec2 u_tl_parent;uniform float u_scale_parent;uniform float u_buffer_scale;attribute vec2 a_pos;attribute vec2 a_texture_pos;varying vec2 v_pos0;varying vec2 v_pos1;void main() {gl_Position=u_matrix*vec4(a_pos,0,1);v_pos0=(((a_texture_pos/8192.0)-0.5)/u_buffer_scale )+0.5;v_pos1=(v_pos0*u_scale_parent)+u_tl_parent;}"),cr=vr(`uniform sampler2D u_texture;varying vec2 v_tex;varying float v_fade_opacity; +#pragma mapbox: define lowp float opacity +void main() { +#pragma mapbox: initialize lowp float opacity +lowp float alpha=opacity*v_fade_opacity;gl_FragColor=texture2D(u_texture,v_tex)*alpha; +#ifdef OVERDRAW_INSPECTOR +gl_FragColor=vec4(1.0); +#endif +}`,`const float PI=3.141592653589793;attribute vec4 a_pos_offset;attribute vec4 a_data;attribute vec4 a_pixeloffset;attribute vec3 a_projected_pos;attribute float a_fade_opacity;uniform bool u_is_size_zoom_constant;uniform bool u_is_size_feature_constant;uniform highp float u_size_t;uniform highp float u_size;uniform highp float u_camera_to_center_distance;uniform highp float u_pitch;uniform bool u_rotate_symbol;uniform highp float u_aspect_ratio;uniform float u_fade_change;uniform mat4 u_matrix;uniform mat4 u_label_plane_matrix;uniform mat4 u_coord_matrix;uniform bool u_is_text;uniform bool u_pitch_with_map;uniform vec2 u_texsize;varying vec2 v_tex;varying float v_fade_opacity; +#pragma mapbox: define lowp float opacity +void main() { +#pragma mapbox: initialize lowp float opacity +vec2 a_pos=a_pos_offset.xy;vec2 a_offset=a_pos_offset.zw;vec2 a_tex=a_data.xy;vec2 a_size=a_data.zw;float a_size_min=floor(a_size[0]*0.5);vec2 a_pxoffset=a_pixeloffset.xy;vec2 a_minFontScale=a_pixeloffset.zw/256.0;highp float segment_angle=-a_projected_pos[2];float size;if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {size=mix(a_size_min,a_size[1],u_size_t)/128.0;} else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {size=a_size_min/128.0;} else {size=u_size;}vec4 projectedPoint=u_matrix*vec4(a_pos,0,1);highp float camera_to_anchor_distance=projectedPoint.w;highp float distance_ratio=u_pitch_with_map ? +camera_to_anchor_distance/u_camera_to_center_distance : +u_camera_to_center_distance/camera_to_anchor_distance;highp float perspective_ratio=clamp(0.5+0.5*distance_ratio,0.0,4.0);size*=perspective_ratio;float fontScale=u_is_text ? size/24.0 : size;highp float symbol_rotation=0.0;if (u_rotate_symbol) {vec4 offsetProjectedPoint=u_matrix*vec4(a_pos+vec2(1,0),0,1);vec2 a=projectedPoint.xy/projectedPoint.w;vec2 b=offsetProjectedPoint.xy/offsetProjectedPoint.w;symbol_rotation=atan((b.y-a.y)/u_aspect_ratio,b.x-a.x);}highp float angle_sin=sin(segment_angle+symbol_rotation);highp float angle_cos=cos(segment_angle+symbol_rotation);mat2 rotation_matrix=mat2(angle_cos,-1.0*angle_sin,angle_sin,angle_cos);vec4 projected_pos=u_label_plane_matrix*vec4(a_projected_pos.xy,0.0,1.0);gl_Position=u_coord_matrix*vec4(projected_pos.xy/projected_pos.w+rotation_matrix*(a_offset/32.0*max(a_minFontScale,fontScale)+a_pxoffset/16.0),0.0,1.0);v_tex=a_tex/u_texsize;vec2 fade_opacity=unpack_opacity(a_fade_opacity);float fade_change=fade_opacity[1] > 0.5 ? u_fade_change :-u_fade_change;v_fade_opacity=max(0.0,min(1.0,fade_opacity[0]+fade_change));}`),Fr=vr(`#define SDF_PX 8.0 +uniform bool u_is_halo;uniform sampler2D u_texture;uniform highp float u_gamma_scale;uniform lowp float u_device_pixel_ratio;uniform bool u_is_text;varying vec2 v_data0;varying vec3 v_data1; +#pragma mapbox: define highp vec4 fill_color +#pragma mapbox: define highp vec4 halo_color +#pragma mapbox: define lowp float opacity +#pragma mapbox: define lowp float halo_width +#pragma mapbox: define lowp float halo_blur +void main() { +#pragma mapbox: initialize highp vec4 fill_color +#pragma mapbox: initialize highp vec4 halo_color +#pragma mapbox: initialize lowp float opacity +#pragma mapbox: initialize lowp float halo_width +#pragma mapbox: initialize lowp float halo_blur +float EDGE_GAMMA=0.105/u_device_pixel_ratio;vec2 tex=v_data0.xy;float gamma_scale=v_data1.x;float size=v_data1.y;float fade_opacity=v_data1[2];float fontScale=u_is_text ? size/24.0 : size;lowp vec4 color=fill_color;highp float gamma=EDGE_GAMMA/(fontScale*u_gamma_scale);lowp float buff=(256.0-64.0)/256.0;if (u_is_halo) {color=halo_color;gamma=(halo_blur*1.19/SDF_PX+EDGE_GAMMA)/(fontScale*u_gamma_scale);buff=(6.0-halo_width/fontScale)/SDF_PX;}lowp float dist=texture2D(u_texture,tex).a;highp float gamma_scaled=gamma*gamma_scale;highp float alpha=smoothstep(buff-gamma_scaled,buff+gamma_scaled,dist);gl_FragColor=color*(alpha*opacity*fade_opacity); +#ifdef OVERDRAW_INSPECTOR +gl_FragColor=vec4(1.0); +#endif +}`,`const float PI=3.141592653589793;attribute vec4 a_pos_offset;attribute vec4 a_data;attribute vec4 a_pixeloffset;attribute vec3 a_projected_pos;attribute float a_fade_opacity;uniform bool u_is_size_zoom_constant;uniform bool u_is_size_feature_constant;uniform highp float u_size_t;uniform highp float u_size;uniform mat4 u_matrix;uniform mat4 u_label_plane_matrix;uniform mat4 u_coord_matrix;uniform bool u_is_text;uniform bool u_pitch_with_map;uniform highp float u_pitch;uniform bool u_rotate_symbol;uniform highp float u_aspect_ratio;uniform highp float u_camera_to_center_distance;uniform float u_fade_change;uniform vec2 u_texsize;varying vec2 v_data0;varying vec3 v_data1; +#pragma mapbox: define highp vec4 fill_color +#pragma mapbox: define highp vec4 halo_color +#pragma mapbox: define lowp float opacity +#pragma mapbox: define lowp float halo_width +#pragma mapbox: define lowp float halo_blur +void main() { +#pragma mapbox: initialize highp vec4 fill_color +#pragma mapbox: initialize highp vec4 halo_color +#pragma mapbox: initialize lowp float opacity +#pragma mapbox: initialize lowp float halo_width +#pragma mapbox: initialize lowp float halo_blur +vec2 a_pos=a_pos_offset.xy;vec2 a_offset=a_pos_offset.zw;vec2 a_tex=a_data.xy;vec2 a_size=a_data.zw;float a_size_min=floor(a_size[0]*0.5);vec2 a_pxoffset=a_pixeloffset.xy;highp float segment_angle=-a_projected_pos[2];float size;if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {size=mix(a_size_min,a_size[1],u_size_t)/128.0;} else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {size=a_size_min/128.0;} else {size=u_size;}vec4 projectedPoint=u_matrix*vec4(a_pos,0,1);highp float camera_to_anchor_distance=projectedPoint.w;highp float distance_ratio=u_pitch_with_map ? +camera_to_anchor_distance/u_camera_to_center_distance : +u_camera_to_center_distance/camera_to_anchor_distance;highp float perspective_ratio=clamp(0.5+0.5*distance_ratio,0.0,4.0);size*=perspective_ratio;float fontScale=u_is_text ? size/24.0 : size;highp float symbol_rotation=0.0;if (u_rotate_symbol) {vec4 offsetProjectedPoint=u_matrix*vec4(a_pos+vec2(1,0),0,1);vec2 a=projectedPoint.xy/projectedPoint.w;vec2 b=offsetProjectedPoint.xy/offsetProjectedPoint.w;symbol_rotation=atan((b.y-a.y)/u_aspect_ratio,b.x-a.x);}highp float angle_sin=sin(segment_angle+symbol_rotation);highp float angle_cos=cos(segment_angle+symbol_rotation);mat2 rotation_matrix=mat2(angle_cos,-1.0*angle_sin,angle_sin,angle_cos);vec4 projected_pos=u_label_plane_matrix*vec4(a_projected_pos.xy,0.0,1.0);gl_Position=u_coord_matrix*vec4(projected_pos.xy/projected_pos.w+rotation_matrix*(a_offset/32.0*fontScale+a_pxoffset),0.0,1.0);float gamma_scale=gl_Position.w;vec2 fade_opacity=unpack_opacity(a_fade_opacity);float fade_change=fade_opacity[1] > 0.5 ? u_fade_change :-u_fade_change;float interpolated_fade_opacity=max(0.0,min(1.0,fade_opacity[0]+fade_change));v_data0=a_tex/u_texsize;v_data1=vec3(gamma_scale,size,interpolated_fade_opacity);}`),li=vr(`#define SDF_PX 8.0 +#define SDF 1.0 +#define ICON 0.0 +uniform bool u_is_halo;uniform sampler2D u_texture;uniform sampler2D u_texture_icon;uniform highp float u_gamma_scale;uniform lowp float u_device_pixel_ratio;varying vec4 v_data0;varying vec4 v_data1; +#pragma mapbox: define highp vec4 fill_color +#pragma mapbox: define highp vec4 halo_color +#pragma mapbox: define lowp float opacity +#pragma mapbox: define lowp float halo_width +#pragma mapbox: define lowp float halo_blur +void main() { +#pragma mapbox: initialize highp vec4 fill_color +#pragma mapbox: initialize highp vec4 halo_color +#pragma mapbox: initialize lowp float opacity +#pragma mapbox: initialize lowp float halo_width +#pragma mapbox: initialize lowp float halo_blur +float fade_opacity=v_data1[2];if (v_data1.w==ICON) {vec2 tex_icon=v_data0.zw;lowp float alpha=opacity*fade_opacity;gl_FragColor=texture2D(u_texture_icon,tex_icon)*alpha; +#ifdef OVERDRAW_INSPECTOR +gl_FragColor=vec4(1.0); +#endif +return;}vec2 tex=v_data0.xy;float EDGE_GAMMA=0.105/u_device_pixel_ratio;float gamma_scale=v_data1.x;float size=v_data1.y;float fontScale=size/24.0;lowp vec4 color=fill_color;highp float gamma=EDGE_GAMMA/(fontScale*u_gamma_scale);lowp float buff=(256.0-64.0)/256.0;if (u_is_halo) {color=halo_color;gamma=(halo_blur*1.19/SDF_PX+EDGE_GAMMA)/(fontScale*u_gamma_scale);buff=(6.0-halo_width/fontScale)/SDF_PX;}lowp float dist=texture2D(u_texture,tex).a;highp float gamma_scaled=gamma*gamma_scale;highp float alpha=smoothstep(buff-gamma_scaled,buff+gamma_scaled,dist);gl_FragColor=color*(alpha*opacity*fade_opacity); +#ifdef OVERDRAW_INSPECTOR +gl_FragColor=vec4(1.0); +#endif +}`,`const float PI=3.141592653589793;attribute vec4 a_pos_offset;attribute vec4 a_data;attribute vec3 a_projected_pos;attribute float a_fade_opacity;uniform bool u_is_size_zoom_constant;uniform bool u_is_size_feature_constant;uniform highp float u_size_t;uniform highp float u_size;uniform mat4 u_matrix;uniform mat4 u_label_plane_matrix;uniform mat4 u_coord_matrix;uniform bool u_is_text;uniform bool u_pitch_with_map;uniform highp float u_pitch;uniform bool u_rotate_symbol;uniform highp float u_aspect_ratio;uniform highp float u_camera_to_center_distance;uniform float u_fade_change;uniform vec2 u_texsize;uniform vec2 u_texsize_icon;varying vec4 v_data0;varying vec4 v_data1; +#pragma mapbox: define highp vec4 fill_color +#pragma mapbox: define highp vec4 halo_color +#pragma mapbox: define lowp float opacity +#pragma mapbox: define lowp float halo_width +#pragma mapbox: define lowp float halo_blur +void main() { +#pragma mapbox: initialize highp vec4 fill_color +#pragma mapbox: initialize highp vec4 halo_color +#pragma mapbox: initialize lowp float opacity +#pragma mapbox: initialize lowp float halo_width +#pragma mapbox: initialize lowp float halo_blur +vec2 a_pos=a_pos_offset.xy;vec2 a_offset=a_pos_offset.zw;vec2 a_tex=a_data.xy;vec2 a_size=a_data.zw;float a_size_min=floor(a_size[0]*0.5);float is_sdf=a_size[0]-2.0*a_size_min;highp float segment_angle=-a_projected_pos[2];float size;if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {size=mix(a_size_min,a_size[1],u_size_t)/128.0;} else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {size=a_size_min/128.0;} else {size=u_size;}vec4 projectedPoint=u_matrix*vec4(a_pos,0,1);highp float camera_to_anchor_distance=projectedPoint.w;highp float distance_ratio=u_pitch_with_map ? +camera_to_anchor_distance/u_camera_to_center_distance : +u_camera_to_center_distance/camera_to_anchor_distance;highp float perspective_ratio=clamp(0.5+0.5*distance_ratio,0.0,4.0);size*=perspective_ratio;float fontScale=size/24.0;highp float symbol_rotation=0.0;if (u_rotate_symbol) {vec4 offsetProjectedPoint=u_matrix*vec4(a_pos+vec2(1,0),0,1);vec2 a=projectedPoint.xy/projectedPoint.w;vec2 b=offsetProjectedPoint.xy/offsetProjectedPoint.w;symbol_rotation=atan((b.y-a.y)/u_aspect_ratio,b.x-a.x);}highp float angle_sin=sin(segment_angle+symbol_rotation);highp float angle_cos=cos(segment_angle+symbol_rotation);mat2 rotation_matrix=mat2(angle_cos,-1.0*angle_sin,angle_sin,angle_cos);vec4 projected_pos=u_label_plane_matrix*vec4(a_projected_pos.xy,0.0,1.0);gl_Position=u_coord_matrix*vec4(projected_pos.xy/projected_pos.w+rotation_matrix*(a_offset/32.0*fontScale),0.0,1.0);float gamma_scale=gl_Position.w;vec2 fade_opacity=unpack_opacity(a_fade_opacity);float fade_change=fade_opacity[1] > 0.5 ? u_fade_change :-u_fade_change;float interpolated_fade_opacity=max(0.0,min(1.0,fade_opacity[0]+fade_change));v_data0.xy=a_tex/u_texsize;v_data0.zw=a_tex/u_texsize_icon;v_data1=vec4(gamma_scale,size,interpolated_fade_opacity,is_sdf);}`);function vr(w,M){var S=/#pragma mapbox: ([\w]+) ([\w]+) ([\w]+) ([\w]+)/g,L=M.match(/attribute ([\w]+) ([\w]+)/g),Y=w.match(/uniform ([\w]+) ([\w]+)([\s]*)([\w]*)/g),ie=M.match(/uniform ([\w]+) ([\w]+)([\s]*)([\w]*)/g),ae=ie?ie.concat(Y):Y,ge={};return{fragmentSource:w=w.replace(S,function(Pe,Ue,ct,ft,gt){return ge[gt]=!0,Ue==="define"?` +#ifndef HAS_UNIFORM_u_`+gt+` +varying `+ct+" "+ft+" "+gt+`; +#else +uniform `+ct+" "+ft+" u_"+gt+`; +#endif +`:` +#ifdef HAS_UNIFORM_u_`+gt+` + `+ct+" "+ft+" "+gt+" = u_"+gt+`; +#endif +`}),vertexSource:M=M.replace(S,function(Pe,Ue,ct,ft,gt){var ut=ft==="float"?"vec2":"vec4",Pt=gt.match(/color/)?"color":ut;return ge[gt]?Ue==="define"?` +#ifndef HAS_UNIFORM_u_`+gt+` +uniform lowp float u_`+gt+`_t; +attribute `+ct+" "+ut+" a_"+gt+`; +varying `+ct+" "+ft+" "+gt+`; +#else +uniform `+ct+" "+ft+" u_"+gt+`; +#endif +`:Pt==="vec4"?` +#ifndef HAS_UNIFORM_u_`+gt+` + `+gt+" = a_"+gt+`; +#else + `+ct+" "+ft+" "+gt+" = u_"+gt+`; +#endif +`:` +#ifndef HAS_UNIFORM_u_`+gt+` + `+gt+" = unpack_mix_"+Pt+"(a_"+gt+", u_"+gt+`_t); +#else + `+ct+" "+ft+" "+gt+" = u_"+gt+`; +#endif +`:Ue==="define"?` +#ifndef HAS_UNIFORM_u_`+gt+` +uniform lowp float u_`+gt+`_t; +attribute `+ct+" "+ut+" a_"+gt+`; +#else +uniform `+ct+" "+ft+" u_"+gt+`; +#endif +`:Pt==="vec4"?` +#ifndef HAS_UNIFORM_u_`+gt+` + `+ct+" "+ft+" "+gt+" = a_"+gt+`; +#else + `+ct+" "+ft+" "+gt+" = u_"+gt+`; +#endif +`:` +#ifndef HAS_UNIFORM_u_`+gt+` + `+ct+" "+ft+" "+gt+" = unpack_mix_"+Pt+"(a_"+gt+", u_"+gt+`_t); +#else + `+ct+" "+ft+" "+gt+" = u_"+gt+`; +#endif +`}),staticAttributes:L,staticUniforms:ae}}var Bi=Object.freeze({__proto__:null,prelude:Gh,background:Ec,backgroundPattern:Gf,circle:Wh,clippingMask:Hd,heatmap:Cp,heatmapTexture:Af,collisionBox:ia,collisionCircle:mh,debug:ms,fill:Ao,fillOutline:qh,fillOutlinePattern:us,fillPattern:Gd,fillExtrusion:q,fillExtrusionPattern:oe,hillshadePrepare:pe,hillshade:be,line:He,lineGradient:We,linePattern:ot,lineSDF:rr,raster:Ut,symbolIcon:cr,symbolSDF:Fr,symbolTextAndIcon:li}),gn=function(){this.boundProgram=null,this.boundLayoutVertexBuffer=null,this.boundPaintVertexBuffers=[],this.boundIndexBuffer=null,this.boundVertexOffset=null,this.boundDynamicVertexBuffer=null,this.vao=null};function gs(w){for(var M=[],S=0;S>16,ge>>16],u_pixel_coord_lower:[65535&ae,65535&ge]}}Mo.prototype.draw=function(w,M,S,L,Y,ie,ae,ge,Pe,Ue,ct,ft,gt,ut,Pt,Wt){var St,Zt=w.gl;if(!this.failedToCreate){for(var ir in w.program.set(this.program),w.setDepthMode(S),w.setStencilMode(L),w.setColorMode(Y),w.setCullFace(ie),this.fixedUniforms)this.fixedUniforms[ir].set(ae[ir]);ut&&ut.setUniforms(w,this.binderUniforms,ft,{zoom:gt});for(var dr=(St={},St[Zt.LINES]=2,St[Zt.TRIANGLES]=3,St[Zt.LINE_STRIP]=1,St)[M],kr=0,Lr=ct.get();kr0?1-1/(1.001-ae):-ae),u_contrast_factor:(ie=Y.paint.get("raster-contrast"),ie>0?1/(1-ie):1+ie),u_spin_weights:Os(Y.paint.get("raster-hue-rotate"))};var ie,ae};function Os(w){w*=Math.PI/180;var M=Math.sin(w),S=Math.cos(w);return[(2*S+1)/3,(-Math.sqrt(3)*M-S+1)/3,(Math.sqrt(3)*M-S+1)/3]}var gh,Ss=function(w,M,S,L,Y,ie,ae,ge,Pe,Ue){var ct=Y.transform;return{u_is_size_zoom_constant:+(w==="constant"||w==="source"),u_is_size_feature_constant:+(w==="constant"||w==="camera"),u_size_t:M?M.uSizeT:0,u_size:M?M.uSize:0,u_camera_to_center_distance:ct.cameraToCenterDistance,u_pitch:ct.pitch/360*2*Math.PI,u_rotate_symbol:+S,u_aspect_ratio:ct.width/ct.height,u_fade_change:Y.options.fadeDuration?Y.symbolFadeChange:1,u_matrix:ie,u_label_plane_matrix:ae,u_coord_matrix:ge,u_is_text:+Pe,u_pitch_with_map:+L,u_texsize:Ue,u_texture:0}},Ah=function(w,M,S,L,Y,ie,ae,ge,Pe,Ue,ct){var ft=Y.transform;return n.extend(Ss(w,M,S,L,Y,ie,ae,ge,Pe,Ue),{u_gamma_scale:L?Math.cos(ft._pitch)*ft.cameraToCenterDistance:1,u_device_pixel_ratio:n.browser.devicePixelRatio,u_is_halo:+ct})},mc=function(w,M,S,L,Y,ie,ae,ge,Pe,Ue){return n.extend(Ah(w,M,S,L,Y,ie,ae,ge,!0,Pe,!0),{u_texsize_icon:Ue,u_texture_icon:1})},Qa=function(w,M,S){return{u_matrix:w,u_opacity:M,u_color:S}},Ru=function(w,M,S,L,Y,ie){return n.extend(function(ae,ge,Pe,Ue){var ct=Pe.imageManager.getPattern(ae.from.toString()),ft=Pe.imageManager.getPattern(ae.to.toString()),gt=Pe.imageManager.getPixelSize(),ut=gt.width,Pt=gt.height,Wt=Math.pow(2,Ue.tileID.overscaledZ),St=Ue.tileSize*Math.pow(2,Pe.transform.tileZoom)/Wt,Zt=St*(Ue.tileID.canonical.x+Ue.tileID.wrap*Wt),ir=St*Ue.tileID.canonical.y;return{u_image:0,u_pattern_tl_a:ct.tl,u_pattern_br_a:ct.br,u_pattern_tl_b:ft.tl,u_pattern_br_b:ft.br,u_texsize:[ut,Pt],u_mix:ge.t,u_pattern_size_a:ct.displaySize,u_pattern_size_b:ft.displaySize,u_scale_a:ge.fromScale,u_scale_b:ge.toScale,u_tile_units_to_pixels:1/ua(Ue,1,Pe.transform.tileZoom),u_pixel_coord_upper:[Zt>>16,ir>>16],u_pixel_coord_lower:[65535&Zt,65535&ir]}}(L,ie,S,Y),{u_matrix:w,u_opacity:M})},gc={fillExtrusion:function(w,M){return{u_matrix:new n.UniformMatrix4f(w,M.u_matrix),u_lightpos:new n.Uniform3f(w,M.u_lightpos),u_lightintensity:new n.Uniform1f(w,M.u_lightintensity),u_lightcolor:new n.Uniform3f(w,M.u_lightcolor),u_vertical_gradient:new n.Uniform1f(w,M.u_vertical_gradient),u_opacity:new n.Uniform1f(w,M.u_opacity)}},fillExtrusionPattern:function(w,M){return{u_matrix:new n.UniformMatrix4f(w,M.u_matrix),u_lightpos:new n.Uniform3f(w,M.u_lightpos),u_lightintensity:new n.Uniform1f(w,M.u_lightintensity),u_lightcolor:new n.Uniform3f(w,M.u_lightcolor),u_vertical_gradient:new n.Uniform1f(w,M.u_vertical_gradient),u_height_factor:new n.Uniform1f(w,M.u_height_factor),u_image:new n.Uniform1i(w,M.u_image),u_texsize:new n.Uniform2f(w,M.u_texsize),u_pixel_coord_upper:new n.Uniform2f(w,M.u_pixel_coord_upper),u_pixel_coord_lower:new n.Uniform2f(w,M.u_pixel_coord_lower),u_scale:new n.Uniform3f(w,M.u_scale),u_fade:new n.Uniform1f(w,M.u_fade),u_opacity:new n.Uniform1f(w,M.u_opacity)}},fill:function(w,M){return{u_matrix:new n.UniformMatrix4f(w,M.u_matrix)}},fillPattern:function(w,M){return{u_matrix:new n.UniformMatrix4f(w,M.u_matrix),u_image:new n.Uniform1i(w,M.u_image),u_texsize:new n.Uniform2f(w,M.u_texsize),u_pixel_coord_upper:new n.Uniform2f(w,M.u_pixel_coord_upper),u_pixel_coord_lower:new n.Uniform2f(w,M.u_pixel_coord_lower),u_scale:new n.Uniform3f(w,M.u_scale),u_fade:new n.Uniform1f(w,M.u_fade)}},fillOutline:function(w,M){return{u_matrix:new n.UniformMatrix4f(w,M.u_matrix),u_world:new n.Uniform2f(w,M.u_world)}},fillOutlinePattern:function(w,M){return{u_matrix:new n.UniformMatrix4f(w,M.u_matrix),u_world:new n.Uniform2f(w,M.u_world),u_image:new n.Uniform1i(w,M.u_image),u_texsize:new n.Uniform2f(w,M.u_texsize),u_pixel_coord_upper:new n.Uniform2f(w,M.u_pixel_coord_upper),u_pixel_coord_lower:new n.Uniform2f(w,M.u_pixel_coord_lower),u_scale:new n.Uniform3f(w,M.u_scale),u_fade:new n.Uniform1f(w,M.u_fade)}},circle:function(w,M){return{u_camera_to_center_distance:new n.Uniform1f(w,M.u_camera_to_center_distance),u_scale_with_map:new n.Uniform1i(w,M.u_scale_with_map),u_pitch_with_map:new n.Uniform1i(w,M.u_pitch_with_map),u_extrude_scale:new n.Uniform2f(w,M.u_extrude_scale),u_device_pixel_ratio:new n.Uniform1f(w,M.u_device_pixel_ratio),u_matrix:new n.UniformMatrix4f(w,M.u_matrix)}},collisionBox:function(w,M){return{u_matrix:new n.UniformMatrix4f(w,M.u_matrix),u_camera_to_center_distance:new n.Uniform1f(w,M.u_camera_to_center_distance),u_pixels_to_tile_units:new n.Uniform1f(w,M.u_pixels_to_tile_units),u_extrude_scale:new n.Uniform2f(w,M.u_extrude_scale),u_overscale_factor:new n.Uniform1f(w,M.u_overscale_factor)}},collisionCircle:function(w,M){return{u_matrix:new n.UniformMatrix4f(w,M.u_matrix),u_inv_matrix:new n.UniformMatrix4f(w,M.u_inv_matrix),u_camera_to_center_distance:new n.Uniform1f(w,M.u_camera_to_center_distance),u_viewport_size:new n.Uniform2f(w,M.u_viewport_size)}},debug:function(w,M){return{u_color:new n.UniformColor(w,M.u_color),u_matrix:new n.UniformMatrix4f(w,M.u_matrix),u_overlay:new n.Uniform1i(w,M.u_overlay),u_overlay_scale:new n.Uniform1f(w,M.u_overlay_scale)}},clippingMask:function(w,M){return{u_matrix:new n.UniformMatrix4f(w,M.u_matrix)}},heatmap:function(w,M){return{u_extrude_scale:new n.Uniform1f(w,M.u_extrude_scale),u_intensity:new n.Uniform1f(w,M.u_intensity),u_matrix:new n.UniformMatrix4f(w,M.u_matrix)}},heatmapTexture:function(w,M){return{u_matrix:new n.UniformMatrix4f(w,M.u_matrix),u_world:new n.Uniform2f(w,M.u_world),u_image:new n.Uniform1i(w,M.u_image),u_color_ramp:new n.Uniform1i(w,M.u_color_ramp),u_opacity:new n.Uniform1f(w,M.u_opacity)}},hillshade:function(w,M){return{u_matrix:new n.UniformMatrix4f(w,M.u_matrix),u_image:new n.Uniform1i(w,M.u_image),u_latrange:new n.Uniform2f(w,M.u_latrange),u_light:new n.Uniform2f(w,M.u_light),u_shadow:new n.UniformColor(w,M.u_shadow),u_highlight:new n.UniformColor(w,M.u_highlight),u_accent:new n.UniformColor(w,M.u_accent)}},hillshadePrepare:function(w,M){return{u_matrix:new n.UniformMatrix4f(w,M.u_matrix),u_image:new n.Uniform1i(w,M.u_image),u_dimension:new n.Uniform2f(w,M.u_dimension),u_zoom:new n.Uniform1f(w,M.u_zoom),u_unpack:new n.Uniform4f(w,M.u_unpack)}},line:function(w,M){return{u_matrix:new n.UniformMatrix4f(w,M.u_matrix),u_ratio:new n.Uniform1f(w,M.u_ratio),u_device_pixel_ratio:new n.Uniform1f(w,M.u_device_pixel_ratio),u_units_to_pixels:new n.Uniform2f(w,M.u_units_to_pixels)}},lineGradient:function(w,M){return{u_matrix:new n.UniformMatrix4f(w,M.u_matrix),u_ratio:new n.Uniform1f(w,M.u_ratio),u_device_pixel_ratio:new n.Uniform1f(w,M.u_device_pixel_ratio),u_units_to_pixels:new n.Uniform2f(w,M.u_units_to_pixels),u_image:new n.Uniform1i(w,M.u_image),u_image_height:new n.Uniform1f(w,M.u_image_height)}},linePattern:function(w,M){return{u_matrix:new n.UniformMatrix4f(w,M.u_matrix),u_texsize:new n.Uniform2f(w,M.u_texsize),u_ratio:new n.Uniform1f(w,M.u_ratio),u_device_pixel_ratio:new n.Uniform1f(w,M.u_device_pixel_ratio),u_image:new n.Uniform1i(w,M.u_image),u_units_to_pixels:new n.Uniform2f(w,M.u_units_to_pixels),u_scale:new n.Uniform3f(w,M.u_scale),u_fade:new n.Uniform1f(w,M.u_fade)}},lineSDF:function(w,M){return{u_matrix:new n.UniformMatrix4f(w,M.u_matrix),u_ratio:new n.Uniform1f(w,M.u_ratio),u_device_pixel_ratio:new n.Uniform1f(w,M.u_device_pixel_ratio),u_units_to_pixels:new n.Uniform2f(w,M.u_units_to_pixels),u_patternscale_a:new n.Uniform2f(w,M.u_patternscale_a),u_patternscale_b:new n.Uniform2f(w,M.u_patternscale_b),u_sdfgamma:new n.Uniform1f(w,M.u_sdfgamma),u_image:new n.Uniform1i(w,M.u_image),u_tex_y_a:new n.Uniform1f(w,M.u_tex_y_a),u_tex_y_b:new n.Uniform1f(w,M.u_tex_y_b),u_mix:new n.Uniform1f(w,M.u_mix)}},raster:function(w,M){return{u_matrix:new n.UniformMatrix4f(w,M.u_matrix),u_tl_parent:new n.Uniform2f(w,M.u_tl_parent),u_scale_parent:new n.Uniform1f(w,M.u_scale_parent),u_buffer_scale:new n.Uniform1f(w,M.u_buffer_scale),u_fade_t:new n.Uniform1f(w,M.u_fade_t),u_opacity:new n.Uniform1f(w,M.u_opacity),u_image0:new n.Uniform1i(w,M.u_image0),u_image1:new n.Uniform1i(w,M.u_image1),u_brightness_low:new n.Uniform1f(w,M.u_brightness_low),u_brightness_high:new n.Uniform1f(w,M.u_brightness_high),u_saturation_factor:new n.Uniform1f(w,M.u_saturation_factor),u_contrast_factor:new n.Uniform1f(w,M.u_contrast_factor),u_spin_weights:new n.Uniform3f(w,M.u_spin_weights)}},symbolIcon:function(w,M){return{u_is_size_zoom_constant:new n.Uniform1i(w,M.u_is_size_zoom_constant),u_is_size_feature_constant:new n.Uniform1i(w,M.u_is_size_feature_constant),u_size_t:new n.Uniform1f(w,M.u_size_t),u_size:new n.Uniform1f(w,M.u_size),u_camera_to_center_distance:new n.Uniform1f(w,M.u_camera_to_center_distance),u_pitch:new n.Uniform1f(w,M.u_pitch),u_rotate_symbol:new n.Uniform1i(w,M.u_rotate_symbol),u_aspect_ratio:new n.Uniform1f(w,M.u_aspect_ratio),u_fade_change:new n.Uniform1f(w,M.u_fade_change),u_matrix:new n.UniformMatrix4f(w,M.u_matrix),u_label_plane_matrix:new n.UniformMatrix4f(w,M.u_label_plane_matrix),u_coord_matrix:new n.UniformMatrix4f(w,M.u_coord_matrix),u_is_text:new n.Uniform1i(w,M.u_is_text),u_pitch_with_map:new n.Uniform1i(w,M.u_pitch_with_map),u_texsize:new n.Uniform2f(w,M.u_texsize),u_texture:new n.Uniform1i(w,M.u_texture)}},symbolSDF:function(w,M){return{u_is_size_zoom_constant:new n.Uniform1i(w,M.u_is_size_zoom_constant),u_is_size_feature_constant:new n.Uniform1i(w,M.u_is_size_feature_constant),u_size_t:new n.Uniform1f(w,M.u_size_t),u_size:new n.Uniform1f(w,M.u_size),u_camera_to_center_distance:new n.Uniform1f(w,M.u_camera_to_center_distance),u_pitch:new n.Uniform1f(w,M.u_pitch),u_rotate_symbol:new n.Uniform1i(w,M.u_rotate_symbol),u_aspect_ratio:new n.Uniform1f(w,M.u_aspect_ratio),u_fade_change:new n.Uniform1f(w,M.u_fade_change),u_matrix:new n.UniformMatrix4f(w,M.u_matrix),u_label_plane_matrix:new n.UniformMatrix4f(w,M.u_label_plane_matrix),u_coord_matrix:new n.UniformMatrix4f(w,M.u_coord_matrix),u_is_text:new n.Uniform1i(w,M.u_is_text),u_pitch_with_map:new n.Uniform1i(w,M.u_pitch_with_map),u_texsize:new n.Uniform2f(w,M.u_texsize),u_texture:new n.Uniform1i(w,M.u_texture),u_gamma_scale:new n.Uniform1f(w,M.u_gamma_scale),u_device_pixel_ratio:new n.Uniform1f(w,M.u_device_pixel_ratio),u_is_halo:new n.Uniform1i(w,M.u_is_halo)}},symbolTextAndIcon:function(w,M){return{u_is_size_zoom_constant:new n.Uniform1i(w,M.u_is_size_zoom_constant),u_is_size_feature_constant:new n.Uniform1i(w,M.u_is_size_feature_constant),u_size_t:new n.Uniform1f(w,M.u_size_t),u_size:new n.Uniform1f(w,M.u_size),u_camera_to_center_distance:new n.Uniform1f(w,M.u_camera_to_center_distance),u_pitch:new n.Uniform1f(w,M.u_pitch),u_rotate_symbol:new n.Uniform1i(w,M.u_rotate_symbol),u_aspect_ratio:new n.Uniform1f(w,M.u_aspect_ratio),u_fade_change:new n.Uniform1f(w,M.u_fade_change),u_matrix:new n.UniformMatrix4f(w,M.u_matrix),u_label_plane_matrix:new n.UniformMatrix4f(w,M.u_label_plane_matrix),u_coord_matrix:new n.UniformMatrix4f(w,M.u_coord_matrix),u_is_text:new n.Uniform1i(w,M.u_is_text),u_pitch_with_map:new n.Uniform1i(w,M.u_pitch_with_map),u_texsize:new n.Uniform2f(w,M.u_texsize),u_texsize_icon:new n.Uniform2f(w,M.u_texsize_icon),u_texture:new n.Uniform1i(w,M.u_texture),u_texture_icon:new n.Uniform1i(w,M.u_texture_icon),u_gamma_scale:new n.Uniform1f(w,M.u_gamma_scale),u_device_pixel_ratio:new n.Uniform1f(w,M.u_device_pixel_ratio),u_is_halo:new n.Uniform1i(w,M.u_is_halo)}},background:function(w,M){return{u_matrix:new n.UniformMatrix4f(w,M.u_matrix),u_opacity:new n.Uniform1f(w,M.u_opacity),u_color:new n.UniformColor(w,M.u_color)}},backgroundPattern:function(w,M){return{u_matrix:new n.UniformMatrix4f(w,M.u_matrix),u_opacity:new n.Uniform1f(w,M.u_opacity),u_image:new n.Uniform1i(w,M.u_image),u_pattern_tl_a:new n.Uniform2f(w,M.u_pattern_tl_a),u_pattern_br_a:new n.Uniform2f(w,M.u_pattern_br_a),u_pattern_tl_b:new n.Uniform2f(w,M.u_pattern_tl_b),u_pattern_br_b:new n.Uniform2f(w,M.u_pattern_br_b),u_texsize:new n.Uniform2f(w,M.u_texsize),u_mix:new n.Uniform1f(w,M.u_mix),u_pattern_size_a:new n.Uniform2f(w,M.u_pattern_size_a),u_pattern_size_b:new n.Uniform2f(w,M.u_pattern_size_b),u_scale_a:new n.Uniform1f(w,M.u_scale_a),u_scale_b:new n.Uniform1f(w,M.u_scale_b),u_pixel_coord_upper:new n.Uniform2f(w,M.u_pixel_coord_upper),u_pixel_coord_lower:new n.Uniform2f(w,M.u_pixel_coord_lower),u_tile_units_to_pixels:new n.Uniform1f(w,M.u_tile_units_to_pixels)}}};function _h(w,M,S,L,Y,ie,ae){for(var ge=w.context,Pe=ge.gl,Ue=w.useProgram("collisionBox"),ct=[],ft=0,gt=0,ut=0;ut0){var kr=n.create(),Lr=Zt;n.mul(kr,St.placementInvProjMatrix,w.transform.glCoordMatrix),n.mul(kr,kr,St.placementViewportMatrix),ct.push({circleArray:dr,circleOffset:gt,transform:Lr,invTransform:kr}),gt=ft+=dr.length/4}ir&&Ue.draw(ge,Pe.LINES,mt.disabled,Qe.disabled,w.colorModeForRenderPass(),Jt.disabled,ni(Zt,w.transform,Wt),S.id,ir.layoutVertexBuffer,ir.indexBuffer,ir.segments,null,w.transform.zoom,null,null,ir.collisionVertexBuffer)}}if(ae&&ct.length){var Wr=w.useProgram("collisionCircle"),ai=new n.StructArrayLayout2f1f2i16;ai.resize(4*ft),ai._trim();for(var Ci=0,Si=0,$i=ct;Si<$i.length;Si+=1)for(var bn=$i[Si],Tn=0;Tn=0&&(Pt[St.associatedIconIndex]={shiftedAnchor:ai,angle:Ci})}else Ll(St.numGlyphs,gt)}if(ct){ut.clear();for(var $i=w.icon.placedSymbolArray,bn=0;bn<$i.length;bn++){var Tn=$i.get(bn);if(Tn.hidden)Ll(Tn.numGlyphs,ut);else{var xn=Pt[bn];if(xn)for(var zo=0;zo0){var ae=n.browser.now(),ge=(ae-w.timeAdded)/ie,Pe=M?(ae-M.timeAdded)/ie:-1,Ue=S.getSource(),ct=Y.coveringZoomLevel({tileSize:Ue.tileSize,roundZoom:Ue.roundZoom}),ft=!M||Math.abs(M.tileID.overscaledZ-ct)>Math.abs(w.tileID.overscaledZ-ct),gt=ft&&w.refreshedUponExpiration?1:n.clamp(ft?ge:1-Pe,0,1);return w.refreshedUponExpiration&&ge>=1&&(w.refreshedUponExpiration=!1),M?{opacity:1,mix:1-gt}:{opacity:gt,mix:0}}return{opacity:1,mix:0}}var yf=new n.Color(1,0,0,1),Bu=new n.Color(0,1,0,1),Wf=new n.Color(0,0,1,1),qf=new n.Color(1,0,1,1),Bt=new n.Color(0,1,1,1);function ar(w,M,S,L){Ur(w,0,M+S/2,w.transform.width,S,L)}function Br(w,M,S,L){Ur(w,M-S/2,0,S,w.transform.height,L)}function Ur(w,M,S,L,Y,ie){var ae=w.context,ge=ae.gl;ge.enable(ge.SCISSOR_TEST),ge.scissor(M*n.browser.devicePixelRatio,S*n.browser.devicePixelRatio,L*n.browser.devicePixelRatio,Y*n.browser.devicePixelRatio),ae.clear({color:ie}),ge.disable(ge.SCISSOR_TEST)}function ci(w,M,S){var L=w.context,Y=L.gl,ie=S.posMatrix,ae=w.useProgram("debug"),ge=mt.disabled,Pe=Qe.disabled,Ue=w.colorModeForRenderPass();L.activeTexture.set(Y.TEXTURE0),w.emptyTexture.bind(Y.LINEAR,Y.CLAMP_TO_EDGE),ae.draw(L,Y.LINE_STRIP,ge,Pe,Ue,Jt.disabled,Po(ie,n.Color.red),"$debug",w.debugBuffer,w.tileBorderIndexBuffer,w.debugSegments);var ct=M.getTileByID(S.key).latestRawTileData,ft=Math.floor((ct&&ct.byteLength||0)/1024),gt=M.getTile(S).tileSize,ut=512/Math.min(gt,512)*(S.overscaledZ/w.transform.zoom)*.5,Pt=S.canonical.toString();S.overscaledZ!==S.canonical.z&&(Pt+=" => "+S.overscaledZ),function(Wt,St){Wt.initDebugOverlayCanvas();var Zt=Wt.debugOverlayCanvas,ir=Wt.context.gl,dr=Wt.debugOverlayCanvas.getContext("2d");dr.clearRect(0,0,Zt.width,Zt.height),dr.shadowColor="white",dr.shadowBlur=2,dr.lineWidth=1.5,dr.strokeStyle="white",dr.textBaseline="top",dr.font="bold 36px Open Sans, sans-serif",dr.fillText(St,5,5),dr.strokeText(St,5,5),Wt.debugOverlayTexture.update(Zt),Wt.debugOverlayTexture.bind(ir.LINEAR,ir.CLAMP_TO_EDGE)}(w,Pt+" "+ft+"kb"),ae.draw(L,Y.TRIANGLES,ge,Pe,$t.alphaBlended,Jt.disabled,Po(ie,n.Color.transparent,ut),"$debug",w.debugBuffer,w.quadTriangleIndexBuffer,w.debugSegments)}var Li={symbol:function(w,M,S,L,Y){if(w.renderPass==="translucent"){var ie=Qe.disabled,ae=w.colorModeForRenderPass();S.layout.get("text-variable-anchor")&&function(ge,Pe,Ue,ct,ft,gt,ut){for(var Pt=Pe.transform,Wt=ft==="map",St=gt==="map",Zt=0,ir=ge;Zt256&&this.clearStencil(),S.setColorMode($t.disabled),S.setDepthMode(mt.disabled);var Y=this.useProgram("clippingMask");this._tileClippingMaskIDs={};for(var ie=0,ae=M;ie256&&this.clearStencil();var w=this.nextStencilID++,M=this.context.gl;return new Qe({func:M.NOTEQUAL,mask:255},w,255,M.KEEP,M.KEEP,M.REPLACE)},yi.prototype.stencilModeForClipping=function(w){var M=this.context.gl;return new Qe({func:M.EQUAL,mask:255},this._tileClippingMaskIDs[w.key],0,M.KEEP,M.KEEP,M.REPLACE)},yi.prototype.stencilConfigForOverlap=function(w){var M,S=this.context.gl,L=w.sort(function(Pe,Ue){return Ue.overscaledZ-Pe.overscaledZ}),Y=L[L.length-1].overscaledZ,ie=L[0].overscaledZ-Y+1;if(ie>1){this.currentStencilSource=void 0,this.nextStencilID+ie>256&&this.clearStencil();for(var ae={},ge=0;ge=0;this.currentLayer--){var dr=this.style._layers[L[this.currentLayer]],kr=Y[dr.source],Lr=Ue[dr.source];this._renderTileClippingMasks(dr,Lr),this.renderLayer(this,kr,dr,Lr)}for(this.renderPass="translucent",this.currentLayer=0;this.currentLayer0?M.pop():null},yi.prototype.isPatternMissing=function(w){if(!w)return!1;if(!w.from||!w.to)return!0;var M=this.imageManager.getPattern(w.from.toString()),S=this.imageManager.getPattern(w.to.toString());return!M||!S},yi.prototype.useProgram=function(w,M){this.cache=this.cache||{};var S=""+w+(M?M.cacheKey:"")+(this._showOverdrawInspector?"/overdraw":"");return this.cache[S]||(this.cache[S]=new Mo(this.context,w,Bi[w],M,gc[w],this._showOverdrawInspector)),this.cache[S]},yi.prototype.setCustomLayerDefaults=function(){this.context.unbindVAO(),this.context.cullFace.setDefault(),this.context.activeTexture.setDefault(),this.context.pixelStoreUnpack.setDefault(),this.context.pixelStoreUnpackPremultiplyAlpha.setDefault(),this.context.pixelStoreUnpackFlipY.setDefault()},yi.prototype.setBaseState=function(){var w=this.context.gl;this.context.cullFace.set(!1),this.context.viewport.set([0,0,this.width,this.height]),this.context.blendEquation.set(w.FUNC_ADD)},yi.prototype.initDebugOverlayCanvas=function(){this.debugOverlayCanvas==null&&(this.debugOverlayCanvas=n.window.document.createElement("canvas"),this.debugOverlayCanvas.width=512,this.debugOverlayCanvas.height=512,this.debugOverlayTexture=new n.Texture(this.context,this.debugOverlayCanvas,this.context.gl.RGBA))},yi.prototype.destroy=function(){this.emptyTexture.destroy(),this.debugOverlayTexture&&this.debugOverlayTexture.destroy()};var Pn=function(w,M){this.points=w,this.planes=M};Pn.fromInvProjectionMatrix=function(w,M,S){var L=Math.pow(2,S),Y=[[-1,1,-1,1],[1,1,-1,1],[1,-1,-1,1],[-1,-1,-1,1],[-1,1,1,1],[1,1,1,1],[1,-1,1,1],[-1,-1,1,1]].map(function(ae){return n.transformMat4([],ae,w)}).map(function(ae){return n.scale$1([],ae,1/ae[3]/M*L)}),ie=[[0,1,2],[6,5,4],[0,3,7],[2,1,5],[3,2,6],[0,4,5]].map(function(ae){var ge=n.sub([],Y[ae[0]],Y[ae[1]]),Pe=n.sub([],Y[ae[2]],Y[ae[1]]),Ue=n.normalize([],n.cross([],ge,Pe)),ct=-n.dot(Ue,Y[ae[1]]);return Ue.concat(ct)});return new Pn(Y,ie)};var sn=function(w,M){this.min=w,this.max=M,this.center=n.scale$2([],n.add([],this.min,this.max),.5)};sn.prototype.quadrant=function(w){for(var M=[w%2==0,w<2],S=n.clone$2(this.min),L=n.clone$2(this.max),Y=0;Y=0;if(ie===0)return 0;ie!==M.length&&(S=!1)}if(S)return 2;for(var ge=0;ge<3;ge++){for(var Pe=Number.MAX_VALUE,Ue=-Number.MAX_VALUE,ct=0;ctthis.max[ge]-this.min[ge])return 0}return 1};var To=function(w,M,S,L){if(w===void 0&&(w=0),M===void 0&&(M=0),S===void 0&&(S=0),L===void 0&&(L=0),isNaN(w)||w<0||isNaN(M)||M<0||isNaN(S)||S<0||isNaN(L)||L<0)throw new Error("Invalid value for edge-insets, top, bottom, left and right must all be numbers");this.top=w,this.bottom=M,this.left=S,this.right=L};To.prototype.interpolate=function(w,M,S){return M.top!=null&&w.top!=null&&(this.top=n.number(w.top,M.top,S)),M.bottom!=null&&w.bottom!=null&&(this.bottom=n.number(w.bottom,M.bottom,S)),M.left!=null&&w.left!=null&&(this.left=n.number(w.left,M.left,S)),M.right!=null&&w.right!=null&&(this.right=n.number(w.right,M.right,S)),this},To.prototype.getCenter=function(w,M){var S=n.clamp((this.left+w-this.right)/2,0,w),L=n.clamp((this.top+M-this.bottom)/2,0,M);return new n.Point(S,L)},To.prototype.equals=function(w){return this.top===w.top&&this.bottom===w.bottom&&this.left===w.left&&this.right===w.right},To.prototype.clone=function(){return new To(this.top,this.bottom,this.left,this.right)},To.prototype.toJSON=function(){return{top:this.top,bottom:this.bottom,left:this.left,right:this.right}};var Hi=function(w,M,S,L,Y){this.tileSize=512,this.maxValidLatitude=85.051129,this._renderWorldCopies=Y===void 0||Y,this._minZoom=w||0,this._maxZoom=M||22,this._minPitch=S??0,this._maxPitch=L??60,this.setMaxBounds(),this.width=0,this.height=0,this._center=new n.LngLat(0,0),this.zoom=0,this.angle=0,this._fov=.6435011087932844,this._pitch=0,this._unmodified=!0,this._edgeInsets=new To,this._posMatrixCache={},this._alignedPosMatrixCache={}},Ti={minZoom:{configurable:!0},maxZoom:{configurable:!0},minPitch:{configurable:!0},maxPitch:{configurable:!0},renderWorldCopies:{configurable:!0},worldSize:{configurable:!0},centerOffset:{configurable:!0},size:{configurable:!0},bearing:{configurable:!0},pitch:{configurable:!0},fov:{configurable:!0},zoom:{configurable:!0},center:{configurable:!0},padding:{configurable:!0},centerPoint:{configurable:!0},unmodified:{configurable:!0},point:{configurable:!0}};Hi.prototype.clone=function(){var w=new Hi(this._minZoom,this._maxZoom,this._minPitch,this.maxPitch,this._renderWorldCopies);return w.tileSize=this.tileSize,w.latRange=this.latRange,w.width=this.width,w.height=this.height,w._center=this._center,w.zoom=this.zoom,w.angle=this.angle,w._fov=this._fov,w._pitch=this._pitch,w._unmodified=this._unmodified,w._edgeInsets=this._edgeInsets.clone(),w._calcMatrices(),w},Ti.minZoom.get=function(){return this._minZoom},Ti.minZoom.set=function(w){this._minZoom!==w&&(this._minZoom=w,this.zoom=Math.max(this.zoom,w))},Ti.maxZoom.get=function(){return this._maxZoom},Ti.maxZoom.set=function(w){this._maxZoom!==w&&(this._maxZoom=w,this.zoom=Math.min(this.zoom,w))},Ti.minPitch.get=function(){return this._minPitch},Ti.minPitch.set=function(w){this._minPitch!==w&&(this._minPitch=w,this.pitch=Math.max(this.pitch,w))},Ti.maxPitch.get=function(){return this._maxPitch},Ti.maxPitch.set=function(w){this._maxPitch!==w&&(this._maxPitch=w,this.pitch=Math.min(this.pitch,w))},Ti.renderWorldCopies.get=function(){return this._renderWorldCopies},Ti.renderWorldCopies.set=function(w){w===void 0?w=!0:w===null&&(w=!1),this._renderWorldCopies=w},Ti.worldSize.get=function(){return this.tileSize*this.scale},Ti.centerOffset.get=function(){return this.centerPoint._sub(this.size._div(2))},Ti.size.get=function(){return new n.Point(this.width,this.height)},Ti.bearing.get=function(){return-this.angle/Math.PI*180},Ti.bearing.set=function(w){var M=-n.wrap(w,-180,180)*Math.PI/180;this.angle!==M&&(this._unmodified=!1,this.angle=M,this._calcMatrices(),this.rotationMatrix=n.create$2(),n.rotate(this.rotationMatrix,this.rotationMatrix,this.angle))},Ti.pitch.get=function(){return this._pitch/Math.PI*180},Ti.pitch.set=function(w){var M=n.clamp(w,this.minPitch,this.maxPitch)/180*Math.PI;this._pitch!==M&&(this._unmodified=!1,this._pitch=M,this._calcMatrices())},Ti.fov.get=function(){return this._fov/Math.PI*180},Ti.fov.set=function(w){w=Math.max(.01,Math.min(60,w)),this._fov!==w&&(this._unmodified=!1,this._fov=w/180*Math.PI,this._calcMatrices())},Ti.zoom.get=function(){return this._zoom},Ti.zoom.set=function(w){var M=Math.min(Math.max(w,this.minZoom),this.maxZoom);this._zoom!==M&&(this._unmodified=!1,this._zoom=M,this.scale=this.zoomScale(M),this.tileZoom=Math.floor(M),this.zoomFraction=M-this.tileZoom,this._constrain(),this._calcMatrices())},Ti.center.get=function(){return this._center},Ti.center.set=function(w){w.lat===this._center.lat&&w.lng===this._center.lng||(this._unmodified=!1,this._center=w,this._constrain(),this._calcMatrices())},Ti.padding.get=function(){return this._edgeInsets.toJSON()},Ti.padding.set=function(w){this._edgeInsets.equals(w)||(this._unmodified=!1,this._edgeInsets.interpolate(this._edgeInsets,w,1),this._calcMatrices())},Ti.centerPoint.get=function(){return this._edgeInsets.getCenter(this.width,this.height)},Hi.prototype.isPaddingEqual=function(w){return this._edgeInsets.equals(w)},Hi.prototype.interpolatePadding=function(w,M,S){this._unmodified=!1,this._edgeInsets.interpolate(w,M,S),this._constrain(),this._calcMatrices()},Hi.prototype.coveringZoomLevel=function(w){var M=(w.roundZoom?Math.round:Math.floor)(this.zoom+this.scaleZoom(this.tileSize/w.tileSize));return Math.max(0,M)},Hi.prototype.getVisibleUnwrappedCoordinates=function(w){var M=[new n.UnwrappedTileID(0,w)];if(this._renderWorldCopies)for(var S=this.pointCoordinate(new n.Point(0,0)),L=this.pointCoordinate(new n.Point(this.width,0)),Y=this.pointCoordinate(new n.Point(this.width,this.height)),ie=this.pointCoordinate(new n.Point(0,this.height)),ae=Math.floor(Math.min(S.x,L.x,Y.x,ie.x)),ge=Math.floor(Math.max(S.x,L.x,Y.x,ie.x)),Pe=ae-1;Pe<=ge+1;Pe++)Pe!==0&&M.push(new n.UnwrappedTileID(Pe,w));return M},Hi.prototype.coveringTiles=function(w){var M=this.coveringZoomLevel(w),S=M;if(w.minzoom!==void 0&&Mw.maxzoom&&(M=w.maxzoom);var L=n.MercatorCoordinate.fromLngLat(this.center),Y=Math.pow(2,M),ie=[Y*L.x,Y*L.y,0],ae=Pn.fromInvProjectionMatrix(this.invProjMatrix,this.worldSize,M),ge=w.minzoom||0;this.pitch<=60&&this._edgeInsets.top<.1&&(ge=M);var Pe=function(Si){return{aabb:new sn([Si*Y,0,0],[(Si+1)*Y,Y,0]),zoom:0,x:0,y:0,wrap:Si,fullyVisible:!1}},Ue=[],ct=[],ft=M,gt=w.reparseOverscaled?S:M;if(this._renderWorldCopies)for(var ut=1;ut<=3;ut++)Ue.push(Pe(-ut)),Ue.push(Pe(ut));for(Ue.push(Pe(0));Ue.length>0;){var Pt=Ue.pop(),Wt=Pt.x,St=Pt.y,Zt=Pt.fullyVisible;if(!Zt){var ir=Pt.aabb.intersects(ae);if(ir===0)continue;Zt=ir===2}var dr=Pt.aabb.distanceX(ie),kr=Pt.aabb.distanceY(ie),Lr=Math.max(Math.abs(dr),Math.abs(kr));if(Pt.zoom===ft||Lr>3+(1<=ge)ct.push({tileID:new n.OverscaledTileID(Pt.zoom===ft?gt:Pt.zoom,Pt.wrap,Pt.zoom,Wt,St),distanceSq:n.sqrLen([ie[0]-.5-Wt,ie[1]-.5-St])});else for(var Wr=0;Wr<4;Wr++){var ai=(Wt<<1)+Wr%2,Ci=(St<<1)+(Wr>>1);Ue.push({aabb:Pt.aabb.quadrant(Wr),zoom:Pt.zoom+1,x:ai,y:Ci,wrap:Pt.wrap,fullyVisible:Zt})}}return ct.sort(function(Si,$i){return Si.distanceSq-$i.distanceSq}).map(function(Si){return Si.tileID})},Hi.prototype.resize=function(w,M){this.width=w,this.height=M,this.pixelsToGLUnits=[2/w,-2/M],this._constrain(),this._calcMatrices()},Ti.unmodified.get=function(){return this._unmodified},Hi.prototype.zoomScale=function(w){return Math.pow(2,w)},Hi.prototype.scaleZoom=function(w){return Math.log(w)/Math.LN2},Hi.prototype.project=function(w){var M=n.clamp(w.lat,-this.maxValidLatitude,this.maxValidLatitude);return new n.Point(n.mercatorXfromLng(w.lng)*this.worldSize,n.mercatorYfromLat(M)*this.worldSize)},Hi.prototype.unproject=function(w){return new n.MercatorCoordinate(w.x/this.worldSize,w.y/this.worldSize).toLngLat()},Ti.point.get=function(){return this.project(this.center)},Hi.prototype.setLocationAtPoint=function(w,M){var S=this.pointCoordinate(M),L=this.pointCoordinate(this.centerPoint),Y=this.locationCoordinate(w),ie=new n.MercatorCoordinate(Y.x-(S.x-L.x),Y.y-(S.y-L.y));this.center=this.coordinateLocation(ie),this._renderWorldCopies&&(this.center=this.center.wrap())},Hi.prototype.locationPoint=function(w){return this.coordinatePoint(this.locationCoordinate(w))},Hi.prototype.pointLocation=function(w){return this.coordinateLocation(this.pointCoordinate(w))},Hi.prototype.locationCoordinate=function(w){return n.MercatorCoordinate.fromLngLat(w)},Hi.prototype.coordinateLocation=function(w){return w.toLngLat()},Hi.prototype.pointCoordinate=function(w){var M=[w.x,w.y,0,1],S=[w.x,w.y,1,1];n.transformMat4(M,M,this.pixelMatrixInverse),n.transformMat4(S,S,this.pixelMatrixInverse);var L=M[3],Y=S[3],ie=M[1]/L,ae=S[1]/Y,ge=M[2]/L,Pe=S[2]/Y,Ue=ge===Pe?0:(0-ge)/(Pe-ge);return new n.MercatorCoordinate(n.number(M[0]/L,S[0]/Y,Ue)/this.worldSize,n.number(ie,ae,Ue)/this.worldSize)},Hi.prototype.coordinatePoint=function(w){var M=[w.x*this.worldSize,w.y*this.worldSize,0,1];return n.transformMat4(M,M,this.pixelMatrix),new n.Point(M[0]/M[3],M[1]/M[3])},Hi.prototype.getBounds=function(){return new n.LngLatBounds().extend(this.pointLocation(new n.Point(0,0))).extend(this.pointLocation(new n.Point(this.width,0))).extend(this.pointLocation(new n.Point(this.width,this.height))).extend(this.pointLocation(new n.Point(0,this.height)))},Hi.prototype.getMaxBounds=function(){return this.latRange&&this.latRange.length===2&&this.lngRange&&this.lngRange.length===2?new n.LngLatBounds([this.lngRange[0],this.latRange[0]],[this.lngRange[1],this.latRange[1]]):null},Hi.prototype.setMaxBounds=function(w){w?(this.lngRange=[w.getWest(),w.getEast()],this.latRange=[w.getSouth(),w.getNorth()],this._constrain()):(this.lngRange=null,this.latRange=[-this.maxValidLatitude,this.maxValidLatitude])},Hi.prototype.calculatePosMatrix=function(w,M){M===void 0&&(M=!1);var S=w.key,L=M?this._alignedPosMatrixCache:this._posMatrixCache;if(L[S])return L[S];var Y=w.canonical,ie=this.worldSize/this.zoomScale(Y.z),ae=Y.x+Math.pow(2,Y.z)*w.wrap,ge=n.identity(new Float64Array(16));return n.translate(ge,ge,[ae*ie,Y.y*ie,0]),n.scale(ge,ge,[ie/n.EXTENT,ie/n.EXTENT,1]),n.multiply(ge,M?this.alignedProjMatrix:this.projMatrix,ge),L[S]=new Float32Array(ge),L[S]},Hi.prototype.customLayerMatrix=function(){return this.mercatorMatrix.slice()},Hi.prototype._constrain=function(){if(this.center&&this.width&&this.height&&!this._constraining){this._constraining=!0;var w,M,S,L,Y=-90,ie=90,ae=-180,ge=180,Pe=this.size,Ue=this._unmodified;if(this.latRange){var ct=this.latRange;Y=n.mercatorYfromLat(ct[1])*this.worldSize,w=(ie=n.mercatorYfromLat(ct[0])*this.worldSize)-Yie&&(L=ie-Wt)}if(this.lngRange){var St=gt.x,Zt=Pe.x/2;St-Ztge&&(S=ge-Zt)}S===void 0&&L===void 0||(this.center=this.unproject(new n.Point(S!==void 0?S:gt.x,L!==void 0?L:gt.y))),this._unmodified=Ue,this._constraining=!1}},Hi.prototype._calcMatrices=function(){if(this.height){var w=this.centerOffset;this.cameraToCenterDistance=.5/Math.tan(this._fov/2)*this.height;var M=Math.PI/2+this._pitch,S=this._fov*(.5+w.y/this.height),L=Math.sin(S)*this.cameraToCenterDistance/Math.sin(n.clamp(Math.PI-M-S,.01,Math.PI-.01)),Y=this.point,ie=Y.x,ae=Y.y,ge=1.01*(Math.cos(Math.PI/2-this._pitch)*L+this.cameraToCenterDistance),Pe=this.height/50,Ue=new Float64Array(16);n.perspective(Ue,this._fov,this.width/this.height,Pe,ge),Ue[8]=2*-w.x/this.width,Ue[9]=2*w.y/this.height,n.scale(Ue,Ue,[1,-1,1]),n.translate(Ue,Ue,[0,0,-this.cameraToCenterDistance]),n.rotateX(Ue,Ue,this._pitch),n.rotateZ(Ue,Ue,this.angle),n.translate(Ue,Ue,[-ie,-ae,0]),this.mercatorMatrix=n.scale([],Ue,[this.worldSize,this.worldSize,this.worldSize]),n.scale(Ue,Ue,[1,1,n.mercatorZfromAltitude(1,this.center.lat)*this.worldSize,1]),this.projMatrix=Ue,this.invProjMatrix=n.invert([],this.projMatrix);var ct=this.width%2/2,ft=this.height%2/2,gt=Math.cos(this.angle),ut=Math.sin(this.angle),Pt=ie-Math.round(ie)+gt*ct+ut*ft,Wt=ae-Math.round(ae)+gt*ft+ut*ct,St=new Float64Array(Ue);if(n.translate(St,St,[Pt>.5?Pt-1:Pt,Wt>.5?Wt-1:Wt,0]),this.alignedProjMatrix=St,Ue=n.create(),n.scale(Ue,Ue,[this.width/2,-this.height/2,1]),n.translate(Ue,Ue,[1,-1,0]),this.labelPlaneMatrix=Ue,Ue=n.create(),n.scale(Ue,Ue,[1,-1,1]),n.translate(Ue,Ue,[-1,-1,0]),n.scale(Ue,Ue,[2/this.width,2/this.height,1]),this.glCoordMatrix=Ue,this.pixelMatrix=n.multiply(new Float64Array(16),this.labelPlaneMatrix,this.projMatrix),!(Ue=n.invert(new Float64Array(16),this.pixelMatrix)))throw new Error("failed to invert matrix");this.pixelMatrixInverse=Ue,this._posMatrixCache={},this._alignedPosMatrixCache={}}},Hi.prototype.maxPitchScaleFactor=function(){if(!this.pixelMatrixInverse)return 1;var w=this.pointCoordinate(new n.Point(0,0)),M=[w.x*this.worldSize,w.y*this.worldSize,0,1];return n.transformMat4(M,M,this.pixelMatrix)[3]/this.cameraToCenterDistance},Hi.prototype.getCameraPoint=function(){var w=Math.tan(this._pitch)*(this.cameraToCenterDistance||1);return this.centerPoint.add(new n.Point(0,w))},Hi.prototype.getCameraQueryGeometry=function(w){var M=this.getCameraPoint();if(w.length===1)return[w[0],M];for(var S=M.x,L=M.y,Y=M.x,ie=M.y,ae=0,ge=w;ae=3&&!w.some(function(S){return isNaN(S)})){var M=this._map.dragRotate.isEnabled()&&this._map.touchZoomRotate.isEnabled()?+(w[3]||0):this._map.getBearing();return this._map.jumpTo({center:[+w[2],+w[1]],zoom:+w[0],bearing:M,pitch:+(w[4]||0)}),!0}return!1},Kn.prototype._updateHashUnthrottled=function(){var w=n.window.location.href.replace(/(#.+)?$/,this.getHashString());try{n.window.history.replaceState(n.window.history.state,null,w)}catch{}};var zn={linearity:.3,easing:n.bezier(0,0,.3,1)},Fs=n.extend({deceleration:2500,maxSpeed:1400},zn),wl=n.extend({deceleration:20,maxSpeed:1400},zn),yo=n.extend({deceleration:1e3,maxSpeed:360},zn),tc=n.extend({deceleration:1e3,maxSpeed:90},zn),Tl=function(w){this._map=w,this.clear()};function ll(w,M){(!w.duration||w.duration0&&M-w[0].time>160;)w.shift()},Tl.prototype._onMoveEnd=function(w){if(this._drainInertiaBuffer(),!(this._inertiaBuffer.length<2)){for(var M={zoom:0,bearing:0,pitch:0,pan:new n.Point(0,0),pinchAround:void 0,around:void 0},S=0,L=this._inertiaBuffer;S=this._clickTolerance||this._map.fire(new Sl(w.type,this._map,w))},Pa.prototype.dblclick=function(w){return this._firePreventable(new Sl(w.type,this._map,w))},Pa.prototype.mouseover=function(w){this._map.fire(new Sl(w.type,this._map,w))},Pa.prototype.mouseout=function(w){this._map.fire(new Sl(w.type,this._map,w))},Pa.prototype.touchstart=function(w){return this._firePreventable(new _d(w.type,this._map,w))},Pa.prototype.touchmove=function(w){this._map.fire(new _d(w.type,this._map,w))},Pa.prototype.touchend=function(w){this._map.fire(new _d(w.type,this._map,w))},Pa.prototype.touchcancel=function(w){this._map.fire(new _d(w.type,this._map,w))},Pa.prototype._firePreventable=function(w){if(this._map.fire(w),w.defaultPrevented)return{}},Pa.prototype.isEnabled=function(){return!0},Pa.prototype.isActive=function(){return!1},Pa.prototype.enable=function(){},Pa.prototype.disable=function(){};var Yi=function(w){this._map=w};Yi.prototype.reset=function(){this._delayContextMenu=!1,delete this._contextMenuEvent},Yi.prototype.mousemove=function(w){this._map.fire(new Sl(w.type,this._map,w))},Yi.prototype.mousedown=function(){this._delayContextMenu=!0},Yi.prototype.mouseup=function(){this._delayContextMenu=!1,this._contextMenuEvent&&(this._map.fire(new Sl("contextmenu",this._map,this._contextMenuEvent)),delete this._contextMenuEvent)},Yi.prototype.contextmenu=function(w){this._delayContextMenu?this._contextMenuEvent=w:this._map.fire(new Sl(w.type,this._map,w)),this._map.listens("contextmenu")&&w.preventDefault()},Yi.prototype.isEnabled=function(){return!0},Yi.prototype.isActive=function(){return!1},Yi.prototype.enable=function(){},Yi.prototype.disable=function(){};var Cc=function(w,M){this._map=w,this._el=w.getCanvasContainer(),this._container=w.getContainer(),this._clickTolerance=M.clickTolerance||1};function qd(w,M){for(var S={},L=0;Lthis.numTouches)&&(this.aborted=!0),this.aborted||(this.startTime===void 0&&(this.startTime=w.timeStamp),S.length===this.numTouches&&(this.centroid=function(L){for(var Y=new n.Point(0,0),ie=0,ae=L;ie30)&&(this.aborted=!0)}}},yd.prototype.touchend=function(w,M,S){if((!this.centroid||w.timeStamp-this.startTime>500)&&(this.aborted=!0),S.length===0){var L=!this.aborted&&this.centroid;if(this.reset(),L)return L}};var ru=function(w){this.singleTap=new yd(w),this.numTaps=w.numTaps,this.reset()};ru.prototype.reset=function(){this.lastTime=1/0,delete this.lastTap,this.count=0,this.singleTap.reset()},ru.prototype.touchstart=function(w,M,S){this.singleTap.touchstart(w,M,S)},ru.prototype.touchmove=function(w,M,S){this.singleTap.touchmove(w,M,S)},ru.prototype.touchend=function(w,M,S){var L=this.singleTap.touchend(w,M,S);if(L){var Y=w.timeStamp-this.lastTime<500,ie=!this.lastTap||this.lastTap.dist(L)<30;if(Y&&ie||this.reset(),this.count++,this.lastTime=w.timeStamp,this.lastTap=L,this.count===this.numTaps)return this.reset(),L}};var kl=function(){this._zoomIn=new ru({numTouches:1,numTaps:2}),this._zoomOut=new ru({numTouches:2,numTaps:1}),this.reset()};kl.prototype.reset=function(){this._active=!1,this._zoomIn.reset(),this._zoomOut.reset()},kl.prototype.touchstart=function(w,M,S){this._zoomIn.touchstart(w,M,S),this._zoomOut.touchstart(w,M,S)},kl.prototype.touchmove=function(w,M,S){this._zoomIn.touchmove(w,M,S),this._zoomOut.touchmove(w,M,S)},kl.prototype.touchend=function(w,M,S){var L=this,Y=this._zoomIn.touchend(w,M,S),ie=this._zoomOut.touchend(w,M,S);return Y?(this._active=!0,w.preventDefault(),setTimeout(function(){return L.reset()},0),{cameraAnimation:function(ae){return ae.easeTo({duration:300,zoom:ae.getZoom()+1,around:ae.unproject(Y)},{originalEvent:w})}}):ie?(this._active=!0,w.preventDefault(),setTimeout(function(){return L.reset()},0),{cameraAnimation:function(ae){return ae.easeTo({duration:300,zoom:ae.getZoom()-1,around:ae.unproject(ie)},{originalEvent:w})}}):void 0},kl.prototype.touchcancel=function(){this.reset()},kl.prototype.enable=function(){this._enabled=!0},kl.prototype.disable=function(){this._enabled=!1,this.reset()},kl.prototype.isEnabled=function(){return this._enabled},kl.prototype.isActive=function(){return this._active};var Ip={0:1,2:2},Fi=function(w){this.reset(),this._clickTolerance=w.clickTolerance||1};Fi.prototype.blur=function(){this.reset()},Fi.prototype.reset=function(){this._active=!1,this._moved=!1,delete this._lastPoint,delete this._eventButton},Fi.prototype._correctButton=function(w,M){return!1},Fi.prototype._move=function(w,M){return{}},Fi.prototype.mousedown=function(w,M){if(!this._lastPoint){var S=s.mouseButton(w);this._correctButton(w,S)&&(this._lastPoint=M,this._eventButton=S)}},Fi.prototype.mousemoveWindow=function(w,M){var S=this._lastPoint;if(S){if(w.preventDefault(),function(L,Y){var ie=Ip[Y];return L.buttons===void 0||(L.buttons&ie)!==ie}(w,this._eventButton))this.reset();else if(this._moved||!(M.dist(S)0&&(this._active=!0);var L=qd(S,M),Y=new n.Point(0,0),ie=new n.Point(0,0),ae=0;for(var ge in L){var Pe=L[ge],Ue=this._touches[ge];Ue&&(Y._add(Pe),ie._add(Pe.sub(Ue)),ae++,L[ge]=Pe)}if(this._touches=L,!(aeMath.abs(w.x)}var $d=function(w){function M(){w.apply(this,arguments)}return w&&(M.__proto__=w),(M.prototype=Object.create(w&&w.prototype)).constructor=M,M.prototype.reset=function(){w.prototype.reset.call(this),this._valid=void 0,delete this._firstMove,delete this._lastPoints},M.prototype._start=function(S){this._lastPoints=S,yh(S[0].sub(S[1]))&&(this._valid=!1)},M.prototype._move=function(S,L,Y){var ie=S[0].sub(this._lastPoints[0]),ae=S[1].sub(this._lastPoints[1]);if(this._valid=this.gestureBeginsVertically(ie,ae,Y.timeStamp),this._valid)return this._lastPoints=S,this._active=!0,{pitchDelta:(ie.y+ae.y)/2*-.5}},M.prototype.gestureBeginsVertically=function(S,L,Y){if(this._valid!==void 0)return this._valid;var ie=S.mag()>=2,ae=L.mag()>=2;if(ie||ae){if(!ie||!ae)return this._firstMove===void 0&&(this._firstMove=Y),Y-this._firstMove<100&&void 0;var ge=S.y>0==L.y>0;return yh(S)&&yh(L)&&ge}},M}(Ic),$f={panStep:100,bearingStep:15,pitchStep:10},Yu=function(){var w=$f;this._panStep=w.panStep,this._bearingStep=w.bearingStep,this._pitchStep=w.pitchStep,this._rotationDisabled=!1};function gu(w){return w*(2-w)}Yu.prototype.blur=function(){this.reset()},Yu.prototype.reset=function(){this._active=!1},Yu.prototype.keydown=function(w){var M=this;if(!(w.altKey||w.ctrlKey||w.metaKey)){var S=0,L=0,Y=0,ie=0,ae=0;switch(w.keyCode){case 61:case 107:case 171:case 187:S=1;break;case 189:case 109:case 173:S=-1;break;case 37:w.shiftKey?L=-1:(w.preventDefault(),ie=-1);break;case 39:w.shiftKey?L=1:(w.preventDefault(),ie=1);break;case 38:w.shiftKey?Y=1:(w.preventDefault(),ae=-1);break;case 40:w.shiftKey?Y=-1:(w.preventDefault(),ae=1);break;default:return}return this._rotationDisabled&&(L=0,Y=0),{cameraAnimation:function(ge){var Pe=ge.getZoom();ge.easeTo({duration:300,easeId:"keyboardHandler",easing:gu,zoom:S?Math.round(Pe)+S*(w.shiftKey?2:1):Pe,bearing:ge.getBearing()+L*M._bearingStep,pitch:ge.getPitch()+Y*M._pitchStep,offset:[-ie*M._panStep,-ae*M._panStep],center:ge.getCenter()},{originalEvent:w})}}}},Yu.prototype.enable=function(){this._enabled=!0},Yu.prototype.disable=function(){this._enabled=!1,this.reset()},Yu.prototype.isEnabled=function(){return this._enabled},Yu.prototype.isActive=function(){return this._active},Yu.prototype.disableRotation=function(){this._rotationDisabled=!0},Yu.prototype.enableRotation=function(){this._rotationDisabled=!1};var So=function(w,M){this._map=w,this._el=w.getCanvasContainer(),this._handler=M,this._delta=0,this._defaultZoomRate=.01,this._wheelZoomRate=1/450,n.bindAll(["_onTimeout"],this)};So.prototype.setZoomRate=function(w){this._defaultZoomRate=w},So.prototype.setWheelZoomRate=function(w){this._wheelZoomRate=w},So.prototype.isEnabled=function(){return!!this._enabled},So.prototype.isActive=function(){return!!this._active||this._finishTimeout!==void 0},So.prototype.isZooming=function(){return!!this._zooming},So.prototype.enable=function(w){this.isEnabled()||(this._enabled=!0,this._aroundCenter=w&&w.around==="center")},So.prototype.disable=function(){this.isEnabled()&&(this._enabled=!1)},So.prototype.wheel=function(w){if(this.isEnabled()){var M=w.deltaMode===n.window.WheelEvent.DOM_DELTA_LINE?40*w.deltaY:w.deltaY,S=n.browser.now(),L=S-(this._lastWheelEventTime||0);this._lastWheelEventTime=S,M!==0&&M%4.000244140625==0?this._type="wheel":M!==0&&Math.abs(M)<4?this._type="trackpad":L>400?(this._type=null,this._lastValue=M,this._timeout=setTimeout(this._onTimeout,40,w)):this._type||(this._type=Math.abs(L*M)<200?"trackpad":"wheel",this._timeout&&(clearTimeout(this._timeout),this._timeout=null,M+=this._lastValue)),w.shiftKey&&M&&(M/=4),this._type&&(this._lastWheelEvent=w,this._delta-=M,this._active||this._start(w)),w.preventDefault()}},So.prototype._onTimeout=function(w){this._type="wheel",this._delta-=this._lastValue,this._active||this._start(w)},So.prototype._start=function(w){if(this._delta){this._frameId&&(this._frameId=null),this._active=!0,this.isZooming()||(this._zooming=!0),this._finishTimeout&&(clearTimeout(this._finishTimeout),delete this._finishTimeout);var M=s.mousePos(this._el,w);this._around=n.LngLat.convert(this._aroundCenter?this._map.getCenter():this._map.unproject(M)),this._aroundPoint=this._map.transform.locationPoint(this._around),this._frameId||(this._frameId=!0,this._handler._triggerRenderFrame())}},So.prototype.renderFrame=function(){var w=this;if(this._frameId&&(this._frameId=null,this.isActive())){var M=this._map.transform;if(this._delta!==0){var S=this._type==="wheel"&&Math.abs(this._delta)>4.000244140625?this._wheelZoomRate:this._defaultZoomRate,L=2/(1+Math.exp(-Math.abs(this._delta*S)));this._delta<0&&L!==0&&(L=1/L);var Y=typeof this._targetZoom=="number"?M.zoomScale(this._targetZoom):M.scale;this._targetZoom=Math.min(M.maxZoom,Math.max(M.minZoom,M.scaleZoom(Y*L))),this._type==="wheel"&&(this._startZoom=M.zoom,this._easing=this._smoothOutEasing(200)),this._delta=0}var ie,ae=typeof this._targetZoom=="number"?this._targetZoom:M.zoom,ge=this._startZoom,Pe=this._easing,Ue=!1;if(this._type==="wheel"&&ge&&Pe){var ct=Math.min((n.browser.now()-this._lastWheelEventTime)/200,1),ft=Pe(ct);ie=n.number(ge,ae,ft),ct<1?this._frameId||(this._frameId=!0):Ue=!0}else ie=ae,Ue=!0;return this._active=!0,Ue&&(this._active=!1,this._finishTimeout=setTimeout(function(){w._zooming=!1,w._handler._triggerRenderFrame(),delete w._targetZoom,delete w._finishTimeout},200)),{noInertia:!0,needsRenderFrame:!Ue,zoomDelta:ie-M.zoom,around:this._aroundPoint,originalEvent:this._lastWheelEvent}}},So.prototype._smoothOutEasing=function(w){var M=n.ease;if(this._prevEase){var S=this._prevEase,L=(n.browser.now()-S.start)/S.duration,Y=S.easing(L+.01)-S.easing(L),ie=.27/Math.sqrt(Y*Y+1e-4)*.01,ae=Math.sqrt(.0729-ie*ie);M=n.bezier(ie,ae,.25,1)}return this._prevEase={start:n.browser.now(),duration:w,easing:M},M},So.prototype.blur=function(){this.reset()},So.prototype.reset=function(){this._active=!1};var Lu=function(w,M){this._clickZoom=w,this._tapZoom=M};Lu.prototype.enable=function(){this._clickZoom.enable(),this._tapZoom.enable()},Lu.prototype.disable=function(){this._clickZoom.disable(),this._tapZoom.disable()},Lu.prototype.isEnabled=function(){return this._clickZoom.isEnabled()&&this._tapZoom.isEnabled()},Lu.prototype.isActive=function(){return this._clickZoom.isActive()||this._tapZoom.isActive()};var Nl=function(){this.reset()};Nl.prototype.reset=function(){this._active=!1},Nl.prototype.blur=function(){this.reset()},Nl.prototype.dblclick=function(w,M){return w.preventDefault(),{cameraAnimation:function(S){S.easeTo({duration:300,zoom:S.getZoom()+(w.shiftKey?-1:1),around:S.unproject(M)},{originalEvent:w})}}},Nl.prototype.enable=function(){this._enabled=!0},Nl.prototype.disable=function(){this._enabled=!1,this.reset()},Nl.prototype.isEnabled=function(){return this._enabled},Nl.prototype.isActive=function(){return this._active};var fa=function(){this._tap=new ru({numTouches:1,numTaps:1}),this.reset()};fa.prototype.reset=function(){this._active=!1,delete this._swipePoint,delete this._swipeTouch,delete this._tapTime,this._tap.reset()},fa.prototype.touchstart=function(w,M,S){this._swipePoint||(this._tapTime&&w.timeStamp-this._tapTime>500&&this.reset(),this._tapTime?S.length>0&&(this._swipePoint=M[0],this._swipeTouch=S[0].identifier):this._tap.touchstart(w,M,S))},fa.prototype.touchmove=function(w,M,S){if(this._tapTime){if(this._swipePoint){if(S[0].identifier!==this._swipeTouch)return;var L=M[0],Y=L.y-this._swipePoint.y;return this._swipePoint=L,w.preventDefault(),this._active=!0,{zoomDelta:Y/128}}}else this._tap.touchmove(w,M,S)},fa.prototype.touchend=function(w,M,S){this._tapTime?this._swipePoint&&S.length===0&&this.reset():this._tap.touchend(w,M,S)&&(this._tapTime=w.timeStamp)},fa.prototype.touchcancel=function(){this.reset()},fa.prototype.enable=function(){this._enabled=!0},fa.prototype.disable=function(){this._enabled=!1,this.reset()},fa.prototype.isEnabled=function(){return this._enabled},fa.prototype.isActive=function(){return this._active};var xf=function(w,M,S){this._el=w,this._mousePan=M,this._touchPan=S};xf.prototype.enable=function(w){this._inertiaOptions=w||{},this._mousePan.enable(),this._touchPan.enable(),this._el.classList.add("mapboxgl-touch-drag-pan")},xf.prototype.disable=function(){this._mousePan.disable(),this._touchPan.disable(),this._el.classList.remove("mapboxgl-touch-drag-pan")},xf.prototype.isEnabled=function(){return this._mousePan.isEnabled()&&this._touchPan.isEnabled()},xf.prototype.isActive=function(){return this._mousePan.isActive()||this._touchPan.isActive()};var Xf=function(w,M,S){this._pitchWithRotate=w.pitchWithRotate,this._mouseRotate=M,this._mousePitch=S};Xf.prototype.enable=function(){this._mouseRotate.enable(),this._pitchWithRotate&&this._mousePitch.enable()},Xf.prototype.disable=function(){this._mouseRotate.disable(),this._mousePitch.disable()},Xf.prototype.isEnabled=function(){return this._mouseRotate.isEnabled()&&(!this._pitchWithRotate||this._mousePitch.isEnabled())},Xf.prototype.isActive=function(){return this._mouseRotate.isActive()||this._mousePitch.isActive()};var Pc=function(w,M,S,L){this._el=w,this._touchZoom=M,this._touchRotate=S,this._tapDragZoom=L,this._rotationDisabled=!1,this._enabled=!0};Pc.prototype.enable=function(w){this._touchZoom.enable(w),this._rotationDisabled||this._touchRotate.enable(w),this._tapDragZoom.enable(),this._el.classList.add("mapboxgl-touch-zoom-rotate")},Pc.prototype.disable=function(){this._touchZoom.disable(),this._touchRotate.disable(),this._tapDragZoom.disable(),this._el.classList.remove("mapboxgl-touch-zoom-rotate")},Pc.prototype.isEnabled=function(){return this._touchZoom.isEnabled()&&(this._rotationDisabled||this._touchRotate.isEnabled())&&this._tapDragZoom.isEnabled()},Pc.prototype.isActive=function(){return this._touchZoom.isActive()||this._touchRotate.isActive()||this._tapDragZoom.isActive()},Pc.prototype.disableRotation=function(){this._rotationDisabled=!0,this._touchRotate.disable()},Pc.prototype.enableRotation=function(){this._rotationDisabled=!1,this._touchZoom.isEnabled()&&this._touchRotate.enable()};var El=function(w){return w.zoom||w.drag||w.pitch||w.rotate},Ku=function(w){function M(){w.apply(this,arguments)}return w&&(M.__proto__=w),(M.prototype=Object.create(w&&w.prototype)).constructor=M,M}(n.Event);function An(w){return w.panDelta&&w.panDelta.mag()||w.zoomDelta||w.bearingDelta||w.pitchDelta}var nn=function(w,M){this._map=w,this._el=this._map.getCanvasContainer(),this._handlers=[],this._handlersById={},this._changes=[],this._inertia=new Tl(w),this._bearingSnap=M.bearingSnap,this._previousActiveHandlers={},this._eventsInProgress={},this._addDefaultHandlers(M),n.bindAll(["handleEvent","handleWindowEvent"],this);var S=this._el;this._listeners=[[S,"touchstart",{passive:!0}],[S,"touchmove",{passive:!1}],[S,"touchend",void 0],[S,"touchcancel",void 0],[S,"mousedown",void 0],[S,"mousemove",void 0],[S,"mouseup",void 0],[n.window.document,"mousemove",{capture:!0}],[n.window.document,"mouseup",void 0],[S,"mouseover",void 0],[S,"mouseout",void 0],[S,"dblclick",void 0],[S,"click",void 0],[S,"keydown",{capture:!1}],[S,"keyup",void 0],[S,"wheel",{passive:!1}],[S,"contextmenu",void 0],[n.window,"blur",void 0]];for(var L=0,Y=this._listeners;Lae?Math.min(2,Wr):Math.max(.5,Wr),bn=Math.pow($i,1-Ci),Tn=ie.unproject(kr.add(Lr.mult(Ci*bn)).mult(Si));ie.setLocationAtPoint(ie.renderWorldCopies?Tn.wrap():Tn,Wt)}Y._fireMoveEvents(L)},function(Ci){Y._afterEase(L,Ci)},S),this},M.prototype._prepareEase=function(S,L,Y){Y===void 0&&(Y={}),this._moving=!0,L||Y.moving||this.fire(new n.Event("movestart",S)),this._zooming&&!Y.zooming&&this.fire(new n.Event("zoomstart",S)),this._rotating&&!Y.rotating&&this.fire(new n.Event("rotatestart",S)),this._pitching&&!Y.pitching&&this.fire(new n.Event("pitchstart",S))},M.prototype._fireMoveEvents=function(S){this.fire(new n.Event("move",S)),this._zooming&&this.fire(new n.Event("zoom",S)),this._rotating&&this.fire(new n.Event("rotate",S)),this._pitching&&this.fire(new n.Event("pitch",S))},M.prototype._afterEase=function(S,L){if(!this._easeId||!L||this._easeId!==L){delete this._easeId;var Y=this._zooming,ie=this._rotating,ae=this._pitching;this._moving=!1,this._zooming=!1,this._rotating=!1,this._pitching=!1,this._padding=!1,Y&&this.fire(new n.Event("zoomend",S)),ie&&this.fire(new n.Event("rotateend",S)),ae&&this.fire(new n.Event("pitchend",S)),this.fire(new n.Event("moveend",S))}},M.prototype.flyTo=function(S,L){var Y=this;if(!S.essential&&n.browser.prefersReducedMotion){var ie=n.pick(S,["center","zoom","bearing","pitch","around"]);return this.jumpTo(ie,L)}this.stop(),S=n.extend({offset:[0,0],speed:1.2,curve:1.42,easing:n.ease},S);var ae=this.transform,ge=this.getZoom(),Pe=this.getBearing(),Ue=this.getPitch(),ct=this.getPadding(),ft="zoom"in S?n.clamp(+S.zoom,ae.minZoom,ae.maxZoom):ge,gt="bearing"in S?this._normalizeBearing(S.bearing,Pe):Pe,ut="pitch"in S?+S.pitch:Ue,Pt="padding"in S?S.padding:ae.padding,Wt=ae.zoomScale(ft-ge),St=n.Point.convert(S.offset),Zt=ae.centerPoint.add(St),ir=ae.pointLocation(Zt),dr=n.LngLat.convert(S.center||ir);this._normalizeCenter(dr);var kr=ae.project(ir),Lr=ae.project(dr).sub(kr),Wr=S.curve,ai=Math.max(ae.width,ae.height),Ci=ai/Wt,Si=Lr.mag();if("minZoom"in S){var $i=n.clamp(Math.min(S.minZoom,ge,ft),ae.minZoom,ae.maxZoom),bn=ai/ae.zoomScale($i-ge);Wr=Math.sqrt(bn/Si*2)}var Tn=Wr*Wr;function xn(Dn){var Rn=(Ci*Ci-ai*ai+(Dn?-1:1)*Tn*Tn*Si*Si)/(2*(Dn?Ci:ai)*Tn*Si);return Math.log(Math.sqrt(Rn*Rn+1)-Rn)}function zo(Dn){return(Math.exp(Dn)-Math.exp(-Dn))/2}function qi(Dn){return(Math.exp(Dn)+Math.exp(-Dn))/2}var Sn=xn(0),$n=function(Dn){return qi(Sn)/qi(Sn+Wr*Dn)},Gi=function(Dn){return ai*((qi(Sn)*(zo(Rn=Sn+Wr*Dn)/qi(Rn))-zo(Sn))/Tn)/Si;var Rn},Hn=(xn(1)-Sn)/Wr;if(Math.abs(Si)<1e-6||!isFinite(Hn)){if(Math.abs(ai-Ci)<1e-6)return this.easeTo(S,L);var eo=CiS.maxDuration&&(S.duration=0),this._zooming=!0,this._rotating=Pe!==gt,this._pitching=ut!==Ue,this._padding=!ae.isPaddingEqual(Pt),this._prepareEase(L,!1),this._ease(function(Dn){var Rn=Dn*Hn,Il=1/$n(Rn);ae.zoom=Dn===1?ft:ge+ae.scaleZoom(Il),Y._rotating&&(ae.bearing=n.number(Pe,gt,Dn)),Y._pitching&&(ae.pitch=n.number(Ue,ut,Dn)),Y._padding&&(ae.interpolatePadding(ct,Pt,Dn),Zt=ae.centerPoint.add(St));var Ga=Dn===1?dr:ae.unproject(kr.add(Lr.mult(Gi(Rn))).mult(Il));ae.setLocationAtPoint(ae.renderWorldCopies?Ga.wrap():Ga,Zt),Y._fireMoveEvents(L)},function(){return Y._afterEase(L)},S),this},M.prototype.isEasing=function(){return!!this._easeFrameId},M.prototype.stop=function(){return this._stop()},M.prototype._stop=function(S,L){if(this._easeFrameId&&(this._cancelRenderFrame(this._easeFrameId),delete this._easeFrameId,delete this._onEaseFrame),this._onEaseEnd){var Y=this._onEaseEnd;delete this._onEaseEnd,Y.call(this,L)}if(!S){var ie=this.handlers;ie&&ie.stop(!1)}return this},M.prototype._ease=function(S,L,Y){Y.animate===!1||Y.duration===0?(S(1),L()):(this._easeStart=n.browser.now(),this._easeOptions=Y,this._onEaseFrame=S,this._onEaseEnd=L,this._easeFrameId=this._requestRenderFrame(this._renderFrameCallback))},M.prototype._renderFrameCallback=function(){var S=Math.min((n.browser.now()-this._easeStart)/this._easeOptions.duration,1);this._onEaseFrame(this._easeOptions.easing(S)),S<1?this._easeFrameId=this._requestRenderFrame(this._renderFrameCallback):this.stop()},M.prototype._normalizeBearing=function(S,L){S=n.wrap(S,-180,180);var Y=Math.abs(S-L);return Math.abs(S-360-L)180?-360:Y<-180?360:0}},M}(n.Evented),Vc=function(w){w===void 0&&(w={}),this.options=w,n.bindAll(["_toggleAttribution","_updateEditLink","_updateData","_updateCompact"],this)};Vc.prototype.getDefaultPosition=function(){return"bottom-right"},Vc.prototype.onAdd=function(w){var M=this.options&&this.options.compact;return this._map=w,this._container=s.create("div","mapboxgl-ctrl mapboxgl-ctrl-attrib"),this._compactButton=s.create("button","mapboxgl-ctrl-attrib-button",this._container),this._compactButton.addEventListener("click",this._toggleAttribution),this._setElementTitle(this._compactButton,"ToggleAttribution"),this._innerContainer=s.create("div","mapboxgl-ctrl-attrib-inner",this._container),this._innerContainer.setAttribute("role","list"),M&&this._container.classList.add("mapboxgl-compact"),this._updateAttributions(),this._updateEditLink(),this._map.on("styledata",this._updateData),this._map.on("sourcedata",this._updateData),this._map.on("moveend",this._updateEditLink),M===void 0&&(this._map.on("resize",this._updateCompact),this._updateCompact()),this._container},Vc.prototype.onRemove=function(){s.remove(this._container),this._map.off("styledata",this._updateData),this._map.off("sourcedata",this._updateData),this._map.off("moveend",this._updateEditLink),this._map.off("resize",this._updateCompact),this._map=void 0,this._attribHTML=void 0},Vc.prototype._setElementTitle=function(w,M){var S=this._map._getUIString("AttributionControl."+M);w.title=S,w.setAttribute("aria-label",S)},Vc.prototype._toggleAttribution=function(){this._container.classList.contains("mapboxgl-compact-show")?(this._container.classList.remove("mapboxgl-compact-show"),this._compactButton.setAttribute("aria-pressed","false")):(this._container.classList.add("mapboxgl-compact-show"),this._compactButton.setAttribute("aria-pressed","true"))},Vc.prototype._updateEditLink=function(){var w=this._editLink;w||(w=this._editLink=this._container.querySelector(".mapbox-improve-map"));var M=[{key:"owner",value:this.styleOwner},{key:"id",value:this.styleId},{key:"access_token",value:this._map._requestManager._customAccessToken||n.config.ACCESS_TOKEN}];if(w){var S=M.reduce(function(L,Y,ie){return Y.value&&(L+=Y.key+"="+Y.value+(ie=0)return!1;return!0})).join(" | ");ae!==this._attribHTML&&(this._attribHTML=ae,w.length?(this._innerContainer.innerHTML=ae,this._container.classList.remove("mapboxgl-attrib-empty")):this._container.classList.add("mapboxgl-attrib-empty"),this._editLink=null)}},Vc.prototype._updateCompact=function(){this._map.getCanvasContainer().offsetWidth<=640?this._container.classList.add("mapboxgl-compact"):this._container.classList.remove("mapboxgl-compact","mapboxgl-compact-show")};var Au=function(){n.bindAll(["_updateLogo"],this),n.bindAll(["_updateCompact"],this)};Au.prototype.onAdd=function(w){this._map=w,this._container=s.create("div","mapboxgl-ctrl");var M=s.create("a","mapboxgl-ctrl-logo");return M.target="_blank",M.rel="noopener nofollow",M.href="https://www.mapbox.com/",M.setAttribute("aria-label",this._map._getUIString("LogoControl.Title")),M.setAttribute("rel","noopener nofollow"),this._container.appendChild(M),this._container.style.display="none",this._map.on("sourcedata",this._updateLogo),this._updateLogo(),this._map.on("resize",this._updateCompact),this._updateCompact(),this._container},Au.prototype.onRemove=function(){s.remove(this._container),this._map.off("sourcedata",this._updateLogo),this._map.off("resize",this._updateCompact)},Au.prototype.getDefaultPosition=function(){return"bottom-left"},Au.prototype._updateLogo=function(w){w&&w.sourceDataType!=="metadata"||(this._container.style.display=this._logoRequired()?"block":"none")},Au.prototype._logoRequired=function(){if(this._map.style){var w=this._map.style.sourceCaches;for(var M in w)if(w[M].getSource().mapbox_logo)return!0;return!1}},Au.prototype._updateCompact=function(){var w=this._container.children;if(w.length){var M=w[0];this._map.getCanvasContainer().offsetWidth<250?M.classList.add("mapboxgl-compact"):M.classList.remove("mapboxgl-compact")}};var Cl=function(){this._queue=[],this._id=0,this._cleared=!1,this._currentlyRunning=!1};Cl.prototype.add=function(w){var M=++this._id;return this._queue.push({callback:w,id:M,cancelled:!1}),M},Cl.prototype.remove=function(w){for(var M=this._currentlyRunning,S=0,L=M?this._queue.concat(M):this._queue;SL.maxZoom)throw new Error("maxZoom must be greater than or equal to minZoom");if(L.minPitch!=null&&L.maxPitch!=null&&L.minPitch>L.maxPitch)throw new Error("maxPitch must be greater than or equal to minPitch");if(L.minPitch!=null&&L.minPitch<0)throw new Error("minPitch must be greater than or equal to 0");if(L.maxPitch!=null&&L.maxPitch>60)throw new Error("maxPitch must be less than or equal to 60");var ie=new Hi(L.minZoom,L.maxZoom,L.minPitch,L.maxPitch,L.renderWorldCopies);if(w.call(this,ie,L),this._interactive=L.interactive,this._maxTileCacheSize=L.maxTileCacheSize,this._failIfMajorPerformanceCaveat=L.failIfMajorPerformanceCaveat,this._preserveDrawingBuffer=L.preserveDrawingBuffer,this._antialias=L.antialias,this._trackResize=L.trackResize,this._bearingSnap=L.bearingSnap,this._refreshExpiredTiles=L.refreshExpiredTiles,this._fadeDuration=L.fadeDuration,this._crossSourceCollisions=L.crossSourceCollisions,this._crossFadingFactor=1,this._collectResourceTiming=L.collectResourceTiming,this._renderTaskQueue=new Cl,this._controls=[],this._mapId=n.uniqueId(),this._locale=n.extend({},Zh,L.locale),this._clickTolerance=L.clickTolerance,this._requestManager=new n.RequestManager(L.transformRequest,L.accessToken),typeof L.container=="string"){if(this._container=n.window.document.getElementById(L.container),!this._container)throw new Error("Container '"+L.container+"' not found.")}else{if(!(L.container instanceof Ha))throw new Error("Invalid type: 'container' must be a String or HTMLElement.");this._container=L.container}if(L.maxBounds&&this.setMaxBounds(L.maxBounds),n.bindAll(["_onWindowOnline","_onWindowResize","_onMapScroll","_contextLost","_contextRestored"],this),this._setupContainer(),this._setupPainter(),this.painter===void 0)throw new Error("Failed to initialize WebGL.");this.on("move",function(){return Y._update(!1)}),this.on("moveend",function(){return Y._update(!1)}),this.on("zoom",function(){return Y._update(!0)}),n.window!==void 0&&(n.window.addEventListener("online",this._onWindowOnline,!1),n.window.addEventListener("resize",this._onWindowResize,!1),n.window.addEventListener("orientationchange",this._onWindowResize,!1)),this.handlers=new nn(this,L),this._hash=L.hash&&new Kn(typeof L.hash=="string"&&L.hash||void 0).addTo(this),this._hash&&this._hash._onHashChange()||(this.jumpTo({center:L.center,zoom:L.zoom,bearing:L.bearing,pitch:L.pitch}),L.bounds&&(this.resize(),this.fitBounds(L.bounds,n.extend({},L.fitBoundsOptions,{duration:0})))),this.resize(),this._localIdeographFontFamily=L.localIdeographFontFamily,L.style&&this.setStyle(L.style,{localIdeographFontFamily:L.localIdeographFontFamily}),L.attributionControl&&this.addControl(new Vc({customAttribution:L.customAttribution})),this.addControl(new Au,L.logoPosition),this.on("style.load",function(){Y.transform.unmodified&&Y.jumpTo(Y.style.stylesheet)}),this.on("data",function(ae){Y._update(ae.dataType==="style"),Y.fire(new n.Event(ae.dataType+"data",ae))}),this.on("dataloading",function(ae){Y.fire(new n.Event(ae.dataType+"dataloading",ae))})}w&&(M.__proto__=w),(M.prototype=Object.create(w&&w.prototype)).constructor=M;var S={showTileBoundaries:{configurable:!0},showPadding:{configurable:!0},showCollisionBoxes:{configurable:!0},showOverdrawInspector:{configurable:!0},repaint:{configurable:!0},vertices:{configurable:!0},version:{configurable:!0}};return M.prototype._getMapId=function(){return this._mapId},M.prototype.addControl=function(L,Y){if(Y===void 0&&(Y=L.getDefaultPosition?L.getDefaultPosition():"top-right"),!L||!L.onAdd)return this.fire(new n.ErrorEvent(new Error("Invalid argument to map.addControl(). Argument must be a control with onAdd and onRemove methods.")));var ie=L.onAdd(this);this._controls.push(L);var ae=this._controlPositions[Y];return Y.indexOf("bottom")!==-1?ae.insertBefore(ie,ae.firstChild):ae.appendChild(ie),this},M.prototype.removeControl=function(L){if(!L||!L.onRemove)return this.fire(new n.ErrorEvent(new Error("Invalid argument to map.removeControl(). Argument must be a control with onAdd and onRemove methods.")));var Y=this._controls.indexOf(L);return Y>-1&&this._controls.splice(Y,1),L.onRemove(this),this},M.prototype.hasControl=function(L){return this._controls.indexOf(L)>-1},M.prototype.resize=function(L){var Y=this._containerDimensions(),ie=Y[0],ae=Y[1];if(ie===this.transform.width&&ae===this.transform.height)return this;this._resizeCanvas(ie,ae),this.transform.resize(ie,ae),this.painter.resize(ie,ae);var ge=!this._moving;return ge&&this.fire(new n.Event("movestart",L)).fire(new n.Event("move",L)),this.fire(new n.Event("resize",L)),ge&&this.fire(new n.Event("moveend",L)),this},M.prototype.getBounds=function(){return this.transform.getBounds()},M.prototype.getMaxBounds=function(){return this.transform.getMaxBounds()},M.prototype.setMaxBounds=function(L){return this.transform.setMaxBounds(n.LngLatBounds.convert(L)),this._update()},M.prototype.setMinZoom=function(L){if((L=L??-2)>=-2&&L<=this.transform.maxZoom)return this.transform.minZoom=L,this._update(),this.getZoom()=this.transform.minZoom)return this.transform.maxZoom=L,this._update(),this.getZoom()>L&&this.setZoom(L),this;throw new Error("maxZoom must be greater than the current minZoom")},M.prototype.getMaxZoom=function(){return this.transform.maxZoom},M.prototype.setMinPitch=function(L){if((L=L??0)<0)throw new Error("minPitch must be greater than or equal to 0");if(L>=0&&L<=this.transform.maxPitch)return this.transform.minPitch=L,this._update(),this.getPitch()60)throw new Error("maxPitch must be less than or equal to 60");if(L>=this.transform.minPitch)return this.transform.maxPitch=L,this._update(),this.getPitch()>L&&this.setPitch(L),this;throw new Error("maxPitch must be greater than the current minPitch")},M.prototype.getMaxPitch=function(){return this.transform.maxPitch},M.prototype.getRenderWorldCopies=function(){return this.transform.renderWorldCopies},M.prototype.setRenderWorldCopies=function(L){return this.transform.renderWorldCopies=L,this._update()},M.prototype.project=function(L){return this.transform.locationPoint(n.LngLat.convert(L))},M.prototype.unproject=function(L){return this.transform.pointLocation(n.Point.convert(L))},M.prototype.isMoving=function(){return this._moving||this.handlers.isMoving()},M.prototype.isZooming=function(){return this._zooming||this.handlers.isZooming()},M.prototype.isRotating=function(){return this._rotating||this.handlers.isRotating()},M.prototype._createDelegatedListener=function(L,Y,ie){var ae,ge=this;if(L==="mouseenter"||L==="mouseover"){var Pe=!1;return{layer:Y,listener:ie,delegates:{mousemove:function(ct){var ft=ge.getLayer(Y)?ge.queryRenderedFeatures(ct.point,{layers:[Y]}):[];ft.length?Pe||(Pe=!0,ie.call(ge,new Sl(L,ge,ct.originalEvent,{features:ft}))):Pe=!1},mouseout:function(){Pe=!1}}}}if(L==="mouseleave"||L==="mouseout"){var Ue=!1;return{layer:Y,listener:ie,delegates:{mousemove:function(ct){(ge.getLayer(Y)?ge.queryRenderedFeatures(ct.point,{layers:[Y]}):[]).length?Ue=!0:Ue&&(Ue=!1,ie.call(ge,new Sl(L,ge,ct.originalEvent)))},mouseout:function(ct){Ue&&(Ue=!1,ie.call(ge,new Sl(L,ge,ct.originalEvent)))}}}}return{layer:Y,listener:ie,delegates:(ae={},ae[L]=function(ct){var ft=ge.getLayer(Y)?ge.queryRenderedFeatures(ct.point,{layers:[Y]}):[];ft.length&&(ct.features=ft,ie.call(ge,ct),delete ct.features)},ae)}},M.prototype.on=function(L,Y,ie){if(ie===void 0)return w.prototype.on.call(this,L,Y);var ae=this._createDelegatedListener(L,Y,ie);for(var ge in this._delegatedListeners=this._delegatedListeners||{},this._delegatedListeners[L]=this._delegatedListeners[L]||[],this._delegatedListeners[L].push(ae),ae.delegates)this.on(ge,ae.delegates[ge]);return this},M.prototype.once=function(L,Y,ie){if(ie===void 0)return w.prototype.once.call(this,L,Y);var ae=this._createDelegatedListener(L,Y,ie);for(var ge in ae.delegates)this.once(ge,ae.delegates[ge]);return this},M.prototype.off=function(L,Y,ie){var ae=this;return ie===void 0?w.prototype.off.call(this,L,Y):(this._delegatedListeners&&this._delegatedListeners[L]&&function(ge){for(var Pe=ge[L],Ue=0;Ue180;){var ae=S.locationPoint(w);if(ae.x>=0&&ae.y>=0&&ae.x<=S.width&&ae.y<=S.height)break;w.lng>S.center.lng?w.lng-=360:w.lng+=360}return w}Rc.prototype.down=function(w,M){this.mouseRotate.mousedown(w,M),this.mousePitch&&this.mousePitch.mousedown(w,M),s.disableDrag()},Rc.prototype.move=function(w,M){var S=this.map,L=this.mouseRotate.mousemoveWindow(w,M);if(L&&L.bearingDelta&&S.setBearing(S.getBearing()+L.bearingDelta),this.mousePitch){var Y=this.mousePitch.mousemoveWindow(w,M);Y&&Y.pitchDelta&&S.setPitch(S.getPitch()+Y.pitchDelta)}},Rc.prototype.off=function(){var w=this.element;s.removeEventListener(w,"mousedown",this.mousedown),s.removeEventListener(w,"touchstart",this.touchstart,{passive:!1}),s.removeEventListener(w,"touchmove",this.touchmove),s.removeEventListener(w,"touchend",this.touchend),s.removeEventListener(w,"touchcancel",this.reset),this.offTemp()},Rc.prototype.offTemp=function(){s.enableDrag(),s.removeEventListener(n.window,"mousemove",this.mousemove),s.removeEventListener(n.window,"mouseup",this.mouseup)},Rc.prototype.mousedown=function(w){this.down(n.extend({},w,{ctrlKey:!0,preventDefault:function(){return w.preventDefault()}}),s.mousePos(this.element,w)),s.addEventListener(n.window,"mousemove",this.mousemove),s.addEventListener(n.window,"mouseup",this.mouseup)},Rc.prototype.mousemove=function(w){this.move(w,s.mousePos(this.element,w))},Rc.prototype.mouseup=function(w){this.mouseRotate.mouseupWindow(w),this.mousePitch&&this.mousePitch.mouseupWindow(w),this.offTemp()},Rc.prototype.touchstart=function(w){w.targetTouches.length!==1?this.reset():(this._startPos=this._lastPos=s.touchPos(this.element,w.targetTouches)[0],this.down({type:"mousedown",button:0,ctrlKey:!0,preventDefault:function(){return w.preventDefault()}},this._startPos))},Rc.prototype.touchmove=function(w){w.targetTouches.length!==1?this.reset():(this._lastPos=s.touchPos(this.element,w.targetTouches)[0],this.move({preventDefault:function(){return w.preventDefault()}},this._lastPos))},Rc.prototype.touchend=function(w){w.targetTouches.length===0&&this._startPos&&this._lastPos&&this._startPos.dist(this._lastPos)=L}this._isDragging&&(this._pos=S.point.sub(this._positionDelta),this._lngLat=this._map.unproject(this._pos),this.setLngLat(this._lngLat),this._element.style.pointerEvents="none",this._state==="pending"&&(this._state="active",this.fire(new n.Event("dragstart"))),this.fire(new n.Event("drag")))},M.prototype._onUp=function(){this._element.style.pointerEvents="auto",this._positionDelta=null,this._pointerdownPos=null,this._isDragging=!1,this._map.off("mousemove",this._onMove),this._map.off("touchmove",this._onMove),this._state==="active"&&this.fire(new n.Event("dragend")),this._state="inactive"},M.prototype._addDragHandler=function(S){this._element.contains(S.originalEvent.target)&&(S.preventDefault(),this._positionDelta=S.point.sub(this._pos).add(this._offset),this._pointerdownPos=S.point,this._state="pending",this._map.on("mousemove",this._onMove),this._map.on("touchmove",this._onMove),this._map.once("mouseup",this._onUp),this._map.once("touchend",this._onUp))},M.prototype.setDraggable=function(S){return this._draggable=!!S,this._map&&(S?(this._map.on("mousedown",this._addDragHandler),this._map.on("touchstart",this._addDragHandler)):(this._map.off("mousedown",this._addDragHandler),this._map.off("touchstart",this._addDragHandler))),this},M.prototype.isDraggable=function(){return this._draggable},M.prototype.setRotation=function(S){return this._rotation=S||0,this._update(),this},M.prototype.getRotation=function(){return this._rotation},M.prototype.setRotationAlignment=function(S){return this._rotationAlignment=S||"auto",this._update(),this},M.prototype.getRotationAlignment=function(){return this._rotationAlignment},M.prototype.setPitchAlignment=function(S){return this._pitchAlignment=S&&S!=="auto"?S:this._rotationAlignment,this._update(),this},M.prototype.getPitchAlignment=function(){return this._pitchAlignment},M}(n.Evented),mm={positionOptions:{enableHighAccuracy:!1,maximumAge:0,timeout:6e3},fitBoundsOptions:{maxZoom:15},trackUserLocation:!1,showAccuracyCircle:!0,showUserLocation:!0},xh=0,Qu=!1,Yd=function(w){function M(S){w.call(this),this.options=n.extend({},mm,S),n.bindAll(["_onSuccess","_onError","_onZoom","_finish","_setupUI","_updateCamera","_updateMarker"],this)}return w&&(M.__proto__=w),(M.prototype=Object.create(w&&w.prototype)).constructor=M,M.prototype.onAdd=function(S){var L;return this._map=S,this._container=s.create("div","mapboxgl-ctrl mapboxgl-ctrl-group"),L=this._setupUI,Zd!==void 0?L(Zd):n.window.navigator.permissions!==void 0?n.window.navigator.permissions.query({name:"geolocation"}).then(function(Y){L(Zd=Y.state!=="denied")}):L(Zd=!!n.window.navigator.geolocation),this._container},M.prototype.onRemove=function(){this._geolocationWatchID!==void 0&&(n.window.navigator.geolocation.clearWatch(this._geolocationWatchID),this._geolocationWatchID=void 0),this.options.showUserLocation&&this._userLocationDotMarker&&this._userLocationDotMarker.remove(),this.options.showAccuracyCircle&&this._accuracyCircleMarker&&this._accuracyCircleMarker.remove(),s.remove(this._container),this._map.off("zoom",this._onZoom),this._map=void 0,xh=0,Qu=!1},M.prototype._isOutOfMapMaxBounds=function(S){var L=this._map.getMaxBounds(),Y=S.coords;return L&&(Y.longitudeL.getEast()||Y.latitudeL.getNorth())},M.prototype._setErrorState=function(){switch(this._watchState){case"WAITING_ACTIVE":this._watchState="ACTIVE_ERROR",this._geolocateButton.classList.remove("mapboxgl-ctrl-geolocate-active"),this._geolocateButton.classList.add("mapboxgl-ctrl-geolocate-active-error");break;case"ACTIVE_LOCK":this._watchState="ACTIVE_ERROR",this._geolocateButton.classList.remove("mapboxgl-ctrl-geolocate-active"),this._geolocateButton.classList.add("mapboxgl-ctrl-geolocate-active-error"),this._geolocateButton.classList.add("mapboxgl-ctrl-geolocate-waiting");break;case"BACKGROUND":this._watchState="BACKGROUND_ERROR",this._geolocateButton.classList.remove("mapboxgl-ctrl-geolocate-background"),this._geolocateButton.classList.add("mapboxgl-ctrl-geolocate-background-error"),this._geolocateButton.classList.add("mapboxgl-ctrl-geolocate-waiting")}},M.prototype._onSuccess=function(S){if(this._map){if(this._isOutOfMapMaxBounds(S))return this._setErrorState(),this.fire(new n.Event("outofmaxbounds",S)),this._updateMarker(),void this._finish();if(this.options.trackUserLocation)switch(this._lastKnownPosition=S,this._watchState){case"WAITING_ACTIVE":case"ACTIVE_LOCK":case"ACTIVE_ERROR":this._watchState="ACTIVE_LOCK",this._geolocateButton.classList.remove("mapboxgl-ctrl-geolocate-waiting"),this._geolocateButton.classList.remove("mapboxgl-ctrl-geolocate-active-error"),this._geolocateButton.classList.add("mapboxgl-ctrl-geolocate-active");break;case"BACKGROUND":case"BACKGROUND_ERROR":this._watchState="BACKGROUND",this._geolocateButton.classList.remove("mapboxgl-ctrl-geolocate-waiting"),this._geolocateButton.classList.remove("mapboxgl-ctrl-geolocate-background-error"),this._geolocateButton.classList.add("mapboxgl-ctrl-geolocate-background")}this.options.showUserLocation&&this._watchState!=="OFF"&&this._updateMarker(S),this.options.trackUserLocation&&this._watchState!=="ACTIVE_LOCK"||this._updateCamera(S),this.options.showUserLocation&&this._dotElement.classList.remove("mapboxgl-user-location-dot-stale"),this.fire(new n.Event("geolocate",S)),this._finish()}},M.prototype._updateCamera=function(S){var L=new n.LngLat(S.coords.longitude,S.coords.latitude),Y=S.coords.accuracy,ie=this._map.getBearing(),ae=n.extend({bearing:ie},this.options.fitBoundsOptions);this._map.fitBounds(L.toBounds(Y),ae,{geolocateSource:!0})},M.prototype._updateMarker=function(S){if(S){var L=new n.LngLat(S.coords.longitude,S.coords.latitude);this._accuracyCircleMarker.setLngLat(L).addTo(this._map),this._userLocationDotMarker.setLngLat(L).addTo(this._map),this._accuracy=S.coords.accuracy,this.options.showUserLocation&&this.options.showAccuracyCircle&&this._updateCircleRadius()}else this._userLocationDotMarker.remove(),this._accuracyCircleMarker.remove()},M.prototype._updateCircleRadius=function(){var S=this._map._container.clientHeight/2,L=this._map.unproject([0,S]),Y=this._map.unproject([1,S]),ie=L.distanceTo(Y),ae=Math.ceil(2*this._accuracy/ie);this._circleElement.style.width=ae+"px",this._circleElement.style.height=ae+"px"},M.prototype._onZoom=function(){this.options.showUserLocation&&this.options.showAccuracyCircle&&this._updateCircleRadius()},M.prototype._onError=function(S){if(this._map){if(this.options.trackUserLocation)if(S.code===1){this._watchState="OFF",this._geolocateButton.classList.remove("mapboxgl-ctrl-geolocate-waiting"),this._geolocateButton.classList.remove("mapboxgl-ctrl-geolocate-active"),this._geolocateButton.classList.remove("mapboxgl-ctrl-geolocate-active-error"),this._geolocateButton.classList.remove("mapboxgl-ctrl-geolocate-background"),this._geolocateButton.classList.remove("mapboxgl-ctrl-geolocate-background-error"),this._geolocateButton.disabled=!0;var L=this._map._getUIString("GeolocateControl.LocationNotAvailable");this._geolocateButton.title=L,this._geolocateButton.setAttribute("aria-label",L),this._geolocationWatchID!==void 0&&this._clearWatch()}else{if(S.code===3&&Qu)return;this._setErrorState()}this._watchState!=="OFF"&&this.options.showUserLocation&&this._dotElement.classList.add("mapboxgl-user-location-dot-stale"),this.fire(new n.Event("error",S)),this._finish()}},M.prototype._finish=function(){this._timeoutId&&clearTimeout(this._timeoutId),this._timeoutId=void 0},M.prototype._setupUI=function(S){var L=this;if(this._container.addEventListener("contextmenu",function(ae){return ae.preventDefault()}),this._geolocateButton=s.create("button","mapboxgl-ctrl-geolocate",this._container),s.create("span","mapboxgl-ctrl-icon",this._geolocateButton).setAttribute("aria-hidden",!0),this._geolocateButton.type="button",S===!1){n.warnOnce("Geolocation support is not available so the GeolocateControl will be disabled.");var Y=this._map._getUIString("GeolocateControl.LocationNotAvailable");this._geolocateButton.disabled=!0,this._geolocateButton.title=Y,this._geolocateButton.setAttribute("aria-label",Y)}else{var ie=this._map._getUIString("GeolocateControl.FindMyLocation");this._geolocateButton.title=ie,this._geolocateButton.setAttribute("aria-label",ie)}this.options.trackUserLocation&&(this._geolocateButton.setAttribute("aria-pressed","false"),this._watchState="OFF"),this.options.showUserLocation&&(this._dotElement=s.create("div","mapboxgl-user-location-dot"),this._userLocationDotMarker=new xd(this._dotElement),this._circleElement=s.create("div","mapboxgl-user-location-accuracy-circle"),this._accuracyCircleMarker=new xd({element:this._circleElement,pitchAlignment:"map"}),this.options.trackUserLocation&&(this._watchState="OFF"),this._map.on("zoom",this._onZoom)),this._geolocateButton.addEventListener("click",this.trigger.bind(this)),this._setup=!0,this.options.trackUserLocation&&this._map.on("movestart",function(ae){ae.geolocateSource||L._watchState!=="ACTIVE_LOCK"||ae.originalEvent&&ae.originalEvent.type==="resize"||(L._watchState="BACKGROUND",L._geolocateButton.classList.add("mapboxgl-ctrl-geolocate-background"),L._geolocateButton.classList.remove("mapboxgl-ctrl-geolocate-active"),L.fire(new n.Event("trackuserlocationend")))})},M.prototype.trigger=function(){if(!this._setup)return n.warnOnce("Geolocate control triggered before added to a map"),!1;if(this.options.trackUserLocation){switch(this._watchState){case"OFF":this._watchState="WAITING_ACTIVE",this.fire(new n.Event("trackuserlocationstart"));break;case"WAITING_ACTIVE":case"ACTIVE_LOCK":case"ACTIVE_ERROR":case"BACKGROUND_ERROR":xh--,Qu=!1,this._watchState="OFF",this._geolocateButton.classList.remove("mapboxgl-ctrl-geolocate-waiting"),this._geolocateButton.classList.remove("mapboxgl-ctrl-geolocate-active"),this._geolocateButton.classList.remove("mapboxgl-ctrl-geolocate-active-error"),this._geolocateButton.classList.remove("mapboxgl-ctrl-geolocate-background"),this._geolocateButton.classList.remove("mapboxgl-ctrl-geolocate-background-error"),this.fire(new n.Event("trackuserlocationend"));break;case"BACKGROUND":this._watchState="ACTIVE_LOCK",this._geolocateButton.classList.remove("mapboxgl-ctrl-geolocate-background"),this._lastKnownPosition&&this._updateCamera(this._lastKnownPosition),this.fire(new n.Event("trackuserlocationstart"))}switch(this._watchState){case"WAITING_ACTIVE":this._geolocateButton.classList.add("mapboxgl-ctrl-geolocate-waiting"),this._geolocateButton.classList.add("mapboxgl-ctrl-geolocate-active");break;case"ACTIVE_LOCK":this._geolocateButton.classList.add("mapboxgl-ctrl-geolocate-active");break;case"ACTIVE_ERROR":this._geolocateButton.classList.add("mapboxgl-ctrl-geolocate-waiting"),this._geolocateButton.classList.add("mapboxgl-ctrl-geolocate-active-error");break;case"BACKGROUND":this._geolocateButton.classList.add("mapboxgl-ctrl-geolocate-background");break;case"BACKGROUND_ERROR":this._geolocateButton.classList.add("mapboxgl-ctrl-geolocate-waiting"),this._geolocateButton.classList.add("mapboxgl-ctrl-geolocate-background-error")}if(this._watchState==="OFF"&&this._geolocationWatchID!==void 0)this._clearWatch();else if(this._geolocationWatchID===void 0){var S;this._geolocateButton.classList.add("mapboxgl-ctrl-geolocate-waiting"),this._geolocateButton.setAttribute("aria-pressed","true"),++xh>1?(S={maximumAge:6e5,timeout:0},Qu=!0):(S=this.options.positionOptions,Qu=!1),this._geolocationWatchID=n.window.navigator.geolocation.watchPosition(this._onSuccess,this._onError,S)}}else n.window.navigator.geolocation.getCurrentPosition(this._onSuccess,this._onError,this.options.positionOptions),this._timeoutId=setTimeout(this._finish,1e4);return!0},M.prototype._clearWatch=function(){n.window.navigator.geolocation.clearWatch(this._geolocationWatchID),this._geolocationWatchID=void 0,this._geolocateButton.classList.remove("mapboxgl-ctrl-geolocate-waiting"),this._geolocateButton.setAttribute("aria-pressed","false"),this.options.showUserLocation&&this._updateMarker(null)},M}(n.Evented),Kh={maxWidth:100,unit:"metric"},bh=function(w){this.options=n.extend({},Kh,w),n.bindAll(["_onMove","setUnit"],this)};function Rp(w,M,S){var L=S&&S.maxWidth||100,Y=w._container.clientHeight/2,ie=w.unproject([0,Y]),ae=w.unproject([L,Y]),ge=ie.distanceTo(ae);if(S&&S.unit==="imperial"){var Pe=3.2808*ge;Pe>5280?bf(M,L,Pe/5280,w._getUIString("ScaleControl.Miles")):bf(M,L,Pe,w._getUIString("ScaleControl.Feet"))}else S&&S.unit==="nautical"?bf(M,L,ge/1852,w._getUIString("ScaleControl.NauticalMiles")):ge>=1e3?bf(M,L,ge/1e3,w._getUIString("ScaleControl.Kilometers")):bf(M,L,ge,w._getUIString("ScaleControl.Meters"))}function bf(w,M,S,L){var Y,ie,ae,ge=(Y=S,(ie=Math.pow(10,(""+Math.floor(Y)).length-1))*(ae=(ae=Y/ie)>=10?10:ae>=5?5:ae>=3?3:ae>=2?2:ae>=1?1:function(Pe){var Ue=Math.pow(10,Math.ceil(-Math.log(Pe)/Math.LN10));return Math.round(Pe*Ue)/Ue}(ae)));w.style.width=M*(ge/S)+"px",w.innerHTML=ge+" "+L}bh.prototype.getDefaultPosition=function(){return"bottom-left"},bh.prototype._onMove=function(){Rp(this._map,this._container,this.options)},bh.prototype.onAdd=function(w){return this._map=w,this._container=s.create("div","mapboxgl-ctrl mapboxgl-ctrl-scale",w.getContainer()),this._map.on("move",this._onMove),this._onMove(),this._container},bh.prototype.onRemove=function(){s.remove(this._container),this._map.off("move",this._onMove),this._map=void 0},bh.prototype.setUnit=function(w){this.options.unit=w,Rp(this._map,this._container,this.options)};var Du=function(w){this._fullscreen=!1,w&&w.container&&(w.container instanceof n.window.HTMLElement?this._container=w.container:n.warnOnce("Full screen control 'container' must be a DOM element.")),n.bindAll(["_onClickFullscreen","_changeIcon"],this),"onfullscreenchange"in n.window.document?this._fullscreenchange="fullscreenchange":"onmozfullscreenchange"in n.window.document?this._fullscreenchange="mozfullscreenchange":"onwebkitfullscreenchange"in n.window.document?this._fullscreenchange="webkitfullscreenchange":"onmsfullscreenchange"in n.window.document&&(this._fullscreenchange="MSFullscreenChange")};Du.prototype.onAdd=function(w){return this._map=w,this._container||(this._container=this._map.getContainer()),this._controlContainer=s.create("div","mapboxgl-ctrl mapboxgl-ctrl-group"),this._checkFullscreenSupport()?this._setupUI():(this._controlContainer.style.display="none",n.warnOnce("This device does not support fullscreen mode.")),this._controlContainer},Du.prototype.onRemove=function(){s.remove(this._controlContainer),this._map=null,n.window.document.removeEventListener(this._fullscreenchange,this._changeIcon)},Du.prototype._checkFullscreenSupport=function(){return!!(n.window.document.fullscreenEnabled||n.window.document.mozFullScreenEnabled||n.window.document.msFullscreenEnabled||n.window.document.webkitFullscreenEnabled)},Du.prototype._setupUI=function(){var w=this._fullscreenButton=s.create("button","mapboxgl-ctrl-fullscreen",this._controlContainer);s.create("span","mapboxgl-ctrl-icon",w).setAttribute("aria-hidden",!0),w.type="button",this._updateTitle(),this._fullscreenButton.addEventListener("click",this._onClickFullscreen),n.window.document.addEventListener(this._fullscreenchange,this._changeIcon)},Du.prototype._updateTitle=function(){var w=this._getTitle();this._fullscreenButton.setAttribute("aria-label",w),this._fullscreenButton.title=w},Du.prototype._getTitle=function(){return this._map._getUIString(this._isFullscreen()?"FullscreenControl.Exit":"FullscreenControl.Enter")},Du.prototype._isFullscreen=function(){return this._fullscreen},Du.prototype._changeIcon=function(){(n.window.document.fullscreenElement||n.window.document.mozFullScreenElement||n.window.document.webkitFullscreenElement||n.window.document.msFullscreenElement)===this._container!==this._fullscreen&&(this._fullscreen=!this._fullscreen,this._fullscreenButton.classList.toggle("mapboxgl-ctrl-shrink"),this._fullscreenButton.classList.toggle("mapboxgl-ctrl-fullscreen"),this._updateTitle())},Du.prototype._onClickFullscreen=function(){this._isFullscreen()?n.window.document.exitFullscreen?n.window.document.exitFullscreen():n.window.document.mozCancelFullScreen?n.window.document.mozCancelFullScreen():n.window.document.msExitFullscreen?n.window.document.msExitFullscreen():n.window.document.webkitCancelFullScreen&&n.window.document.webkitCancelFullScreen():this._container.requestFullscreen?this._container.requestFullscreen():this._container.mozRequestFullScreen?this._container.mozRequestFullScreen():this._container.msRequestFullscreen?this._container.msRequestFullscreen():this._container.webkitRequestFullscreen&&this._container.webkitRequestFullscreen()};var Bp={closeButton:!0,closeOnClick:!0,focusAfterOpen:!0,className:"",maxWidth:"240px"},Kd=["a[href]","[tabindex]:not([tabindex='-1'])","[contenteditable]:not([contenteditable='false'])","button:not([disabled])","input:not([disabled])","select:not([disabled])","textarea:not([disabled])"].join(", "),Yf=function(w){function M(S){w.call(this),this.options=n.extend(Object.create(Bp),S),n.bindAll(["_update","_onClose","remove","_onMouseMove","_onMouseUp","_onDrag"],this)}return w&&(M.__proto__=w),(M.prototype=Object.create(w&&w.prototype)).constructor=M,M.prototype.addTo=function(S){return this._map&&this.remove(),this._map=S,this.options.closeOnClick&&this._map.on("click",this._onClose),this.options.closeOnMove&&this._map.on("move",this._onClose),this._map.on("remove",this.remove),this._update(),this._focusFirstElement(),this._trackPointer?(this._map.on("mousemove",this._onMouseMove),this._map.on("mouseup",this._onMouseUp),this._container&&this._container.classList.add("mapboxgl-popup-track-pointer"),this._map._canvasContainer.classList.add("mapboxgl-track-pointer")):this._map.on("move",this._update),this.fire(new n.Event("open")),this},M.prototype.isOpen=function(){return!!this._map},M.prototype.remove=function(){return this._content&&s.remove(this._content),this._container&&(s.remove(this._container),delete this._container),this._map&&(this._map.off("move",this._update),this._map.off("move",this._onClose),this._map.off("click",this._onClose),this._map.off("remove",this.remove),this._map.off("mousemove",this._onMouseMove),this._map.off("mouseup",this._onMouseUp),this._map.off("drag",this._onDrag),delete this._map),this.fire(new n.Event("close")),this},M.prototype.getLngLat=function(){return this._lngLat},M.prototype.setLngLat=function(S){return this._lngLat=n.LngLat.convert(S),this._pos=null,this._trackPointer=!1,this._update(),this._map&&(this._map.on("move",this._update),this._map.off("mousemove",this._onMouseMove),this._container&&this._container.classList.remove("mapboxgl-popup-track-pointer"),this._map._canvasContainer.classList.remove("mapboxgl-track-pointer")),this},M.prototype.trackPointer=function(){return this._trackPointer=!0,this._pos=null,this._update(),this._map&&(this._map.off("move",this._update),this._map.on("mousemove",this._onMouseMove),this._map.on("drag",this._onDrag),this._container&&this._container.classList.add("mapboxgl-popup-track-pointer"),this._map._canvasContainer.classList.add("mapboxgl-track-pointer")),this},M.prototype.getElement=function(){return this._container},M.prototype.setText=function(S){return this.setDOMContent(n.window.document.createTextNode(S))},M.prototype.setHTML=function(S){var L,Y=n.window.document.createDocumentFragment(),ie=n.window.document.createElement("body");for(ie.innerHTML=S;L=ie.firstChild;)Y.appendChild(L);return this.setDOMContent(Y)},M.prototype.getMaxWidth=function(){return this._container&&this._container.style.maxWidth},M.prototype.setMaxWidth=function(S){return this.options.maxWidth=S,this._update(),this},M.prototype.setDOMContent=function(S){if(this._content)for(;this._content.hasChildNodes();)this._content.firstChild&&this._content.removeChild(this._content.firstChild);else this._content=s.create("div","mapboxgl-popup-content",this._container);return this._content.appendChild(S),this._createCloseButton(),this._update(),this._focusFirstElement(),this},M.prototype.addClassName=function(S){this._container&&this._container.classList.add(S)},M.prototype.removeClassName=function(S){this._container&&this._container.classList.remove(S)},M.prototype.setOffset=function(S){return this.options.offset=S,this._update(),this},M.prototype.toggleClassName=function(S){if(this._container)return this._container.classList.toggle(S)},M.prototype._createCloseButton=function(){this.options.closeButton&&(this._closeButton=s.create("button","mapboxgl-popup-close-button",this._content),this._closeButton.type="button",this._closeButton.setAttribute("aria-label","Close popup"),this._closeButton.innerHTML="×",this._closeButton.addEventListener("click",this._onClose))},M.prototype._onMouseUp=function(S){this._update(S.point)},M.prototype._onMouseMove=function(S){this._update(S.point)},M.prototype._onDrag=function(S){this._update(S.point)},M.prototype._update=function(S){var L=this;if(this._map&&(this._lngLat||this._trackPointer)&&this._content&&(this._container||(this._container=s.create("div","mapboxgl-popup",this._map.getContainer()),this._tip=s.create("div","mapboxgl-popup-tip",this._container),this._container.appendChild(this._content),this.options.className&&this.options.className.split(" ").forEach(function(ft){return L._container.classList.add(ft)}),this._trackPointer&&this._container.classList.add("mapboxgl-popup-track-pointer")),this.options.maxWidth&&this._container.style.maxWidth!==this.options.maxWidth&&(this._container.style.maxWidth=this.options.maxWidth),this._map.transform.renderWorldCopies&&!this._trackPointer&&(this._lngLat=vh(this._lngLat,this._pos,this._map.transform)),!this._trackPointer||S)){var Y=this._pos=this._trackPointer&&S?S:this._map.project(this._lngLat),ie=this.options.anchor,ae=function ft(gt){if(gt){if(typeof gt=="number"){var ut=Math.round(Math.sqrt(.5*Math.pow(gt,2)));return{center:new n.Point(0,0),top:new n.Point(0,gt),"top-left":new n.Point(ut,ut),"top-right":new n.Point(-ut,ut),bottom:new n.Point(0,-gt),"bottom-left":new n.Point(ut,-ut),"bottom-right":new n.Point(-ut,-ut),left:new n.Point(gt,0),right:new n.Point(-gt,0)}}if(gt instanceof n.Point||Array.isArray(gt)){var Pt=n.Point.convert(gt);return{center:Pt,top:Pt,"top-left":Pt,"top-right":Pt,bottom:Pt,"bottom-left":Pt,"bottom-right":Pt,left:Pt,right:Pt}}return{center:n.Point.convert(gt.center||[0,0]),top:n.Point.convert(gt.top||[0,0]),"top-left":n.Point.convert(gt["top-left"]||[0,0]),"top-right":n.Point.convert(gt["top-right"]||[0,0]),bottom:n.Point.convert(gt.bottom||[0,0]),"bottom-left":n.Point.convert(gt["bottom-left"]||[0,0]),"bottom-right":n.Point.convert(gt["bottom-right"]||[0,0]),left:n.Point.convert(gt.left||[0,0]),right:n.Point.convert(gt.right||[0,0])}}return ft(new n.Point(0,0))}(this.options.offset);if(!ie){var ge,Pe=this._container.offsetWidth,Ue=this._container.offsetHeight;ge=Y.y+ae.bottom.ythis._map.transform.height-Ue?["bottom"]:[],Y.xthis._map.transform.width-Pe/2&&ge.push("right"),ie=ge.length===0?"bottom":ge.join("-")}var ct=Y.add(ae[ie]).round();s.setTransform(this._container,_u[ie]+" translate("+ct.x+"px,"+ct.y+"px)"),Zf(this._container,ie,"popup")}},M.prototype._focusFirstElement=function(){if(this.options.focusAfterOpen&&this._container){var S=this._container.querySelector(Kd);S&&S.focus()}},M.prototype._onClose=function(){this.remove()},M}(n.Evented),Qh={version:n.version,supported:o,setRTLTextPlugin:n.setRTLTextPlugin,getRTLTextPluginStatus:n.getRTLTextPluginStatus,Map:Mp,NavigationControl:_c,GeolocateControl:Yd,AttributionControl:Vc,ScaleControl:bh,FullscreenControl:Du,Popup:Yf,Marker:xd,Style:xl,LngLat:n.LngLat,LngLatBounds:n.LngLatBounds,Point:n.Point,MercatorCoordinate:n.MercatorCoordinate,Evented:n.Evented,config:n.config,prewarm:function(){pr().acquire(Hr)},clearPrewarmedResources:function(){var w=Or;w&&(w.isPreloaded()&&w.numActive()===1?(w.release(Hr),Or=null):console.warn("Could not clear WebWorkers since there are active Map instances that still reference it. The pre-warmed WebWorker pool can only be cleared when all map instances have been removed with map.remove()"))},get accessToken(){return n.config.ACCESS_TOKEN},set accessToken(w){n.config.ACCESS_TOKEN=w},get baseApiUrl(){return n.config.API_URL},set baseApiUrl(w){n.config.API_URL=w},get workerCount(){return si.workerCount},set workerCount(w){si.workerCount=w},get maxParallelImageRequests(){return n.config.MAX_PARALLEL_IMAGE_REQUESTS},set maxParallelImageRequests(w){n.config.MAX_PARALLEL_IMAGE_REQUESTS=w},clearStorage:function(w){n.clearTileCache(w)},workerUrl:""};return Qh}),r})});function zBe(t,e){let r=t.stats,i=!1;for(let f of e)r[f]||(t.get(f),i=!0);let n=Object.keys(r).length,o=Xie.get(t);if(!i&&o?.orderedStatNames===e&&o.statCount===n)return;let s={},c=Zie.get(e);c||(c=new Set(e),Zie.set(e,c));for(let f of e)r[f]&&(s[f]=r[f]);for(let[f,g]of Object.entries(r))c.has(f)||(s[f]=g);for(let f of Object.keys(r))delete r[f];Object.assign(r,s),Xie.set(t,{orderedStatNames:e,statCount:n})}var kBe,NBe,Xie,Zie,tG,FF,rG=Nt(()=>{Nb();kBe="GPU Time and Memory",NBe=["Adapter","GPU","GPU Type","GPU Backend","Frame Rate","CPU Time","GPU Time","GPU Memory","Buffer Memory","Texture Memory","Referenced Buffer Memory","Referenced Texture Memory","Swap Chain Texture"],Xie=new WeakMap,Zie=new WeakMap,tG=class{stats=new Map;getStats(e){return this.get(e)}get(e){this.stats.has(e)||this.stats.set(e,new Ed({id:e}));let r=this.stats.get(e);return e===kBe&&zBe(r,NBe),r}},FF=new tG});var Dr,Lg=Nt(()=>{Mv();Dr=new sf({id:"luma.gl"})});function XA(t="id"){iG[t]=iG[t]||1;let e=iG[t]++;return`${t}-${e}`}var iG,jT=Nt(()=>{iG={}});function WBe(t,e){let r={...e};for(let i in t)t[i]!==void 0&&(r[i]=t[i]);return r}function tne(t,e){let r=t.stats,i=!1;for(let f of e)r[f]||(t.get(f),i=!0);let n=Object.keys(r).length,o=Jie.get(t);if(!i&&o?.orderedStatNames===e&&o.statCount===n)return;let s={},c=ene.get(e);c||(c=new Set(e),ene.set(e,c));for(let f of e)r[f]&&(s[f]=r[f]);for(let[f,g]of Object.entries(r))c.has(f)||(s[f]=g);for(let f of Object.keys(r))delete r[f];Object.assign(r,s),Jie.set(t,{orderedStatNames:e,statCount:n})}function rne(t){return t.type==="webgl"?GBe:HBe}function XM(t){let e=t.userData[UBe];return e?.enabled?e:null}function Yv(){return globalThis.performance?.now?.()??Date.now()}function qBe(t,e){let r=XM(t);if(!(!r||!r.activeDefaultFramebufferAcquireDepth))switch(r.transientCanvasResourceCreates=(r.transientCanvasResourceCreates||0)+1,e){case"Texture":r.transientCanvasTextureCreates=(r.transientCanvasTextureCreates||0)+1;break;case"TextureView":r.transientCanvasTextureViewCreates=(r.transientCanvasTextureViewCreates||0)+1;break;case"Sampler":r.transientCanvasSamplerCreates=(r.transientCanvasSamplerCreates||0)+1;break;case"Framebuffer":r.transientCanvasFramebufferCreates=(r.transientCanvasFramebufferCreates||0)+1;break;default:break}}function $Be(t){let e=Object.getPrototypeOf(t);for(;e;){let r=Object.getPrototypeOf(e);if(!r||r===$o.prototype)return XBe(e)||t[Symbol.toStringTag]||t.constructor.name;e=r}return t[Symbol.toStringTag]||t.constructor.name}function XBe(t){let e=Object.getOwnPropertyDescriptor(t,Symbol.toStringTag);return typeof e?.get=="function"?e.get.call(t):typeof e?.value=="string"?e.value:null}var UBe,Yie,Kie,Qie,VBe,jBe,HBe,GBe,Jie,ene,$o,ad=Nt(()=>{jT();UBe="cpu-hotspot-profiler",Yie="GPU Resource Counts",Kie="Resource Counts",Qie="GPU Time and Memory",VBe=["Resources","Buffers","Textures","Samplers","TextureViews","Framebuffers","QuerySets","Shaders","RenderPipelines","ComputePipelines","PipelineLayouts","VertexArrays","RenderPasss","ComputePasss","CommandEncoders","CommandBuffers"],jBe=["Resources","Buffers","Textures","Samplers","TextureViews","Framebuffers","QuerySets","Shaders","RenderPipelines","SharedRenderPipelines","ComputePipelines","PipelineLayouts","VertexArrays","RenderPasss","ComputePasss","CommandEncoders","CommandBuffers"],HBe=VBe.flatMap(t=>[`${t} Created`,`${t} Active`]),GBe=jBe.flatMap(t=>[`${t} Created`,`${t} Active`]),Jie=new WeakMap,ene=new WeakMap,$o=class{toString(){return`${this[Symbol.toStringTag]||this.constructor.name}:"${this.id}"`}id;props;userData={};_device;destroyed=!1;allocatedBytes=0;allocatedBytesName=null;_attachedResources=new Set;constructor(e,r,i){if(!e)throw new Error("no device");this._device=e,this.props=WBe(r,i);let n=this.props.id!=="undefined"?this.props.id:XA(this[Symbol.toStringTag]);this.props.id=n,this.id=n,this.userData=this.props.userData||{},this.addStats()}destroy(){this.destroyed||this.destroyResource()}delete(){return this.destroy(),this}getProps(){return this.props}attachResource(e){this._attachedResources.add(e)}detachResource(e){this._attachedResources.delete(e)}destroyAttachedResource(e){this._attachedResources.delete(e)&&e.destroy()}destroyAttachedResources(){for(let e of this._attachedResources)e.destroy();this._attachedResources=new Set}destroyResource(){this.destroyed||(this.destroyAttachedResources(),this.removeStats(),this.destroyed=!0)}removeStats(){let e=XM(this._device),r=e?Yv():0,i=[this._device.statsManager.getStats(Yie),this._device.statsManager.getStats(Kie)],n=rne(this._device);for(let s of i)tne(s,n);let o=this.getStatsName();for(let s of i)s.get("Resources Active").decrementCount(),s.get(`${o}s Active`).decrementCount();e&&(e.statsBookkeepingCalls=(e.statsBookkeepingCalls||0)+1,e.statsBookkeepingTimeMs=(e.statsBookkeepingTimeMs||0)+(Yv()-r))}trackAllocatedMemory(e,r=this.getStatsName()){let i=XM(this._device),n=i?Yv():0,o=this._device.statsManager.getStats(Qie);this.allocatedBytes>0&&this.allocatedBytesName&&(o.get("GPU Memory").subtractCount(this.allocatedBytes),o.get(`${this.allocatedBytesName} Memory`).subtractCount(this.allocatedBytes)),o.get("GPU Memory").addCount(e),o.get(`${r} Memory`).addCount(e),i&&(i.statsBookkeepingCalls=(i.statsBookkeepingCalls||0)+1,i.statsBookkeepingTimeMs=(i.statsBookkeepingTimeMs||0)+(Yv()-n)),this.allocatedBytes=e,this.allocatedBytesName=r}trackReferencedMemory(e,r=this.getStatsName()){this.trackAllocatedMemory(e,`Referenced ${r}`)}trackDeallocatedMemory(e=this.getStatsName()){if(this.allocatedBytes===0){this.allocatedBytesName=null;return}let r=XM(this._device),i=r?Yv():0,n=this._device.statsManager.getStats(Qie);n.get("GPU Memory").subtractCount(this.allocatedBytes),n.get(`${this.allocatedBytesName||e} Memory`).subtractCount(this.allocatedBytes),r&&(r.statsBookkeepingCalls=(r.statsBookkeepingCalls||0)+1,r.statsBookkeepingTimeMs=(r.statsBookkeepingTimeMs||0)+(Yv()-i)),this.allocatedBytes=0,this.allocatedBytesName=null}trackDeallocatedReferencedMemory(e=this.getStatsName()){this.trackDeallocatedMemory(`Referenced ${e}`)}addStats(){let e=this.getStatsName(),r=XM(this._device),i=r?Yv():0,n=[this._device.statsManager.getStats(Yie),this._device.statsManager.getStats(Kie)],o=rne(this._device);for(let s of n)tne(s,o);for(let s of n)s.get("Resources Created").incrementCount(),s.get("Resources Active").incrementCount(),s.get(`${e}s Created`).incrementCount(),s.get(`${e}s Active`).incrementCount();r&&(r.statsBookkeepingCalls=(r.statsBookkeepingCalls||0)+1,r.statsBookkeepingTimeMs=(r.statsBookkeepingTimeMs||0)+(Yv()-i)),qBe(this._device,e)}getStatsName(){return $Be(this)}};Qi($o,"defaultProps",{id:"undefined",handle:void 0,userData:void 0})});var ZM,lo,kF=Nt(()=>{ad();ZM=class extends $o{get[Symbol.toStringTag](){return"Buffer"}usage;indexType;updateTimestamp;constructor(e,r){let i={...r};(r.usage||0)&ZM.INDEX&&!r.indexType&&(r.data instanceof Uint32Array?i.indexType="uint32":r.data instanceof Uint16Array?i.indexType="uint16":r.data instanceof Uint8Array&&(i.indexType="uint8")),delete i.data,super(e,i,ZM.defaultProps),this.usage=i.usage||0,this.indexType=i.indexType,this.updateTimestamp=e.incrementTimestamp()}clone(e){return this.device.createBuffer({...this.props,...e})}debugData=new ArrayBuffer(0);_setDebugData(e,r,i){let n=null,o;ArrayBuffer.isView(e)?(n=e,o=e.buffer):o=e;let s=Math.min(e?e.byteLength:i,ZM.DEBUG_DATA_MAX_LENGTH);if(o===null)this.debugData=new ArrayBuffer(s);else{let c=Math.min(n?.byteOffset||0,o.byteLength),f=Math.max(0,o.byteLength-c),g=Math.min(s,f);this.debugData=new Uint8Array(o,c,g).slice().buffer}}},lo=ZM;Qi(lo,"INDEX",16),Qi(lo,"VERTEX",32),Qi(lo,"UNIFORM",64),Qi(lo,"STORAGE",128),Qi(lo,"INDIRECT",256),Qi(lo,"QUERY_RESOLVE",512),Qi(lo,"MAP_READ",1),Qi(lo,"MAP_WRITE",2),Qi(lo,"COPY_SRC",4),Qi(lo,"COPY_DST",8),Qi(lo,"DEBUG_DATA_MAX_LENGTH",32),Qi(lo,"defaultProps",{...$o.defaultProps,usage:0,byteLength:0,byteOffset:0,data:null,indexType:"uint16",onMapped:void 0})});var oG,cp,nG,NF=Nt(()=>{oG=class{getDataTypeInfo(e){let[r,i,n]=nG[e],o=e.includes("norm"),s=!o&&!e.startsWith("float"),c=e.startsWith("s");return{signedType:r,primitiveType:i,byteLength:n,normalized:o,integer:s,signed:c}}getNormalizedDataType(e){let r=e;switch(r){case"uint8":return"unorm8";case"sint8":return"snorm8";case"uint16":return"unorm16";case"sint16":return"snorm16";default:return r}}alignTo(e,r){switch(r){case 1:return e;case 2:return e+e%2;default:return e+(4-e%4)%4}}getDataType(e){let r=ArrayBuffer.isView(e)?e.constructor:e;if(r===Uint8ClampedArray)return"uint8";let i=Object.values(nG).find(n=>r===n[4]);if(!i)throw new Error(r.name);return i[0]}getTypedArrayConstructor(e){let[,,,,r]=nG[e];return r}},cp=new oG,nG={uint8:["uint8","u32",1,!1,Uint8Array],sint8:["sint8","i32",1,!1,Int8Array],unorm8:["uint8","f32",1,!0,Uint8Array],snorm8:["sint8","f32",1,!0,Int8Array],uint16:["uint16","u32",2,!1,Uint16Array],sint16:["sint16","i32",2,!1,Int16Array],unorm16:["uint16","u32",2,!0,Uint16Array],snorm16:["sint16","i32",2,!0,Int16Array],float16:["float16","f16",2,!1,Uint16Array],float32:["float32","f32",4,!1,Float32Array],uint32:["uint32","u32",4,!1,Uint32Array],sint32:["sint32","i32",4,!1,Int32Array]}});var sG,py,zF=Nt(()=>{NF();sG=class{getVertexFormatInfo(e){let r;e.endsWith("-webgl")&&(e.replace("-webgl",""),r=!0);let[i,n]=e.split("x"),o=i,s=n?parseInt(n):1,c=cp.getDataTypeInfo(o),f={type:o,components:s,byteLength:c.byteLength*s,integer:c.integer,signed:c.signed,normalized:c.normalized};return r&&(f.webglOnly=!0),f}makeVertexFormat(e,r,i){let n=i?cp.getNormalizedDataType(e):e;switch(n){case"unorm8":return r===1?"unorm8":r===3?"unorm8x3-webgl":`${n}x${r}`;case"snorm8":return r===1?"snorm8":r===3?"snorm8x3-webgl":`${n}x${r}`;case"uint8":case"sint8":if(r===1||r===3)throw new Error(`size: ${r}`);return`${n}x${r}`;case"uint16":return r===1?"uint16":r===3?"uint16x3-webgl":`${n}x${r}`;case"sint16":return r===1?"sint16":r===3?"sint16x3-webgl":`${n}x${r}`;case"unorm16":return r===1?"unorm16":r===3?"unorm16x3-webgl":`${n}x${r}`;case"snorm16":return r===1?"snorm16":r===3?"snorm16x3-webgl":`${n}x${r}`;case"float16":if(r===1||r===3)throw new Error(`size: ${r}`);return`${n}x${r}`;default:return r===1?n:`${n}x${r}`}}getVertexFormatFromAttribute(e,r,i){if(!r||r>4)throw new Error(`size ${r}`);let n=r,o=cp.getDataType(e);return this.makeVertexFormat(o,n,i)}getCompatibleVertexFormat(e){let r;switch(e.primitiveType){case"f32":r="float32";break;case"i32":r="sint32";break;case"u32":r="uint32";break;case"f16":return e.components<=2?"float16x2":"float16x4"}return e.components===1?r:`${r}x${e.components}`}},py=new sG});function fG(t){let e=one[t];if(!e)throw new Error(`Unsupported texture format ${t}`);return e}function nne(){return one}var Ld,uc,ZA,ZBe,UF,aG,VF,lG,YBe,cG,Kv,uG,hG,jF,ine,KBe,QBe,one,dG=Nt(()=>{Ld="texture-compression-bc",uc="texture-compression-astc",ZA="texture-compression-etc2",ZBe="texture-compression-etc1-webgl",UF="texture-compression-pvrtc-webgl",aG="texture-compression-atc-webgl",VF="float32-renderable-webgl",lG="float16-renderable-webgl",YBe="rgb9e5ufloat-renderable-webgl",cG="snorm8-renderable-webgl",Kv="norm16-webgl",uG="norm16-renderable-webgl",hG="snorm16-renderable-webgl",jF="float32-filterable",ine="float16-filterable-webgl";KBe={r8unorm:{},rg8unorm:{},"rgb8unorm-webgl":{},rgba8unorm:{},"rgba8unorm-srgb":{},r8snorm:{render:cG},rg8snorm:{render:cG},"rgb8snorm-webgl":{},rgba8snorm:{render:cG},r8uint:{},rg8uint:{},rgba8uint:{},r8sint:{},rg8sint:{},rgba8sint:{},bgra8unorm:{},"bgra8unorm-srgb":{},r16unorm:{f:Kv,render:uG},rg16unorm:{f:Kv,render:uG},"rgb16unorm-webgl":{f:Kv,render:!1},rgba16unorm:{f:Kv,render:uG},r16snorm:{f:Kv,render:hG},rg16snorm:{f:Kv,render:hG},"rgb16snorm-webgl":{f:Kv,render:!1},rgba16snorm:{f:Kv,render:hG},r16uint:{},rg16uint:{},rgba16uint:{},r16sint:{},rg16sint:{},rgba16sint:{},r16float:{render:lG,filter:"float16-filterable-webgl"},rg16float:{render:lG,filter:ine},rgba16float:{render:lG,filter:ine},r32uint:{},rg32uint:{},rgba32uint:{},r32sint:{},rg32sint:{},rgba32sint:{},r32float:{render:VF,filter:jF},rg32float:{render:!1,filter:jF},"rgb32float-webgl":{render:VF,filter:jF},rgba32float:{render:VF,filter:jF},"rgba4unorm-webgl":{channels:"rgba",bitsPerChannel:[4,4,4,4],packed:!0},"rgb565unorm-webgl":{channels:"rgb",bitsPerChannel:[5,6,5,0],packed:!0},"rgb5a1unorm-webgl":{channels:"rgba",bitsPerChannel:[5,5,5,1],packed:!0},rgb9e5ufloat:{channels:"rgb",packed:!0,render:YBe},rg11b10ufloat:{channels:"rgb",bitsPerChannel:[11,11,10,0],packed:!0,p:1,render:VF},rgb10a2unorm:{channels:"rgba",bitsPerChannel:[10,10,10,2],packed:!0,p:1},rgb10a2uint:{channels:"rgba",bitsPerChannel:[10,10,10,2],packed:!0,p:1},stencil8:{attachment:"stencil",bitsPerChannel:[8,0,0,0],dataType:"uint8"},depth16unorm:{attachment:"depth",bitsPerChannel:[16,0,0,0],dataType:"uint16"},depth24plus:{attachment:"depth",bitsPerChannel:[24,0,0,0],dataType:"uint32"},depth32float:{attachment:"depth",bitsPerChannel:[32,0,0,0],dataType:"float32"},"depth24plus-stencil8":{attachment:"depth-stencil",bitsPerChannel:[24,8,0,0],packed:!0},"depth32float-stencil8":{attachment:"depth-stencil",bitsPerChannel:[32,8,0,0],packed:!0}},QBe={"bc1-rgb-unorm-webgl":{f:Ld},"bc1-rgb-unorm-srgb-webgl":{f:Ld},"bc1-rgba-unorm":{f:Ld},"bc1-rgba-unorm-srgb":{f:Ld},"bc2-rgba-unorm":{f:Ld},"bc2-rgba-unorm-srgb":{f:Ld},"bc3-rgba-unorm":{f:Ld},"bc3-rgba-unorm-srgb":{f:Ld},"bc4-r-unorm":{f:Ld},"bc4-r-snorm":{f:Ld},"bc5-rg-unorm":{f:Ld},"bc5-rg-snorm":{f:Ld},"bc6h-rgb-ufloat":{f:Ld},"bc6h-rgb-float":{f:Ld},"bc7-rgba-unorm":{f:Ld},"bc7-rgba-unorm-srgb":{f:Ld},"etc2-rgb8unorm":{f:ZA},"etc2-rgb8unorm-srgb":{f:ZA},"etc2-rgb8a1unorm":{f:ZA},"etc2-rgb8a1unorm-srgb":{f:ZA},"etc2-rgba8unorm":{f:ZA},"etc2-rgba8unorm-srgb":{f:ZA},"eac-r11unorm":{f:ZA},"eac-r11snorm":{f:ZA},"eac-rg11unorm":{f:ZA},"eac-rg11snorm":{f:ZA},"astc-4x4-unorm":{f:uc},"astc-4x4-unorm-srgb":{f:uc},"astc-5x4-unorm":{f:uc},"astc-5x4-unorm-srgb":{f:uc},"astc-5x5-unorm":{f:uc},"astc-5x5-unorm-srgb":{f:uc},"astc-6x5-unorm":{f:uc},"astc-6x5-unorm-srgb":{f:uc},"astc-6x6-unorm":{f:uc},"astc-6x6-unorm-srgb":{f:uc},"astc-8x5-unorm":{f:uc},"astc-8x5-unorm-srgb":{f:uc},"astc-8x6-unorm":{f:uc},"astc-8x6-unorm-srgb":{f:uc},"astc-8x8-unorm":{f:uc},"astc-8x8-unorm-srgb":{f:uc},"astc-10x5-unorm":{f:uc},"astc-10x5-unorm-srgb":{f:uc},"astc-10x6-unorm":{f:uc},"astc-10x6-unorm-srgb":{f:uc},"astc-10x8-unorm":{f:uc},"astc-10x8-unorm-srgb":{f:uc},"astc-10x10-unorm":{f:uc},"astc-10x10-unorm-srgb":{f:uc},"astc-12x10-unorm":{f:uc},"astc-12x10-unorm-srgb":{f:uc},"astc-12x12-unorm":{f:uc},"astc-12x12-unorm-srgb":{f:uc},"pvrtc-rgb4unorm-webgl":{f:UF},"pvrtc-rgba4unorm-webgl":{f:UF},"pvrtc-rgb2unorm-webgl":{f:UF},"pvrtc-rgba2unorm-webgl":{f:UF},"etc1-rbg-unorm-webgl":{f:ZBe},"atc-rgb-unorm-webgl":{f:aG},"atc-rgba-unorm-webgl":{f:aG},"atc-rgbai-unorm-webgl":{f:aG}},one={...KBe,...QBe}});function iLe({format:t,width:e,height:r,depth:i,byteAlignment:n}){let o=ld.getInfo(t),{bytesPerPixel:s,bytesPerBlock:c=s,blockWidth:f=1,blockHeight:g=1,compressed:y=!1}=o,I=y?Math.ceil(e/f):e,F=y?Math.ceil(r/g):r,k=I*c,U=Math.ceil(k/n)*n,K=F,ee=U*K*i;return{bytesPerPixel:s,bytesPerRow:U,rowsPerImage:K,depthOrArrayLayers:i,bytesPerImage:U*K,byteLength:ee}}function nLe(t){let e=fG(t),r={format:t,create:e.f??!0,render:e.render??!0,filter:e.filter??!0,blend:e.blend??!0,store:e.store??!0},i=sne(t),n=t.startsWith("depth")||t.startsWith("stencil"),o=i?.signed,s=i?.integer,c=i?.webgl,f=Boolean(i?.compressed);return r.render&&=!n&&!f,r.filter&&=!n&&!o&&!s&&!c,r}function sne(t){let e=oLe(t);if(ld.isCompressed(t)){e.channels="rgb",e.components=3,e.bytesPerPixel=1,e.srgb=!1,e.compressed=!0,e.bytesPerBlock=aLe(t);let i=sLe(t);i&&(e.blockWidth=i.blockWidth,e.blockHeight=i.blockHeight)}let r=e.packed?null:JBe.exec(t);if(r){let[,i,n,o,s,c]=r,f=`${o}${n}`,g=cp.getDataTypeInfo(f),y=g.byteLength*8,I=i?.length??1,F=[y,I>=2?y:0,I>=3?y:0,I>=4?y:0];e={format:t,attachment:e.attachment,dataType:g.signedType,components:I,channels:i,integer:g.integer,signed:g.signed,normalized:g.normalized,bitsPerChannel:F,bytesPerPixel:g.byteLength*I,packed:e.packed,srgb:e.srgb},c==="-webgl"&&(e.webgl=!0),s==="-srgb"&&(e.srgb=!0)}return t.endsWith("-webgl")&&(e.webgl=!0),t.endsWith("-srgb")&&(e.srgb=!0),e}function oLe(t){let e=fG(t),r=e.bytesPerPixel||1,i=e.bitsPerChannel||[8,8,8,8];return delete e.bitsPerChannel,delete e.bytesPerPixel,delete e.f,delete e.render,delete e.filter,delete e.blend,delete e.store,{...e,format:t,attachment:e.attachment||"color",channels:e.channels||"r",components:e.components||e.channels?.length||1,bytesPerPixel:r,bitsPerChannel:i,dataType:e.dataType||"uint8",srgb:e.srgb??!1,packed:e.packed??!1,webgl:e.webgl??!1,integer:e.integer??!1,signed:e.signed??!1,normalized:e.normalized??!1,compressed:e.compressed??!1}}function sLe(t){let r=/.*-(\d+)x(\d+)-.*/.exec(t);if(r){let[,i,n]=r;return{blockWidth:Number(i),blockHeight:Number(n)}}return t.startsWith("bc")||t.startsWith("etc1")||t.startsWith("etc2")||t.startsWith("eac")||t.startsWith("atc")?{blockWidth:4,blockHeight:4}:t.startsWith("pvrtc-rgb4")||t.startsWith("pvrtc-rgba4")?{blockWidth:4,blockHeight:4}:t.startsWith("pvrtc-rgb2")||t.startsWith("pvrtc-rgba2")?{blockWidth:8,blockHeight:4}:null}function aLe(t){return t.startsWith("bc1")||t.startsWith("bc4")||t.startsWith("etc1")||t.startsWith("etc2-rgb8")||t.startsWith("etc2-rgb8a1")||t.startsWith("eac-r11")||t==="atc-rgb-unorm-webgl"?8:t.startsWith("bc2")||t.startsWith("bc3")||t.startsWith("bc5")||t.startsWith("bc6h")||t.startsWith("bc7")||t.startsWith("etc2-rgba8")||t.startsWith("eac-rg11")||t.startsWith("astc")||t==="atc-rgba-unorm-webgl"||t==="atc-rgbai-unorm-webgl"?16:t.startsWith("pvrtc")?8:16}var JBe,eLe,tLe,rLe,pG,ld,HF=Nt(()=>{NF();dG();JBe=/^(r|rg|rgb|rgba|bgra)([0-9]*)([a-z]*)(-srgb)?(-webgl)?$/,eLe=["rgb","rgba","bgra"],tLe=["depth","stencil"],rLe=["bc1","bc2","bc3","bc4","bc5","bc6","bc7","etc1","etc2","eac","atc","astc","pvrtc"],pG=class{isColor(e){return eLe.some(r=>e.startsWith(r))}isDepthStencil(e){return tLe.some(r=>e.startsWith(r))}isCompressed(e){return rLe.some(r=>e.startsWith(r))}getInfo(e){return sne(e)}getCapabilities(e){return nLe(e)}computeMemoryLayout(e){return iLe(e)}},ld=new pG});function HT(t){return typeof ImageData<"u"&&t instanceof ImageData||typeof ImageBitmap<"u"&&t instanceof ImageBitmap||typeof HTMLImageElement<"u"&&t instanceof HTMLImageElement||typeof HTMLVideoElement<"u"&&t instanceof HTMLVideoElement||typeof VideoFrame<"u"&&t instanceof VideoFrame||typeof HTMLCanvasElement<"u"&&t instanceof HTMLCanvasElement||typeof OffscreenCanvas<"u"&&t instanceof OffscreenCanvas}function YM(t){if(typeof ImageData<"u"&&t instanceof ImageData||typeof ImageBitmap<"u"&&t instanceof ImageBitmap||typeof HTMLCanvasElement<"u"&&t instanceof HTMLCanvasElement||typeof OffscreenCanvas<"u"&&t instanceof OffscreenCanvas)return{width:t.width,height:t.height};if(typeof HTMLImageElement<"u"&&t instanceof HTMLImageElement)return{width:t.naturalWidth,height:t.naturalHeight};if(typeof HTMLVideoElement<"u"&&t instanceof HTMLVideoElement)return{width:t.videoWidth,height:t.videoHeight};if(typeof VideoFrame<"u"&&t instanceof VideoFrame)return{width:t.displayWidth,height:t.displayHeight};throw new Error("Unknown image type")}var mG=Nt(()=>{});function lLe(t,e){let r=gG(t),i=e.map(gG).filter(n=>n!==void 0);return[r,...i].filter(n=>n!==void 0)}function gG(t){if(t!==void 0){if(t===null||typeof t=="string"||typeof t=="number"||typeof t=="boolean")return t;if(t instanceof Error)return t.message;if(Array.isArray(t))return t.map(gG);if(typeof t=="object"){if(cLe(t)){let e=String(t);if(e!=="[object Object]")return e}return uLe(t)?hLe(t):t.constructor?.name||"Object"}return String(t)}}function cLe(t){return"toString"in t&&typeof t.toString=="function"&&t.toString!==Object.prototype.toString}function uLe(t){return"message"in t&&"type"in t}function hLe(t){let e=typeof t.type=="string"?t.type:"message",r=typeof t.message=="string"?t.message:"",i=typeof t.lineNum=="number"?t.lineNum:null,n=typeof t.linePos=="number"?t.linePos:null,o=i!==null&&n!==null?` @ ${i}:${n}`:i!==null?` @ ${i}`:"";return`${e}${o}: ${r}`.trim()}function fLe(t,e){return t!=null?Boolean(t):e!==void 0?e!=="production":!1}function dLe(){return fLe(Dr.get("debug"),pLe())}function pLe(){let t=globalThis.process;if(t?.env)return t.env.NODE_ENV}var KM,QM,AG,Qp,_G=Nt(()=>{rG();Lg();jT();kF();zF();HF();mG();dG();KM=class{};QM=class{features;disabledFeatures;constructor(e=[],r){this.features=new Set(e),this.disabledFeatures=r||{}}*[Symbol.iterator](){yield*this.features}has(e){return!this.disabledFeatures?.[e]&&this.features.has(e)}},AG=class{get[Symbol.toStringTag](){return"Device"}toString(){return`Device(${this.id})`}id;props;userData={};statsManager=FF;_factories={};timestamp=0;_reused=!1;_moduleData={};_textureCaps={};_debugGPUTimeQuery=null;constructor(e){this.props={...AG.defaultProps,...e},this.id=this.props.id||XA(this[Symbol.toStringTag].toLowerCase())}getVertexFormatInfo(e){return py.getVertexFormatInfo(e)}isVertexFormatSupported(e){return!0}getTextureFormatInfo(e){return ld.getInfo(e)}getTextureFormatCapabilities(e){let r=this._textureCaps[e];if(!r){let i=this._getDeviceTextureFormatCapabilities(e);r=this._getDeviceSpecificTextureFormatCapabilities(i),this._textureCaps[e]=r}return r}getMipLevelCount(e,r,i=1){let n=Math.max(e,r,i);return 1+Math.floor(Math.log2(n))}isExternalImage(e){return HT(e)}getExternalImageSize(e){return YM(e)}isTextureFormatSupported(e){return this.getTextureFormatCapabilities(e).create}isTextureFormatFilterable(e){return this.getTextureFormatCapabilities(e).filter}isTextureFormatRenderable(e){return this.getTextureFormatCapabilities(e).render}isTextureFormatCompressed(e){return ld.isCompressed(e)}getSupportedCompressedTextureFormats(){let e=[];for(let r of Object.keys(nne()))this.isTextureFormatCompressed(r)&&this.isTextureFormatSupported(r)&&e.push(r);return e}pushDebugGroup(e){this.commandEncoder.pushDebugGroup(e)}popDebugGroup(){this.commandEncoder?.popDebugGroup()}insertDebugMarker(e){this.commandEncoder?.insertDebugMarker(e)}loseDevice(){return!1}incrementTimestamp(){return this.timestamp++}reportError(e,r,...i){if(!this.props.onError(e,r)){let o=lLe(r,i);return Dr.error(this.type==="webgl"?"%cWebGL":"%cWebGPU","color: white; background: red; padding: 2px 6px; border-radius: 3px;",e.message,...o)}return()=>{}}debug(){if(this.props.debug)debugger;else{let e=`'Type luma.log.set({debug: true}) in console to enable debug breakpoints', +or create a device with the 'debug: true' prop.`;Dr.once(0,e)()}}getDefaultCanvasContext(){if(!this.canvasContext)throw new Error("Device has no default CanvasContext. See props.createCanvasContext");return this.canvasContext}createFence(){throw new Error("createFence() not implemented")}beginRenderPass(e){return this.commandEncoder.beginRenderPass(e)}beginComputePass(e){return this.commandEncoder.beginComputePass(e)}generateMipmapsWebGPU(e){throw new Error("not implemented")}_createSharedRenderPipelineWebGL(e){throw new Error("_createSharedRenderPipelineWebGL() not implemented")}_createBindGroupLayoutWebGPU(e,r){throw new Error("_createBindGroupLayoutWebGPU() not implemented")}_createBindGroupWebGPU(e,r,i,n,o){throw new Error("_createBindGroupWebGPU() not implemented")}_supportsDebugGPUTime(){return this.features.has("timestamp-query")&&Boolean(this.props.debug||this.props.debugGPUTime)}_enableDebugGPUTime(e=256){if(!this._supportsDebugGPUTime())return null;if(this._debugGPUTimeQuery)return this._debugGPUTimeQuery;try{this._debugGPUTimeQuery=this.createQuerySet({type:"timestamp",count:e}),this.commandEncoder=this.createCommandEncoder({id:this.commandEncoder.props.id,timeProfilingQuerySet:this._debugGPUTimeQuery})}catch{this._debugGPUTimeQuery=null}return this._debugGPUTimeQuery}_disableDebugGPUTime(){this._debugGPUTimeQuery&&(this.commandEncoder.getTimeProfilingQuerySet()===this._debugGPUTimeQuery&&(this.commandEncoder=this.createCommandEncoder({id:this.commandEncoder.props.id})),this._debugGPUTimeQuery.destroy(),this._debugGPUTimeQuery=null)}_isDebugGPUTimeEnabled(){return this._debugGPUTimeQuery!==null}getCanvasContext(){return this.getDefaultCanvasContext()}readPixelsToArrayWebGL(e,r){throw new Error("not implemented")}readPixelsToBufferWebGL(e,r){throw new Error("not implemented")}setParametersWebGL(e){throw new Error("not implemented")}getParametersWebGL(e){throw new Error("not implemented")}withParametersWebGL(e,r){throw new Error("not implemented")}clearWebGL(e){throw new Error("not implemented")}resetWebGL(){throw new Error("not implemented")}getModuleData(e){return this._moduleData[e]||={},this._moduleData[e]}static _getCanvasContextProps(e){return e.createCanvasContext===!0?{}:e.createCanvasContext}_getDeviceTextureFormatCapabilities(e){let r=ld.getCapabilities(e),i=o=>(typeof o=="string"?this.features.has(o):o)??!0,n=i(r.create);return{format:e,create:n,render:n&&i(r.render),filter:n&&i(r.filter),blend:n&&i(r.blend),store:n&&i(r.store)}}_normalizeBufferProps(e){(e instanceof ArrayBuffer||ArrayBuffer.isView(e))&&(e={data:e});let r={...e};if((e.usage||0)&lo.INDEX&&(e.indexType||(e.data instanceof Uint32Array?r.indexType="uint32":e.data instanceof Uint16Array?r.indexType="uint16":e.data instanceof Uint8Array&&(r.data=new Uint16Array(e.data),r.indexType="uint16")),!r.indexType))throw new Error("indices buffer content must be of type uint16 or uint32");return r}},Qp=AG;Qi(Qp,"defaultProps",{id:null,powerPreference:"high-performance",failIfMajorPerformanceCaveat:!1,createCanvasContext:void 0,webgl:{},onError:(e,r)=>{},onResize:(e,r)=>{let[i,n]=e.getDevicePixelSize();Dr.log(1,`${e} resized => ${i}x${n}px`)()},onPositionChange:(e,r)=>{let[i,n]=e.getPosition();Dr.log(1,`${e} repositioned => ${i},${n}`)()},onVisibilityChange:e=>Dr.log(1,`${e} Visibility changed ${e.isVisible}`)(),onDevicePixelRatioChange:(e,r)=>Dr.log(1,`${e} DPR changed ${r.oldRatio} => ${e.devicePixelRatio}`)(),debug:dLe(),debugGPUTime:!1,debugShaders:Dr.get("debug-shaders")||void 0,debugFramebuffers:Boolean(Dr.get("debug-framebuffers")),debugFactories:Boolean(Dr.get("debug-factories")),debugWebGL:Boolean(Dr.get("debug-webgl")),debugSpectorJS:void 0,debugSpectorJSUrl:void 0,_reuseDevices:!1,_requestMaxLimits:!0,_cacheShaders:!0,_destroyShaders:!1,_cachePipelines:!0,_sharePipelines:!0,_destroyPipelines:!1,_initializeFeatures:!0,_disabledFeatures:{"compilation-status-async-webgl":!0},_handle:void 0})});var mLe,ane,WF,GF,YA,lne=Nt(()=>{_G();rG();Lg();mLe="set luma.log.level=1 (or higher) to trace rendering",ane="No matching device found. Ensure `@luma.gl/webgl` and/or `@luma.gl/webgpu` modules are imported.",WF=class{stats=FF;log=Dr;VERSION="9.3.3";spector;preregisteredAdapters=new Map;constructor(){if(globalThis.luma){if(globalThis.luma.VERSION!==this.VERSION)throw Dr.error(`Found luma.gl ${globalThis.luma.VERSION} while initialzing ${this.VERSION}`)(),Dr.error("'yarn why @luma.gl/core' can help identify the source of the conflict")(),new Error("luma.gl - multiple versions detected: see console log");Dr.error("This version of luma.gl has already been initialized")()}Dr.log(1,`${this.VERSION} - ${mLe}`)(),globalThis.luma=this}async createDevice(e={}){let r={...WF.defaultProps,...e},i=this.selectAdapter(r.type,r.adapters);if(!i)throw new Error(ane);return r.waitForPageLoad&&await i.pageLoaded,await i.create(r)}async attachDevice(e,r){let i=this._getTypeFromHandle(e,r.adapters),n=i&&this.selectAdapter(i,r.adapters);if(!n)throw new Error(ane);return await n?.attach?.(e,r)}registerAdapters(e){for(let r of e)this.preregisteredAdapters.set(r.type,r)}getSupportedAdapters(e=[]){let r=this._getAdapterMap(e);return Array.from(r).map(([,i])=>i).filter(i=>i.isSupported?.()).map(i=>i.type)}getBestAvailableAdapterType(e=[]){let r=["webgpu","webgl","null"],i=this._getAdapterMap(e);for(let n of r)if(i.get(n)?.isSupported?.())return n;return null}selectAdapter(e,r=[]){let i=e;e==="best-available"&&(i=this.getBestAvailableAdapterType(r));let n=this._getAdapterMap(r);return i&&n.get(i)||null}enforceWebGL2(e=!0,r=[]){let n=this._getAdapterMap(r).get("webgl");n||Dr.warn("enforceWebGL2: webgl adapter not found")(),n?.enforceWebGL2?.(e)}setDefaultDeviceProps(e){Object.assign(WF.defaultProps,e)}_getAdapterMap(e=[]){let r=new Map(this.preregisteredAdapters);for(let i of e)r.set(i.type,i);return r}_getTypeFromHandle(e,r=[]){return e instanceof WebGL2RenderingContext?"webgl":typeof GPUDevice<"u"&&e instanceof GPUDevice||e?.queue?"webgpu":e===null?"null":(e instanceof WebGLRenderingContext?Dr.warn("WebGL1 is not supported",e)():Dr.warn("Unknown handle type",e)(),null)}},GF=WF;Qi(GF,"defaultProps",{...Qp.defaultProps,type:"best-available",adapters:void 0,waitForPageLoad:!0});YA=new GF});function _Le(){return qF||(ALe()||typeof window>"u"?qF=Promise.resolve():qF=new Promise(t=>window.addEventListener("load",()=>t()))),qF}var JM,gLe,ALe,qF,cne=Nt(()=>{Iv();JM=class{get pageLoaded(){return _Le()}},gLe=rp()&&typeof document<"u",ALe=()=>gLe&&document.readyState==="complete",qF=null});var $F,une=Nt(()=>{$F=class{props;_resizeObserver;_intersectionObserver;_observeDevicePixelRatioTimeout=null;_observeDevicePixelRatioMediaQuery=null;_handleDevicePixelRatioChange=()=>this._refreshDevicePixelRatio();_trackPositionInterval=null;_started=!1;get started(){return this._started}constructor(e){this.props=e}start(){if(!(this._started||!this.props.canvas)){this._started=!0,this._intersectionObserver||=new IntersectionObserver(e=>this.props.onIntersection(e)),this._resizeObserver||=new ResizeObserver(e=>this.props.onResize(e)),this._intersectionObserver.observe(this.props.canvas);try{this._resizeObserver.observe(this.props.canvas,{box:"device-pixel-content-box"})}catch{this._resizeObserver.observe(this.props.canvas,{box:"content-box"})}this._observeDevicePixelRatioTimeout=setTimeout(()=>this._refreshDevicePixelRatio(),0),this.props.trackPosition&&this._trackPosition()}}stop(){this._started&&(this._started=!1,this._observeDevicePixelRatioTimeout&&(clearTimeout(this._observeDevicePixelRatioTimeout),this._observeDevicePixelRatioTimeout=null),this._observeDevicePixelRatioMediaQuery&&(this._observeDevicePixelRatioMediaQuery.removeEventListener("change",this._handleDevicePixelRatioChange),this._observeDevicePixelRatioMediaQuery=null),this._trackPositionInterval&&(clearInterval(this._trackPositionInterval),this._trackPositionInterval=null),this._resizeObserver?.disconnect(),this._intersectionObserver?.disconnect())}_refreshDevicePixelRatio(){this._started&&(this.props.onDevicePixelRatioChange(),this._observeDevicePixelRatioMediaQuery?.removeEventListener("change",this._handleDevicePixelRatioChange),this._observeDevicePixelRatioMediaQuery=matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`),this._observeDevicePixelRatioMediaQuery.addEventListener("change",this._handleDevicePixelRatioChange,{once:!0}))}_trackPosition(e=100){this._trackPositionInterval||(this._trackPositionInterval=setInterval(()=>{this._started?this.props.onPositionChange():this._trackPositionInterval&&(clearInterval(this._trackPositionInterval),this._trackPositionInterval=null)},e))}}});function hne(){let t,e;return{promise:new Promise((i,n)=>{t=i,e=n}),resolve:t,reject:e}}var fne=Nt(()=>{});function yG(t,e){if(!t){let r=new Error(e??"luma.gl assertion failed.");throw Error.captureStackTrace?.(r,yG),r}}function S1(t,e){return yG(t,e),t}var vG=Nt(()=>{});function yLe(t){if(typeof t=="string"){let e=document.getElementById(t);if(!e)throw new Error(`${t} is not an HTML element`);return e}return t||document.body}function vLe(t){let e=document.getElementById(t);if(!my.isHTMLCanvas(e))throw new Error("Object is not a canvas element");return e}function xLe(t){let{width:e,height:r}=t,i=document.createElement("canvas");i.id=XA("lumagl-auto-created-canvas"),i.width=e||1,i.height=r||1,i.style.width=Number.isFinite(e)?`${e}px`:"100%",i.style.height=Number.isFinite(r)?`${r}px`:"100%",t?.visible||(i.style.visibility="hidden");let n=yLe(t?.container||null);return n.insertBefore(i,n.firstChild),i}function bLe(t,e,r,i,n){let o=t,s=dne(o[0],e,r),c=pne(o[1],e,i,n),f=dne(o[0]+1,e,r),g=f===r-1?f:f-1;f=pne(o[1]+1,e,i,n);let y;return n?(f=f===0?f:f+1,y=c,c=f):y=f===i-1?f:f-1,{x:s,y:c,width:Math.max(g-s+1,1),height:Math.max(y-c+1,1)}}function dne(t,e,r){return Math.min(Math.round(t*e),r-1)}function pne(t,e,r,i){return i?Math.max(0,r-1-Math.round(t*e)):Math.min(Math.round(t*e),r-1)}var eP,my,xG=Nt(()=>{Iv();une();jT();fne();vG();eP=class{static isHTMLCanvas(e){return typeof HTMLCanvasElement<"u"&&e instanceof HTMLCanvasElement}static isOffscreenCanvas(e){return typeof OffscreenCanvas<"u"&&e instanceof OffscreenCanvas}id;props;canvas;htmlCanvas;offscreenCanvas;type;initialized;isInitialized=!1;isVisible=!0;cssWidth;cssHeight;devicePixelRatio;devicePixelWidth;devicePixelHeight;drawingBufferWidth;drawingBufferHeight;_initializedResolvers=hne();_canvasObserver;_position=[0,0];destroyed=!1;_needsDrawingBufferResize=!0;toString(){return`${this[Symbol.toStringTag]}(${this.id})`}constructor(e){this.props={...eP.defaultProps,...e},e=this.props,this.initialized=this._initializedResolvers.promise,rp()?e.canvas?typeof e.canvas=="string"?this.canvas=vLe(e.canvas):this.canvas=e.canvas:this.canvas=xLe(e):this.canvas={width:e.width||1,height:e.height||1},eP.isHTMLCanvas(this.canvas)?(this.id=e.id||this.canvas.id,this.type="html-canvas",this.htmlCanvas=this.canvas):eP.isOffscreenCanvas(this.canvas)?(this.id=e.id||"offscreen-canvas",this.type="offscreen-canvas",this.offscreenCanvas=this.canvas):(this.id=e.id||"node-canvas-context",this.type="node"),this.cssWidth=this.htmlCanvas?.clientWidth||this.canvas.width,this.cssHeight=this.htmlCanvas?.clientHeight||this.canvas.height,this.devicePixelWidth=this.canvas.width,this.devicePixelHeight=this.canvas.height,this.drawingBufferWidth=this.canvas.width,this.drawingBufferHeight=this.canvas.height,this.devicePixelRatio=globalThis.devicePixelRatio||1,this._position=[0,0],this._canvasObserver=new $F({canvas:this.htmlCanvas,trackPosition:this.props.trackPosition,onResize:r=>this._handleResize(r),onIntersection:r=>this._handleIntersection(r),onDevicePixelRatioChange:()=>this._observeDevicePixelRatio(),onPositionChange:()=>this.updatePosition()})}destroy(){this.destroyed||(this.destroyed=!0,this._stopObservers(),this.device=null)}setProps(e){return"useDevicePixels"in e&&(this.props.useDevicePixels=e.useDevicePixels||!1,this._updateDrawingBufferSize()),this}getCurrentFramebuffer(e){return this._resizeDrawingBufferIfNeeded(),this._getCurrentFramebuffer(e)}getCSSSize(){return[this.cssWidth,this.cssHeight]}getPosition(){return this._position}getDevicePixelSize(){return[this.devicePixelWidth,this.devicePixelHeight]}getDrawingBufferSize(){return[this.drawingBufferWidth,this.drawingBufferHeight]}getMaxDrawingBufferSize(){let e=this.device.limits.maxTextureDimension2D;return[e,e]}setDrawingBufferSize(e,r){e=Math.floor(e),r=Math.floor(r),!(this.drawingBufferWidth===e&&this.drawingBufferHeight===r)&&(this.drawingBufferWidth=e,this.drawingBufferHeight=r,this._needsDrawingBufferResize=!0)}getDevicePixelRatio(){return typeof window<"u"&&window.devicePixelRatio||1}cssToDevicePixels(e,r=!0){let i=this.cssToDeviceRatio(),[n,o]=this.getDrawingBufferSize();return bLe(e,i,n,o,r)}getPixelSize(){return this.getDevicePixelSize()}getAspect(){let[e,r]=this.getDrawingBufferSize();return e>0&&r>0?e/r:1}cssToDeviceRatio(){try{let[e]=this.getDrawingBufferSize(),[r]=this.getCSSSize();return r?e/r:1}catch{return 1}}resize(e){this.setDrawingBufferSize(e.width,e.height)}_setAutoCreatedCanvasId(e){this.htmlCanvas?.id==="lumagl-auto-created-canvas"&&(this.htmlCanvas.id=e)}_startObservers(){this.destroyed||this._canvasObserver.start()}_stopObservers(){this._canvasObserver.stop()}_handleIntersection(e){if(this.destroyed)return;let r=e.find(n=>n.target===this.canvas);if(!r)return;let i=r.isIntersecting;this.isVisible!==i&&(this.isVisible=i,this.device.props.onVisibilityChange(this))}_handleResize(e){if(this.destroyed)return;let r=e.find(g=>g.target===this.canvas);if(!r)return;let i=S1(r.contentBoxSize?.[0]);this.cssWidth=i.inlineSize,this.cssHeight=i.blockSize;let n=this.getDevicePixelSize(),o=r.devicePixelContentBoxSize?.[0]?.inlineSize||i.inlineSize*devicePixelRatio,s=r.devicePixelContentBoxSize?.[0]?.blockSize||i.blockSize*devicePixelRatio,[c,f]=this.getMaxDrawingBufferSize();this.devicePixelWidth=Math.max(1,Math.min(o,c)),this.devicePixelHeight=Math.max(1,Math.min(s,f)),this._updateDrawingBufferSize(),this.device.props.onResize(this,{oldPixelSize:n})}_updateDrawingBufferSize(){if(this.props.autoResize)if(typeof this.props.useDevicePixels=="number"){let e=this.props.useDevicePixels;this.setDrawingBufferSize(this.cssWidth*e,this.cssHeight*e)}else this.props.useDevicePixels?this.setDrawingBufferSize(this.devicePixelWidth,this.devicePixelHeight):this.setDrawingBufferSize(this.cssWidth,this.cssHeight);this._initializedResolvers.resolve(),this.isInitialized=!0,this.updatePosition()}_resizeDrawingBufferIfNeeded(){this._needsDrawingBufferResize&&(this._needsDrawingBufferResize=!1,(this.drawingBufferWidth!==this.canvas.width||this.drawingBufferHeight!==this.canvas.height)&&(this.canvas.width=this.drawingBufferWidth,this.canvas.height=this.drawingBufferHeight,this._configureDevice()))}_observeDevicePixelRatio(){if(this.destroyed||!this._canvasObserver.started)return;let e=this.devicePixelRatio;this.devicePixelRatio=window.devicePixelRatio,this.updatePosition(),this.device.props.onDevicePixelRatioChange?.(this,{oldRatio:e})}updatePosition(){if(this.destroyed)return;let e=this.htmlCanvas?.getBoundingClientRect();if(e){let r=[e.left,e.top];if(this._position??=r,r[0]!==this._position[0]||r[1]!==this._position[1]){let n=this._position;this._position=r,this.device.props.onPositionChange?.(this,{oldPosition:n})}}}},my=eP;Qi(my,"defaultProps",{id:void 0,canvas:null,width:800,height:600,useDevicePixels:!0,autoResize:!0,container:null,visible:!0,alphaMode:"opaque",colorSpace:"srgb",trackPosition:!1})});var GT,mne=Nt(()=>{xG();GT=class extends my{};Qi(GT,"defaultProps",my.defaultProps)});var tP,gne=Nt(()=>{xG();tP=class extends my{}});var XF,Dd,bG=Nt(()=>{ad();XF=class extends $o{get[Symbol.toStringTag](){return"Sampler"}constructor(e,r){r=XF.normalizeProps(e,r),super(e,r,XF.defaultProps)}static normalizeProps(e,r){return r}},Dd=XF;Qi(Dd,"defaultProps",{...$o.defaultProps,type:"color-sampler",addressModeU:"clamp-to-edge",addressModeV:"clamp-to-edge",addressModeW:"clamp-to-edge",magFilter:"nearest",minFilter:"nearest",mipmapFilter:"none",lodMinClamp:0,lodMaxClamp:32,compare:"less-equal",maxAnisotropy:1})});var wLe,Fm,oo,wG=Nt(()=>{ad();bG();Lg();HF();wLe={"1d":"1d","2d":"2d","2d-array":"2d",cube:"2d","cube-array":"2d","3d":"3d"},Fm=class extends $o{dimension;baseDimension;format;width;height;depth;mipLevels;samples;byteAlignment;ready=Promise.resolve(this);isReady=!0;updateTimestamp;get[Symbol.toStringTag](){return"Texture"}toString(){return`Texture(${this.id},${this.format},${this.width}x${this.height})`}constructor(e,r,i){if(r=Fm.normalizeProps(e,r),super(e,r,Fm.defaultProps),this.dimension=this.props.dimension,this.baseDimension=wLe[this.dimension],this.format=this.props.format,this.width=this.props.width,this.height=this.props.height,this.depth=this.props.depth,this.mipLevels=this.props.mipLevels,this.samples=this.props.samples||1,this.dimension==="cube"&&(this.depth=6),this.props.width===void 0||this.props.height===void 0)if(e.isExternalImage(r.data)){let n=e.getExternalImageSize(r.data);this.width=n?.width||1,this.height=n?.height||1}else this.width=1,this.height=1,(this.props.width===void 0||this.props.height===void 0)&&Dr.warn(`${this} created with undefined width or height. This is deprecated. Use DynamicTexture instead.`)();this.byteAlignment=i?.byteAlignment||1,this.updateTimestamp=e.incrementTimestamp()}clone(e){return this.device.createTexture({...this.props,...e})}setSampler(e){this.sampler=e instanceof Dd?e:this.device.createSampler(e)}copyImageData(e){let{data:r,depth:i,...n}=e;this.writeData(r,{...n,depthOrArrayLayers:n.depthOrArrayLayers??i})}computeMemoryLayout(e={}){let r=this._normalizeTextureReadOptions(e),{width:i=this.width,height:n=this.height,depthOrArrayLayers:o=this.depth}=r,{format:s,byteAlignment:c}=this;return ld.computeMemoryLayout({format:s,width:i,height:n,depth:o,byteAlignment:c})}readBuffer(e,r){throw new Error("readBuffer not implemented")}readDataAsync(e){throw new Error("readBuffer not implemented")}writeBuffer(e,r){throw new Error("readBuffer not implemented")}writeData(e,r){throw new Error("readBuffer not implemented")}readDataSyncWebGL(e){throw new Error("readDataSyncWebGL not available")}generateMipmapsWebGL(){throw new Error("generateMipmapsWebGL not available")}static normalizeProps(e,r){let i={...r},{width:n,height:o}=i;return typeof n=="number"&&(i.width=Math.max(1,Math.ceil(n))),typeof o=="number"&&(i.height=Math.max(1,Math.ceil(o))),i}_initializeData(e){this.device.isExternalImage(e)?this.copyExternalImage({image:e,width:this.width,height:this.height,depth:this.depth,mipLevel:0,x:0,y:0,z:0,aspect:"all",colorSpace:"srgb",premultipliedAlpha:!1,flipY:!1}):e&&this.copyImageData({data:e,mipLevel:0,x:0,y:0,z:0,aspect:"all"})}_normalizeCopyImageDataOptions(e){let{data:r,depth:i,...n}=e,o=this._normalizeTextureWriteOptions({...n,depthOrArrayLayers:n.depthOrArrayLayers??i});return{data:r,depth:o.depthOrArrayLayers,...o}}_normalizeCopyExternalImageOptions(e){let r=Fm._omitUndefined(e),i=r.mipLevel??0,n=this._getMipLevelSize(i),o=this.device.getExternalImageSize(e.image),s={...Fm.defaultCopyExternalImageOptions,...n,...o,...r};return s.width=Math.min(s.width,n.width-s.x),s.height=Math.min(s.height,n.height-s.y),s.depth=Math.min(s.depth,n.depthOrArrayLayers-s.z),s}_normalizeTextureReadOptions(e){let r=Fm._omitUndefined(e),i=r.mipLevel??0,n=this._getMipLevelSize(i),o={...Fm.defaultTextureReadOptions,...n,...r};return o.width=Math.min(o.width,n.width-o.x),o.height=Math.min(o.height,n.height-o.y),o.depthOrArrayLayers=Math.min(o.depthOrArrayLayers,n.depthOrArrayLayers-o.z),o}_getSupportedColorReadOptions(e){let r=this._normalizeTextureReadOptions(e),i=ld.getInfo(this.format);switch(this._validateColorReadAspect(r),this._validateColorReadFormat(i),this.dimension){case"2d":case"cube":case"cube-array":case"2d-array":case"3d":return r;default:throw new Error(`${this} color readback does not support ${this.dimension} textures`)}}_validateColorReadAspect(e){if(e.aspect!=="all")throw new Error(`${this} color readback only supports aspect 'all'`)}_validateColorReadFormat(e){if(e.compressed)throw new Error(`${this} color readback does not support compressed formats (${this.format})`);switch(e.attachment){case"color":return;case"depth":throw new Error(`${this} color readback does not support depth formats (${this.format})`);case"stencil":throw new Error(`${this} color readback does not support stencil formats (${this.format})`);case"depth-stencil":throw new Error(`${this} color readback does not support depth-stencil formats (${this.format})`);default:throw new Error(`${this} color readback does not support format ${this.format}`)}}_normalizeTextureWriteOptions(e){let r=Fm._omitUndefined(e),i=r.mipLevel??0,n=this._getMipLevelSize(i),o={...Fm.defaultTextureWriteOptions,...n,...r};o.width=Math.min(o.width,n.width-o.x),o.height=Math.min(o.height,n.height-o.y),o.depthOrArrayLayers=Math.min(o.depthOrArrayLayers,n.depthOrArrayLayers-o.z);let s=ld.computeMemoryLayout({format:this.format,width:o.width,height:o.height,depth:o.depthOrArrayLayers,byteAlignment:this.byteAlignment}),c=s.bytesPerPixel*o.width;if(o.bytesPerRow=r.bytesPerRow??s.bytesPerRow,o.rowsPerImage=r.rowsPerImage??o.height,o.bytesPerRow>e),i=this.baseDimension==="1d"?1:Math.max(1,this.height>>e),n=this.dimension==="3d"?Math.max(1,this.depth>>e):this.depth;return{width:r,height:i,depthOrArrayLayers:n}}getAllocatedByteLength(){let e=0;for(let r=0;rr!==void 0))}},oo=Fm;Qi(oo,"SAMPLE",4),Qi(oo,"STORAGE",8),Qi(oo,"RENDER",16),Qi(oo,"COPY_SRC",1),Qi(oo,"COPY_DST",2),Qi(oo,"TEXTURE",4),Qi(oo,"RENDER_ATTACHMENT",16),Qi(oo,"defaultProps",{...$o.defaultProps,data:null,dimension:"2d",format:"rgba8unorm",usage:Fm.SAMPLE|Fm.RENDER|Fm.COPY_DST,width:void 0,height:void 0,depth:1,mipLevels:1,samples:void 0,sampler:{},view:void 0}),Qi(oo,"defaultCopyDataOptions",{data:void 0,byteOffset:0,bytesPerRow:void 0,rowsPerImage:void 0,width:void 0,height:void 0,depthOrArrayLayers:void 0,depth:1,mipLevel:0,x:0,y:0,z:0,aspect:"all"}),Qi(oo,"defaultCopyExternalImageOptions",{image:void 0,sourceX:0,sourceY:0,width:void 0,height:void 0,depth:1,mipLevel:0,x:0,y:0,z:0,aspect:"all",colorSpace:"srgb",premultipliedAlpha:!1,flipY:!1}),Qi(oo,"defaultTextureReadOptions",{x:0,y:0,z:0,width:void 0,height:void 0,depthOrArrayLayers:1,mipLevel:0,aspect:"all"}),Qi(oo,"defaultTextureWriteOptions",{byteOffset:0,bytesPerRow:void 0,rowsPerImage:void 0,x:0,y:0,z:0,width:void 0,height:void 0,depthOrArrayLayers:1,mipLevel:0,aspect:"all"})});var TG,Dg,Ane=Nt(()=>{ad();TG=class extends $o{get[Symbol.toStringTag](){return"TextureView"}constructor(e,r){super(e,r,TG.defaultProps)}},Dg=TG;Qi(Dg,"defaultProps",{...$o.defaultProps,format:void 0,dimension:void 0,aspect:"all",baseMipLevel:0,mipLevelCount:void 0,baseArrayLayer:0,arrayLayerCount:void 0})});function _ne(t,e,r){let i="",n=e.split(/\r?\n/),o=t.slice().sort((s,c)=>s.lineNum-c.lineNum);switch(r?.showSourceCode||"no"){case"all":let s=0;for(let c=1;c<=n.length;c++){let f=n[c-1],g=o[s];for(f&&g&&(i+=yne(f,c,r));o.length>s&&g.lineNum===c;){let y=o[s++];y&&(i+=SG(y,n,y.lineNum,{...r,inlineSource:!1}))}}for(;o.length>s;){let c=o[s++];c&&(i+=SG(c,[],0,{...r,inlineSource:!1}))}return i;case"issues":case"no":for(let c of t)i+=SG(c,n,c.lineNum,{inlineSource:r?.showSourceCode!=="no"});return i}}function SG(t,e,r,i){if(i?.inlineSource){let o=TLe(e,r),s=t.linePos>0?`${" ".repeat(t.linePos+5)}^^^ +`:"";return` +${o}${s}${t.type.toUpperCase()}: ${t.message} + +`}let n=t.type==="error"?"red":"orange";return i?.html?`

${t.type.toUpperCase()}: ${t.message}
`:`${t.type.toUpperCase()}: ${t.message}`}function TLe(t,e,r){let i="";for(let n=e-2;n<=e;n++){let o=t[n-1];o!==void 0&&(i+=yne(o,e,r))}return i}function yne(t,e,r){let i=r?.html?ELe(t):t;return`${SLe(String(e),4)}: ${i}${r?.html?"
":` +`}`}function SLe(t,e){let r="";for(let i=t.length;i",">").replaceAll('"',""").replaceAll("'","'")}var vne=Nt(()=>{});function CLe(t){return ILe(t.source)||t.id||XA(`unnamed ${t.stage}-shader`)}function ILe(t,e="unnamed"){return/#define[\s*]SHADER_NAME[\s*]([A-Za-z0-9_-]+)[\s*]/.exec(t)?.[1]??e}var EG,Qv,CG=Nt(()=>{ad();jT();vne();EG=class extends $o{get[Symbol.toStringTag](){return"Shader"}stage;source;compilationStatus="pending";constructor(e,r){r={...r,debugShaders:r.debugShaders||e.props.debugShaders||"errors"},super(e,{id:CLe(r),...r},EG.defaultProps),this.stage=this.props.stage,this.source=this.props.source}getCompilationInfoSync(){return null}getTranslatedSource(){return null}async debugShader(){let e=this.props.debugShaders;switch(e){case"never":return;case"errors":if(this.compilationStatus==="success")return;break;case"warnings":case"always":break}let r=await this.getCompilationInfo();e==="warnings"&&r?.length===0||this._displayShaderLog(r,this.id)}_displayShaderLog(e,r){if(typeof document>"u"||!document?.createElement)return;let i=r,n=`${this.stage} shader "${i}"`,o=_ne(e,this.source,{showSourceCode:"all",html:!0}),s=this.getTranslatedSource(),c=document.createElement("div");c.innerHTML=`

Compilation error in ${n}

+
+
+ +
+
${o}
`,s&&(c.innerHTML+=`

Translated Source



${s}
`),c.style.top="0",c.style.left="0",c.style.background="white",c.style.position="fixed",c.style.zIndex="9999",c.style.maxWidth="100vw",c.style.maxHeight="100vh",c.style.overflowY="auto",document.body.appendChild(c),c.querySelector(".luma-compiler-log-error")?.scrollIntoView(),c.querySelector("button#close").onclick=()=>{c.remove()},c.querySelector("button#copy").onclick=()=>{navigator.clipboard.writeText(this.source)}}},Qv=EG;Qi(Qv,"defaultProps",{...$o.defaultProps,language:"auto",stage:void 0,source:"",sourceMap:null,entryPoint:"main",debugShaders:void 0})});var IG,KA,xne=Nt(()=>{ad();wG();Lg();IG=class extends $o{get[Symbol.toStringTag](){return"Framebuffer"}width;height;constructor(e,r={}){super(e,r,IG.defaultProps),this.width=this.props.width,this.height=this.props.height}clone(e){let r=this.colorAttachments.map(n=>n.texture.clone(e)),i=this.depthStencilAttachment&&this.depthStencilAttachment.texture.clone(e);return this.device.createFramebuffer({...this.props,...e,colorAttachments:r,depthStencilAttachment:i})}resize(e){let r=!e;if(e){let[i,n]=Array.isArray(e)?e:[e.width,e.height];r=r||n!==this.height||i!==this.width,this.width=i,this.height=n}r&&(Dr.log(2,`Resizing framebuffer ${this.id} to ${this.width}x${this.height}`)(),this.resizeAttachments(this.width,this.height))}autoCreateAttachmentTextures(){if(this.props.colorAttachments.length===0&&!this.props.depthStencilAttachment)throw new Error("Framebuffer has noattachments");this.colorAttachments=this.props.colorAttachments.map((r,i)=>{if(typeof r=="string"){let n=this.createColorTexture(r,i);return this.attachResource(n),n.view}return r instanceof oo?r.view:r});let e=this.props.depthStencilAttachment;if(e)if(typeof e=="string"){let r=this.createDepthStencilTexture(e);this.attachResource(r),this.depthStencilAttachment=r.view}else e instanceof oo?this.depthStencilAttachment=e.view:this.depthStencilAttachment=e}createColorTexture(e,r){return this.device.createTexture({id:`${this.id}-color-attachment-${r}`,usage:oo.RENDER_ATTACHMENT,format:e,width:this.width,height:this.height,sampler:{magFilter:"linear",minFilter:"linear"}})}createDepthStencilTexture(e){return this.device.createTexture({id:`${this.id}-depth-stencil-attachment`,usage:oo.RENDER_ATTACHMENT,format:e,width:this.width,height:this.height})}resizeAttachments(e,r){if(this.colorAttachments.forEach((i,n)=>{let o=i.texture.clone({width:e,height:r});this.destroyAttachedResource(i),this.colorAttachments[n]=o.view,this.attachResource(o.view)}),this.depthStencilAttachment){let i=this.depthStencilAttachment.texture.clone({width:e,height:r});this.destroyAttachedResource(this.depthStencilAttachment),this.depthStencilAttachment=i.view,this.attachResource(i)}this.updateAttachments()}},KA=IG;Qi(KA,"defaultProps",{...$o.defaultProps,width:1,height:1,colorAttachments:[],depthStencilAttachment:null})});var MG,km,PG=Nt(()=>{ad();MG=class extends $o{get[Symbol.toStringTag](){return"RenderPipeline"}shaderLayout;bufferLayout;linkStatus="pending";hash="";sharedRenderPipeline=null;get isPending(){return this.linkStatus==="pending"||this.vs.compilationStatus==="pending"||this.fs?.compilationStatus==="pending"}get isErrored(){return this.linkStatus==="error"||this.vs.compilationStatus==="error"||this.fs?.compilationStatus==="error"}constructor(e,r){super(e,r,MG.defaultProps),this.shaderLayout=this.props.shaderLayout,this.bufferLayout=this.props.bufferLayout||[],this.sharedRenderPipeline=this.props._sharedRenderPipeline||null}},km=MG;Qi(km,"defaultProps",{...$o.defaultProps,vs:null,vertexEntryPoint:"vertexMain",vsConstants:{},fs:null,fragmentEntryPoint:"fragmentMain",fsConstants:{},shaderLayout:null,bufferLayout:[],topology:"triangle-list",colorAttachmentFormats:void 0,depthStencilAttachmentFormat:void 0,parameters:{},varyings:void 0,bufferMode:void 0,disableWarnings:!1,_sharedRenderPipeline:void 0,bindings:void 0,bindGroups:void 0})});var rP,bne=Nt(()=>{ad();rP=class extends $o{get[Symbol.toStringTag](){return"SharedRenderPipeline"}constructor(e,r){super(e,r,{...$o.defaultProps,handle:void 0,vs:void 0,fs:void 0,varyings:void 0,bufferMode:void 0})}}});var RG,WT,wne=Nt(()=>{ad();RG=class extends $o{get[Symbol.toStringTag](){return"ComputePipeline"}hash="";shaderLayout;constructor(e,r){super(e,r,RG.defaultProps),this.shaderLayout=r.shaderLayout}},WT=RG;Qi(WT,"defaultProps",{...$o.defaultProps,shader:void 0,entryPoint:void 0,constants:{},shaderLayout:void 0})});var BG,qT,Tne=Nt(()=>{wne();PG();Lg();jT();BG=class{static getDefaultPipelineFactory(e){let r=e.getModuleData("@luma.gl/core");return r.defaultPipelineFactory||=new BG(e),r.defaultPipelineFactory}device;_hashCounter=0;_hashes={};_renderPipelineCache={};_computePipelineCache={};_sharedRenderPipelineCache={};get[Symbol.toStringTag](){return"PipelineFactory"}toString(){return`PipelineFactory(${this.device.id})`}constructor(e){this.device=e}createRenderPipeline(e){if(!this.device.props._cachePipelines)return this.device.createRenderPipeline(e);let r={...km.defaultProps,...e},i=this._renderPipelineCache,n=this._hashRenderPipeline(r),o=i[n]?.resource;if(o)i[n].useCount++,this.device.props.debugFactories&&Dr.log(3,`${this}: ${i[n].resource} reused, count=${i[n].useCount}, (id=${e.id})`)();else{let s=this.device.type==="webgl"&&this.device.props._sharePipelines?this.createSharedRenderPipeline(r):void 0;o=this.device.createRenderPipeline({...r,id:r.id?`${r.id}-cached`:XA("unnamed-cached"),_sharedRenderPipeline:s}),o.hash=n,i[n]={resource:o,useCount:1},this.device.props.debugFactories&&Dr.log(3,`${this}: ${o} created, count=${i[n].useCount}`)()}return o}createComputePipeline(e){if(!this.device.props._cachePipelines)return this.device.createComputePipeline(e);let r={...WT.defaultProps,...e},i=this._computePipelineCache,n=this._hashComputePipeline(r),o=i[n]?.resource;return o?(i[n].useCount++,this.device.props.debugFactories&&Dr.log(3,`${this}: ${i[n].resource} reused, count=${i[n].useCount}, (id=${e.id})`)()):(o=this.device.createComputePipeline({...r,id:r.id?`${r.id}-cached`:void 0}),o.hash=n,i[n]={resource:o,useCount:1},this.device.props.debugFactories&&Dr.log(3,`${this}: ${o} created, count=${i[n].useCount}`)()),o}release(e){if(!this.device.props._cachePipelines){e.destroy();return}let r=this._getCache(e),i=e.hash;r[i].useCount--,r[i].useCount===0?(this._destroyPipeline(e),this.device.props.debugFactories&&Dr.log(3,`${this}: ${e} released and destroyed`)()):r[i].useCount<0?(Dr.error(`${this}: ${e} released, useCount < 0, resetting`)(),r[i].useCount=0):this.device.props.debugFactories&&Dr.log(3,`${this}: ${e} released, count=${r[i].useCount}`)()}createSharedRenderPipeline(e){let r=this._hashSharedRenderPipeline(e),i=this._sharedRenderPipelineCache[r];return i||(i={resource:this.device._createSharedRenderPipelineWebGL(e),useCount:0},this._sharedRenderPipelineCache[r]=i),i.useCount++,i.resource}releaseSharedRenderPipeline(e){if(!e.sharedRenderPipeline)return;let r=this._hashSharedRenderPipeline(e.sharedRenderPipeline.props),i=this._sharedRenderPipelineCache[r];i&&(i.useCount--,i.useCount===0&&(i.resource.destroy(),delete this._sharedRenderPipelineCache[r]))}_destroyPipeline(e){let r=this._getCache(e);return this.device.props._destroyPipelines?(delete r[e.hash],e.destroy(),e instanceof km&&this.releaseSharedRenderPipeline(e),!0):!1}_getCache(e){let r;if(e instanceof WT&&(r=this._computePipelineCache),e instanceof km&&(r=this._renderPipelineCache),!r)throw new Error(`${this}`);if(!r[e.hash])throw new Error(`${this}: ${e} matched incorrect entry`);return r}_hashComputePipeline(e){let{type:r}=this.device,i=this._getHash(e.shader.source),n=this._getHash(JSON.stringify(e.shaderLayout));return`${r}/C/${i}SL${n}`}_hashRenderPipeline(e){let r=e.vs?this._getHash(e.vs.source):0,i=e.fs?this._getHash(e.fs.source):0,n=this._getWebGLVaryingHash(e),o=this._getHash(JSON.stringify(e.shaderLayout)),s=this._getHash(JSON.stringify(e.bufferLayout)),{type:c}=this.device;switch(c){case"webgl":let f=this._getHash(JSON.stringify(e.parameters));return`${c}/R/${r}/${i}V${n}T${e.topology}P${f}SL${o}BL${s}`;case"webgpu":default:let g=this._getHash(JSON.stringify({vertexEntryPoint:e.vertexEntryPoint,fragmentEntryPoint:e.fragmentEntryPoint})),y=this._getHash(JSON.stringify(e.parameters)),I=this._getWebGPUAttachmentHash(e);return`${c}/R/${r}/${i}V${n}T${e.topology}EP${g}P${y}SL${o}BL${s}A${I}`}}_hashSharedRenderPipeline(e){let r=e.vs?this._getHash(e.vs.source):0,i=e.fs?this._getHash(e.fs.source):0,n=this._getWebGLVaryingHash(e);return`webgl/S/${r}/${i}V${n}`}_getHash(e){return this._hashes[e]===void 0&&(this._hashes[e]=this._hashCounter++),this._hashes[e]}_getWebGLVaryingHash(e){let{varyings:r=[],bufferMode:i=null}=e;return this._getHash(JSON.stringify({varyings:r,bufferMode:i}))}_getWebGPUAttachmentHash(e){let r=e.colorAttachmentFormats??[this.device.preferredColorFormat],i=e.parameters?.depthWriteEnabled?e.depthStencilAttachmentFormat||this.device.preferredDepthFormat:null;return this._getHash(JSON.stringify({colorAttachmentFormats:r,depthStencilAttachmentFormat:i}))}},qT=BG;Qi(qT,"defaultProps",{...km.defaultProps})});var LG,$T,Sne=Nt(()=>{CG();Lg();LG=class{static getDefaultShaderFactory(e){let r=e.getModuleData("@luma.gl/core");return r.defaultShaderFactory||=new LG(e),r.defaultShaderFactory}device;_cache={};get[Symbol.toStringTag](){return"ShaderFactory"}toString(){return`${this[Symbol.toStringTag]}(${this.device.id})`}constructor(e){this.device=e}createShader(e){if(!this.device.props._cacheShaders)return this.device.createShader(e);let r=this._hashShader(e),i=this._cache[r];if(i)i.useCount++,this.device.props.debugFactories&&Dr.log(3,`${this}: Reusing shader ${i.resource.id} count=${i.useCount}`)();else{let n=this.device.createShader({...e,id:e.id?`${e.id}-cached`:void 0});this._cache[r]=i={resource:n,useCount:1},this.device.props.debugFactories&&Dr.log(3,`${this}: Created new shader ${n.id}`)()}return i.resource}release(e){if(!this.device.props._cacheShaders){e.destroy();return}let r=this._hashShader(e),i=this._cache[r];if(i)if(i.useCount--,i.useCount===0)this.device.props._destroyShaders&&(delete this._cache[r],i.resource.destroy(),this.device.props.debugFactories&&Dr.log(3,`${this}: Releasing shader ${e.id}, destroyed`)());else{if(i.useCount<0)throw new Error(`ShaderFactory: Shader ${e.id} released too many times`);this.device.props.debugFactories&&Dr.log(3,`${this}: Releasing shader ${e.id} count=${i.useCount}`)()}}_hashShader(e){return`${e.stage}:${e.source}`}},$T=LG;Qi($T,"defaultProps",{...Qv.defaultProps})});function Ene(t,e,r){let i=t.bindings.find(n=>n.name===e||`${n.name.toLocaleLowerCase()}uniforms`===e.toLocaleLowerCase());return!i&&!r?.ignoreWarnings&&Dr.warn(`Binding ${e} not set: Not found in shader layout.`)(),i||null}function iP(t,e){if(!e)return{};if(MLe(e))return Object.fromEntries(Object.entries(e).map(([n,o])=>[Number(n),{...o}]));let r={};for(let[i,n]of Object.entries(e)){let s=Ene(t,i)?.group??0;r[s]||={},r[s][i]=n}return r}function ZF(t){let e={};for(let r of Object.values(t))Object.assign(e,r);return e}function MLe(t){let e=Object.keys(t);return e.length>0&&e.every(r=>/^\d+$/.test(r))}var Cne=Nt(()=>{Lg()});var E1,gy,Ine=Nt(()=>{ad();E1=class extends $o{get[Symbol.toStringTag](){return"RenderPass"}constructor(e,r){r=E1.normalizeProps(e,r),super(e,r,E1.defaultProps)}static normalizeProps(e,r){return r}},gy=E1;Qi(gy,"defaultClearColor",[0,0,0,1]),Qi(gy,"defaultClearDepth",1),Qi(gy,"defaultClearStencil",0),Qi(gy,"defaultProps",{...$o.defaultProps,framebuffer:null,parameters:void 0,clearColor:E1.defaultClearColor,clearColors:void 0,clearDepth:E1.defaultClearDepth,clearStencil:E1.defaultClearStencil,depthReadOnly:!1,stencilReadOnly:!1,discard:!1,occlusionQuerySet:void 0,timestampQuerySet:void 0,beginTimestampIndex:void 0,endTimestampIndex:void 0})});var DG,XT,Mne=Nt(()=>{ad();DG=class extends $o{get[Symbol.toStringTag](){return"CommandEncoder"}_timeProfilingQuerySet=null;_timeProfilingSlotCount=0;_gpuTimeMs;constructor(e,r){super(e,r,DG.defaultProps),this._timeProfilingQuerySet=r.timeProfilingQuerySet??null,this._timeProfilingSlotCount=0,this._gpuTimeMs=void 0}async resolveTimeProfilingQuerySet(){if(this._gpuTimeMs=void 0,!this._timeProfilingQuerySet)return;let e=Math.floor(this._timeProfilingSlotCount/2);if(e<=0)return;let r=e*2,i=await this._timeProfilingQuerySet.readResults({firstQuery:0,queryCount:r}),n=0n;for(let o=0;o=this._timeProfilingQuerySet.props.count?r:(this._timeProfilingSlotCount+=2,{...r,timestampQuerySet:this._timeProfilingQuerySet,beginTimestampIndex:i,endTimestampIndex:i+1})}_supportsTimestampQueries(){return this.device.features.has("timestamp-query")}},XT=DG;Qi(XT,"defaultProps",{...$o.defaultProps,measureExecutionTime:void 0,timeProfilingQuerySet:void 0})});var OG,ZT,Pne=Nt(()=>{ad();OG=class extends $o{get[Symbol.toStringTag](){return"CommandBuffer"}constructor(e,r){super(e,r,OG.defaultProps)}},ZT=OG;Qi(ZT,"defaultProps",{...$o.defaultProps})});function YT(t){let e=YF(t),r=LLe[e];if(!r)throw new Error(`Unsupported variable shader type: ${t}`);return r}function Rne(t){let e=Bne(t),r=BLe[e];if(!r)throw new Error(`Unsupported attribute shader type: ${t}`);let[i,n]=r,o=i==="i32"||i==="u32",s=i!=="u32",c=RLe[i]*n;return{primitiveType:i,components:n,byteLength:c,integer:o,signed:s}}function PLe(t,e){return e===1?t:`vec${e}<${t}>`}function Bne(t){return DLe[t]||t}function YF(t){return OLe[t]||t}var FG,kG,RLe,BLe,LLe,DLe,OLe,KF=Nt(()=>{FG=class{getVariableShaderTypeInfo(e){return YT(e)}getAttributeShaderTypeInfo(e){return Rne(e)}makeShaderAttributeType(e,r){return PLe(e,r)}resolveAttributeShaderTypeAlias(e){return Bne(e)}resolveVariableShaderTypeAlias(e){return YF(e)}};kG=new FG,RLe={f32:4,f16:2,i32:4,u32:4},BLe={f32:["f32",1],"vec2":["f32",2],"vec3":["f32",3],"vec4":["f32",4],f16:["f16",1],"vec2":["f16",2],"vec3":["f16",3],"vec4":["f16",4],i32:["i32",1],"vec2":["i32",2],"vec3":["i32",3],"vec4":["i32",4],u32:["u32",1],"vec2":["u32",2],"vec3":["u32",3],"vec4":["u32",4]},LLe={f32:{type:"f32",components:1},f16:{type:"f16",components:1},i32:{type:"i32",components:1},u32:{type:"u32",components:1},"vec2":{type:"f32",components:2},"vec3":{type:"f32",components:3},"vec4":{type:"f32",components:4},"vec2":{type:"f16",components:2},"vec3":{type:"f16",components:3},"vec4":{type:"f16",components:4},"vec2":{type:"i32",components:2},"vec3":{type:"i32",components:3},"vec4":{type:"i32",components:4},"vec2":{type:"u32",components:2},"vec3":{type:"u32",components:3},"vec4":{type:"u32",components:4},"mat2x2":{type:"f32",components:4},"mat2x3":{type:"f32",components:6},"mat2x4":{type:"f32",components:8},"mat3x2":{type:"f32",components:6},"mat3x3":{type:"f32",components:9},"mat3x4":{type:"f32",components:12},"mat4x2":{type:"f32",components:8},"mat4x3":{type:"f32",components:12},"mat4x4":{type:"f32",components:16},"mat2x2":{type:"f16",components:4},"mat2x3":{type:"f16",components:6},"mat2x4":{type:"f16",components:8},"mat3x2":{type:"f16",components:6},"mat3x3":{type:"f16",components:9},"mat3x4":{type:"f16",components:12},"mat4x2":{type:"f16",components:8},"mat4x3":{type:"f16",components:12},"mat4x4":{type:"f16",components:16},"mat2x2":{type:"i32",components:4},"mat2x3":{type:"i32",components:6},"mat2x4":{type:"i32",components:8},"mat3x2":{type:"i32",components:6},"mat3x3":{type:"i32",components:9},"mat3x4":{type:"i32",components:12},"mat4x2":{type:"i32",components:8},"mat4x3":{type:"i32",components:12},"mat4x4":{type:"i32",components:16},"mat2x2":{type:"u32",components:4},"mat2x3":{type:"u32",components:6},"mat2x4":{type:"u32",components:8},"mat3x2":{type:"u32",components:6},"mat3x3":{type:"u32",components:9},"mat3x4":{type:"u32",components:12},"mat4x2":{type:"u32",components:8},"mat4x3":{type:"u32",components:12},"mat4x4":{type:"u32",components:16}},DLe={vec2i:"vec2",vec3i:"vec3",vec4i:"vec4",vec2u:"vec2",vec3u:"vec3",vec4u:"vec4",vec2f:"vec2",vec3f:"vec3",vec4f:"vec4",vec2h:"vec2",vec3h:"vec3",vec4h:"vec4"},OLe={vec2i:"vec2",vec3i:"vec3",vec4i:"vec4",vec2u:"vec2",vec3u:"vec3",vec4u:"vec4",vec2f:"vec2",vec3f:"vec3",vec4f:"vec4",vec2h:"vec2",vec3h:"vec3",vec4h:"vec4",mat2x2f:"mat2x2",mat2x3f:"mat2x3",mat2x4f:"mat2x4",mat3x2f:"mat3x2",mat3x3f:"mat3x3",mat3x4f:"mat3x4",mat4x2f:"mat4x2",mat4x3f:"mat4x3",mat4x4f:"mat4x4",mat2x2i:"mat2x2",mat2x3i:"mat2x3",mat2x4i:"mat2x4",mat3x2i:"mat3x2",mat3x3i:"mat3x3",mat3x4i:"mat3x4",mat4x2i:"mat4x2",mat4x3i:"mat4x3",mat4x4i:"mat4x4",mat2x2u:"mat2x2",mat2x3u:"mat2x3",mat2x4u:"mat2x4",mat3x2u:"mat3x2",mat3x3u:"mat3x3",mat3x4u:"mat3x4",mat4x2u:"mat4x2",mat4x3u:"mat4x3",mat4x4u:"mat4x4",mat2x2h:"mat2x2",mat2x3h:"mat2x3",mat2x4h:"mat2x4",mat3x2h:"mat3x2",mat3x3h:"mat3x3",mat3x4h:"mat3x4",mat4x2h:"mat4x2",mat4x3h:"mat4x3",mat4x4h:"mat4x4"}});function QF(t,e){let r={};for(let i of t.attributes){let n=FLe(t,e,i.name);n&&(r[i.name]=n)}return r}function Lne(t,e,r=16){let i=QF(t,e),n=new Array(r).fill(null);for(let o of Object.values(i))n[o.location]=o;return n}function FLe(t,e,r){let i=kLe(t,r),n=NLe(e,r);if(!i)return null;let o=kG.getAttributeShaderTypeInfo(i.type),s=py.getCompatibleVertexFormat(o),c=n?.vertexFormat||s,f=py.getVertexFormatInfo(c);return{attributeName:n?.attributeName||i.name,bufferName:n?.bufferName||i.name,location:i.location,shaderType:i.type,primitiveType:o.primitiveType,shaderComponents:o.components,vertexFormat:c,bufferDataType:f.type,bufferComponents:f.components,normalized:f.normalized,integer:o.integer,stepMode:n?.stepMode||i.stepMode||"vertex",byteOffset:n?.byteOffset||0,byteStride:n?.byteStride||0}}function kLe(t,e){let r=t.attributes.find(i=>i.name===e);return r||Dr.warn(`shader layout attribute "${e}" not present in shader`),r||null}function NLe(t,e){zLe(t);let r=ULe(t,e);return r||(r=VLe(t,e),r)?r:(Dr.warn(`layout for attribute "${e}" not present in buffer layout`),null)}function zLe(t){for(let e of t)(e.attributes&&e.format||!e.attributes&&!e.format)&&Dr.warn(`BufferLayout ${name} must have either 'attributes' or 'format' field`)}function ULe(t,e){for(let r of t)if(r.format&&r.name===e)return{attributeName:r.name,bufferName:e,stepMode:r.stepMode,vertexFormat:r.format,byteOffset:0,byteStride:r.byteStride||0};return null}function VLe(t,e){for(let r of t){let i=r.byteStride;if(typeof r.byteStride!="number")for(let o of r.attributes||[]){let s=py.getVertexFormatInfo(o.format);i+=s.byteLength}let n=r.attributes?.find(o=>o.attribute===e);if(n)return{attributeName:n.attribute,bufferName:r.name,stepMode:r.stepMode,vertexFormat:n.format,byteOffset:n.byteOffset,byteStride:i}}return null}var NG=Nt(()=>{Lg();KF();zF()});var zG,KT,Dne=Nt(()=>{NG();ad();zG=class extends $o{get[Symbol.toStringTag](){return"VertexArray"}maxVertexAttributes;attributeInfos;indexBuffer=null;attributes;constructor(e,r){super(e,r,zG.defaultProps),this.maxVertexAttributes=e.limits.maxVertexAttributes,this.attributes=new Array(this.maxVertexAttributes).fill(null),this.attributeInfos=Lne(r.shaderLayout,r.bufferLayout,this.maxVertexAttributes)}setConstantWebGL(e,r){this.device.reportError(new Error("constant attributes not supported"),this)()}},KT=zG;Qi(KT,"defaultProps",{...$o.defaultProps,shaderLayout:void 0,bufferLayout:[]})});var UG,QT,One=Nt(()=>{ad();UG=class extends $o{get[Symbol.toStringTag](){return"TransformFeedback"}constructor(e,r){super(e,r,UG.defaultProps)}},QT=UG;Qi(QT,"defaultProps",{...$o.defaultProps,layout:void 0,buffers:{}})});var VG,JT,Fne=Nt(()=>{ad();VG=class extends $o{get[Symbol.toStringTag](){return"QuerySet"}constructor(e,r){super(e,r,VG.defaultProps)}},JT=VG;Qi(JT,"defaultProps",{...$o.defaultProps,type:void 0,count:void 0})});var jG,eS,kne=Nt(()=>{ad();jG=class extends $o{get[Symbol.toStringTag](){return"Fence"}constructor(e,r={}){super(e,r,jG.defaultProps)}},eS=jG;Qi(eS,"defaultProps",{...$o.defaultProps})});function QA(t,e){switch(e){case 1:return t;case 2:return t+t%2;default:return t+(4-t%4)%4}}function nP(t){let[,,,,e]=jLe[t];return e}var jLe,HG=Nt(()=>{jLe={uint8:["uint8","u32",1,!1,Uint8Array],sint8:["sint8","i32",1,!1,Int8Array],unorm8:["uint8","f32",1,!0,Uint8Array],snorm8:["sint8","f32",1,!0,Int8Array],uint16:["uint16","u32",2,!1,Uint16Array],sint16:["sint16","i32",2,!1,Int16Array],unorm16:["uint16","u32",2,!0,Uint16Array],snorm16:["sint16","i32",2,!0,Int16Array],float16:["float16","f16",2,!1,Uint16Array],float32:["float32","f32",4,!1,Float32Array],uint32:["uint32","u32",4,!1,Uint32Array],sint32:["sint32","i32",4,!1,Int32Array]}});function zne(t,e={}){let r={...t},i=e.layout??"std140",n={},o=0;for(let[s,c]of Object.entries(r))o=GG(n,s,c,o,i);return o=QA(o,Jv(r,i)),{layout:i,byteLength:o*4,uniformTypes:r,fields:n}}function oP(t,e){let r=YF(t),i=YT(r),n=/^mat(\d)x(\d)<.+>$/.exec(r);if(n){let s=Number(n[1]),c=Number(n[2]),f=Nne(c,r,i.type,e),g=GLe(f.size,f.alignment,e);return{alignment:f.alignment,size:s*g,components:s*c,columns:s,rows:c,columnStride:g,shaderType:r,type:i.type}}let o=/^vec(\d)<.+>$/.exec(r);return o?Nne(Number(o[1]),r,i.type,e):{alignment:1,size:1,components:1,columns:1,rows:1,columnStride:1,shaderType:r,type:i.type}}function WG(t){return Boolean(t)&&typeof t=="object"&&!Array.isArray(t)}function GG(t,e,r,i,n){if(typeof r=="string"){let o=oP(r,n),s=QA(i,o.alignment);return t[e]={offset:s,...o},s+o.size}if(Array.isArray(r)){if(Array.isArray(r[0]))throw new Error(`Nested arrays are not supported for ${e}`);let o=r[0],s=r[1],c=Vne(o,n),f=QA(i,Jv(r,n));for(let g=0;g{HG();KF()});function $G(t){return(!JF||JF.byteLength{});function qLe(t){return ArrayBuffer.isView(t)&&!(t instanceof DataView)}function tS(t){return Array.isArray(t)?t.length===0||typeof t[0]=="number":qLe(t)}var YG=Nt(()=>{});function $Le(t){return Boolean(t)&&typeof t=="object"&&!Array.isArray(t)&&!ArrayBuffer.isView(t)}function XLe(t,e,r){return Array.prototype.slice.call(t,e,r)}var ek,Hne=Nt(()=>{ZG();YG();Lg();qG();ek=class{layout;constructor(e){this.layout=e}has(e){return Boolean(this.layout.fields[e])}get(e){let r=this.layout.fields[e];return r?{offset:r.offset,size:r.size}:void 0}getFlatUniformValues(e){let r={};for(let[i,n]of Object.entries(e)){let o=this.layout.uniformTypes[i];o?this._flattenCompositeValue(r,i,o,n):this.layout.fields[i]&&(r[i]=n)}return r}getData(e){let r=$G(this.layout.byteLength);new Uint8Array(r,0,this.layout.byteLength).fill(0);let i={i32:new Int32Array(r),u32:new Uint32Array(r),f32:new Float32Array(r),f16:new Uint16Array(r)},n=this.getFlatUniformValues(e);for(let[o,s]of Object.entries(n))this._writeLeafValue(i,o,s);return new Uint8Array(r,0,this.layout.byteLength)}_flattenCompositeValue(e,r,i,n){if(n!==void 0){if(typeof i=="string"||this.layout.fields[r]){e[r]=n;return}if(Array.isArray(i)){let o=i[0],s=i[1];if(Array.isArray(o))throw new Error(`Nested arrays are not supported for ${r}`);if(typeof o=="string"&&tS(n)){this._flattenPackedArray(e,r,o,s,n);return}if(!Array.isArray(n)){Dr.warn(`Unsupported uniform array value for ${r}:`,n)();return}for(let c=0;c=s.length)break;f===1?e[`${r}[${g}]`]=Number(s[y]):e[`${r}[${g}]`]=XLe(o,y,y+f)}}_writeLeafValue(e,r,i){let n=this.layout.fields[r];if(!n){Dr.warn(`Uniform ${r} not found in layout`)();return}let{type:o,components:s,columns:c,rows:f,offset:g,columnStride:y}=n,I=e[o];if(s===1){I[g]=Number(i);return}let F=i;if(c===1){for(let U=0;Uo)return!1;for(let s=0;s{YG();ZLe=128});var tk,$ne=Nt(()=>{qne();tk=class{name;uniforms={};modifiedUniforms={};modified=!0;bindingLayout={};needsRedraw="initialized";constructor(e){if(this.name=e?.name||"unnamed",e?.name&&e?.shaderLayout){let r=e?.shaderLayout.bindings?.find(n=>n.type==="uniform"&&n.name===e?.name);if(!r)throw new Error(e?.name);let i=r;for(let n of i.uniforms||[])this.bindingLayout[n.name]=n}}setUniforms(e){for(let[r,i]of Object.entries(e))this._setUniform(r,i),this.needsRedraw||this.setNeedsRedraw(`${this.name}.${r}=${i}`)}setNeedsRedraw(e){this.needsRedraw=this.needsRedraw||e}getAllUniforms(){return this.modifiedUniforms={},this.needsRedraw=!1,this.uniforms||{}}_setUniform(e,r){Gne(this.uniforms[e],r)||(this.uniforms[e]=Wne(r),this.modifiedUniforms[e]=!0,this.modified=!0)}}});function KLe(t){return t.type==="webgpu"?"wgsl-uniform":"std140"}var YLe,C1,Xne=Nt(()=>{kF();Lg();qG();$ne();Hne();YLe=1024,C1=class{device;uniformBlocks=new Map;shaderBlockLayouts=new Map;shaderBlockWriters=new Map;uniformBuffers=new Map;constructor(e,r){this.device=e;for(let[i,n]of Object.entries(r)){let o=i,s=zne(n.uniformTypes??{},{layout:n.layout??KLe(e)}),c=new ek(s);this.shaderBlockLayouts.set(o,s),this.shaderBlockWriters.set(o,c);let f=new tk({name:i});f.setUniforms(c.getFlatUniformValues(n.defaultUniforms||{})),this.uniformBlocks.set(o,f)}}destroy(){for(let e of this.uniformBuffers.values())e.destroy()}setUniforms(e){for(let[r,i]of Object.entries(e)){let n=r,s=this.shaderBlockWriters.get(n)?.getFlatUniformValues(i||{});this.uniformBlocks.get(n)?.setUniforms(s||{})}this.updateUniformBuffers()}getUniformBufferByteLength(e){let r=this.shaderBlockLayouts.get(e)?.byteLength||0;return Math.max(r,YLe)}getUniformBufferData(e){let r=this.uniformBlocks.get(e)?.getAllUniforms()||{};return this.shaderBlockWriters.get(e)?.getData(r)||new Uint8Array(0)}createUniformBuffer(e,r){r&&this.setUniforms(r);let i=this.getUniformBufferByteLength(e),n=this.device.createBuffer({usage:lo.UNIFORM|lo.COPY_DST,byteLength:i}),o=this.getUniformBufferData(e);return n.write(o),n}getManagedUniformBuffer(e){if(!this.uniformBuffers.get(e)){let r=this.getUniformBufferByteLength(e),i=this.device.createBuffer({usage:lo.UNIFORM|lo.COPY_DST,byteLength:r});this.uniformBuffers.set(e,i)}return this.uniformBuffers.get(e)}updateUniformBuffers(){let e=!1;for(let r of this.uniformBlocks.keys()){let i=this.updateUniformBuffer(r);e||=i}return e&&Dr.log(3,`UniformStore.updateUniformBuffers(): ${e}`)(),e}updateUniformBuffer(e){let r=this.uniformBlocks.get(e),i=this.uniformBuffers.get(e),n=!1;if(i&&r?.needsRedraw){n||=r.needsRedraw;let o=this.getUniformBufferData(e);i=this.uniformBuffers.get(e),i?.write(o);let s=this.uniformBlocks.get(e)?.getAllUniforms();Dr.log(4,`Writing to uniform buffer ${String(e)}`,o,s)()}return n}}});var Eo=Nt(()=>{lne();cne();_G();mne();gne();kF();wG();Ane();CG();bG();xne();PG();bne();Tne();Sne();Ine();Mne();Pne();Dne();One();Fne();kne();Xne();NF();HG();KF();zF();HF();mG();Lg();Cne();vG();ZG();NG()});function Ese(t=!0){let e=HTMLCanvasElement.prototype;if(!t&&e.originalGetContext){e.getContext=e.originalGetContext,e.originalGetContext=void 0;return}e.originalGetContext=e.getContext,e.getContext=function(r,i){if(r==="webgl"||r==="experimental-webgl"){let n=this.originalGetContext("webgl2",i);return n instanceof HTMLElement&&Eke(n),n}return this.originalGetContext(r,i)}}function Eke(t){t.getExtension("EXT_color_buffer_float");let e={...bke,WEBGL_disjoint_timer_query:t.getExtension("EXT_disjoint_timer_query_webgl2"),WEBGL_draw_buffers:wke(t),OES_vertex_array_object:Tke(t),ANGLE_instanced_arrays:Ske(t)},r=t.getExtension;t.getExtension=function(n){let o=r.call(t,n);return o||(n in e?e[n]:null)};let i=t.getSupportedExtensions;t.getSupportedExtensions=function(){return(i.apply(t)||[])?.concat(Object.keys(e))}}var bke,wke,Tke,Ske,Cse=Nt(()=>{bke={WEBGL_depth_texture:{UNSIGNED_INT_24_8_WEBGL:34042},OES_element_index_uint:{},OES_texture_float:{},OES_texture_half_float:{HALF_FLOAT_OES:5131},EXT_color_buffer_float:{},OES_standard_derivatives:{FRAGMENT_SHADER_DERIVATIVE_HINT_OES:35723},EXT_frag_depth:{},EXT_blend_minmax:{MIN_EXT:32775,MAX_EXT:32776},EXT_shader_texture_lod:{}},wke=t=>({drawBuffersWEBGL(e){return t.drawBuffers(e)},COLOR_ATTACHMENT0_WEBGL:36064,COLOR_ATTACHMENT1_WEBGL:36065,COLOR_ATTACHMENT2_WEBGL:36066,COLOR_ATTACHMENT3_WEBGL:36067}),Tke=t=>({VERTEX_ARRAY_BINDING_OES:34229,createVertexArrayOES(){return t.createVertexArray()},deleteVertexArrayOES(e){return t.deleteVertexArray(e)},isVertexArrayOES(e){return t.isVertexArray(e)},bindVertexArrayOES(e){return t.bindVertexArray(e)}}),Ske=t=>({VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:35070,drawArraysInstancedANGLE(...e){return t.drawArraysInstanced(...e)},drawElementsInstancedANGLE(...e){return t.drawElementsInstanced(...e)},vertexAttribDivisorANGLE(...e){return t.vertexAttribDivisor(...e)}})});async function Xk(t,e){let r=document.getElementsByTagName("head")[0];if(!r)throw new Error("loadScript");let i=document.createElement("script");return i.setAttribute("type","text/javascript"),i.setAttribute("src",t),e&&(i.id=e),new Promise((n,o)=>{i.onload=n,i.onerror=s=>o(new Error(`Unable to load script '${t}': ${s}`)),r.appendChild(i)})}var V9=Nt(()=>{});function j1(t){let e=t.luma||{_polyfilled:!1,extensions:{},softwareRenderer:!1};return e._polyfilled??=!1,e.extensions||={},t.luma=e,e}var Zk=Nt(()=>{});async function Mse(t){if(!globalThis.SPECTOR)try{await Xk(t.debugSpectorJSUrl||Yk.debugSpectorJSUrl)}catch(e){Dr.warn(String(e))}}function Pse(t){if(t={...Yk,...t},!t.debugSpectorJS)return null;if(!zm&&globalThis.SPECTOR&&!globalThis.luma?.spector){Dr.probe(Cke,"SPECTOR found and initialized. Start with `luma.spector.displayUI()`")();let{Spector:e}=globalThis.SPECTOR;zm=new e,globalThis.luma&&(globalThis.luma.spector=zm)}if(!zm)return null;if(Ise||(Ise=!0,zm.spyCanvases(),zm?.onCaptureStarted.add(e=>Dr.info("Spector capture started:",e)()),zm?.onCapture.add(e=>{Dr.info("Spector capture complete:",e)(),zm?.getResultUI(),zm?.resultView.display(),zm?.resultView.addCapture(e)})),t.gl){let e=t.gl,r=j1(e),i=r.device;zm?.startCapture(t.gl,500),r.device=i,new Promise(n=>setTimeout(n,2e3)).then(n=>{Dr.info("Spector capture stopped after 2 seconds")(),zm?.stopCapture()})}return zm}var Cke,zm,Ise,Yk,j9=Nt(()=>{Eo();V9();Zk();Cke=1,zm=null,Ise=!1,Yk={debugSpectorJS:Dr.get("debug-spectorjs"),debugSpectorJSUrl:"https://cdn.jsdelivr.net/npm/spectorjs@0.9.30/dist/spector.bundle.js",gl:void 0}});function Bse(t){return t.luma=t.luma||{},t.luma}async function Lse(){rp()&&!globalThis.WebGLDebugUtils&&(globalThis.global=globalThis.global||globalThis,globalThis.global.module={},await Xk(Ike))}function Dse(t,e={}){return e.debugWebGL||e.traceWebGL?Pke(t,e):Mke(t)}function Mke(t){let e=Bse(t);return e.realContext?e.realContext:t}function Pke(t,e){if(!globalThis.WebGLDebugUtils)return Dr.warn("webgl-debug not loaded")(),t;let r=Bse(t);if(r.debugContext)return r.debugContext;globalThis.WebGLDebugUtils.init({...WA,...t});let i=globalThis.WebGLDebugUtils.makeDebugContext(t,Rke.bind(null,e),Bke.bind(null,e));for(let s in WA)!(s in i)&&typeof WA[s]=="number"&&(i[s]=WA[s]);class n{}Object.setPrototypeOf(i,Object.getPrototypeOf(t)),Object.setPrototypeOf(n,i);let o=Object.create(n);return r.realContext=t,r.debugContext=o,o.luma=r,o.debug=!0,o}function Rse(t,e){e=Array.from(e).map(i=>i===void 0?"undefined":i);let r=globalThis.WebGLDebugUtils.glFunctionArgsToString(t,e);return r=`${r.slice(0,100)}${r.length>100?"...":""}`,`gl.${t}(${r})`}function Rke(t,e,r,i){i=Array.from(i).map(c=>c===void 0?"undefined":c);let n=globalThis.WebGLDebugUtils.glEnumToString(e),o=globalThis.WebGLDebugUtils.glFunctionArgsToString(r,i),s=`${n} in gl.${r}(${o})`;Dr.error("%cWebGL","color: white; background: red; padding: 2px 6px; border-radius: 3px;",s)();debugger;throw new Error(s)}function Bke(t,e,r){let i="";t.traceWebGL&&Dr.level>=1&&(i=Rse(e,r),Dr.info(1,"%cWebGL","color: white; background: blue; padding: 2px 6px; border-radius: 3px;",i)());for(let n of r)if(n===void 0){i=i||Rse(e,r);debugger}}var Ike,H9=Nt(()=>{Eo();Mj();Iv();V9();Ike="https://unpkg.com/webgl-debug@2.0.1/index.js"});function G9(t){return Array.isArray(t)||ArrayBuffer.isView(t)&&!(t instanceof DataView)}function Wu(t,e,r){return e[t]!==void 0?e[t]:r[t]}var jP,kh,Ose,Um,Fse,VP,kse,Nse,W9,s_,q9,zse,$9=Nt(()=>{jP={[3042]:!1,[32773]:new Float32Array([0,0,0,0]),[32777]:32774,[34877]:32774,[32969]:1,[32968]:0,[32971]:1,[32970]:0,[3106]:new Float32Array([0,0,0,0]),[3107]:[!0,!0,!0,!0],[2884]:!1,[2885]:1029,[2929]:!1,[2931]:1,[2932]:513,[2928]:new Float32Array([0,1]),[2930]:!0,[3024]:!0,[35725]:null,[36006]:null,[36007]:null,[34229]:null,[34964]:null,[2886]:2305,[33170]:4352,[2849]:1,[32823]:!1,[32824]:0,[10752]:0,[32926]:!1,[32928]:!1,[32938]:1,[32939]:!1,[3089]:!1,[3088]:new Int32Array([0,0,1024,1024]),[2960]:!1,[2961]:0,[2968]:4294967295,[36005]:4294967295,[2962]:519,[2967]:0,[2963]:4294967295,[34816]:519,[36003]:0,[36004]:4294967295,[2964]:7680,[2965]:7680,[2966]:7680,[34817]:7680,[34818]:7680,[34819]:7680,[2978]:[0,0,1024,1024],[36389]:null,[36662]:null,[36663]:null,[35053]:null,[35055]:null,[35723]:4352,[36010]:null,[35977]:!1,[3333]:4,[3317]:4,[37440]:!1,[37441]:!1,[37443]:37444,[3330]:0,[3332]:0,[3331]:0,[3314]:0,[32878]:0,[3316]:0,[3315]:0,[32877]:0},kh=(t,e,r)=>e?t.enable(r):t.disable(r),Ose=(t,e,r)=>t.hint(r,e),Um=(t,e,r)=>t.pixelStorei(r,e),Fse=(t,e,r)=>{let i=r===36006?36009:36008;return t.bindFramebuffer(i,e)},VP=(t,e,r)=>{let n={[34964]:34962,[36662]:36662,[36663]:36663,[35053]:35051,[35055]:35052}[r];t.bindBuffer(n,e)};kse={[3042]:kh,[32773]:(t,e)=>t.blendColor(...e),[32777]:"blendEquation",[34877]:"blendEquation",[32969]:"blendFunc",[32968]:"blendFunc",[32971]:"blendFunc",[32970]:"blendFunc",[3106]:(t,e)=>t.clearColor(...e),[3107]:(t,e)=>t.colorMask(...e),[2884]:kh,[2885]:(t,e)=>t.cullFace(e),[2929]:kh,[2931]:(t,e)=>t.clearDepth(e),[2932]:(t,e)=>t.depthFunc(e),[2928]:(t,e)=>t.depthRange(...e),[2930]:(t,e)=>t.depthMask(e),[3024]:kh,[35723]:Ose,[35725]:(t,e)=>t.useProgram(e),[36007]:(t,e)=>t.bindRenderbuffer(36161,e),[36389]:(t,e)=>t.bindTransformFeedback?.(36386,e),[34229]:(t,e)=>t.bindVertexArray(e),[36006]:Fse,[36010]:Fse,[34964]:VP,[36662]:VP,[36663]:VP,[35053]:VP,[35055]:VP,[2886]:(t,e)=>t.frontFace(e),[33170]:Ose,[2849]:(t,e)=>t.lineWidth(e),[32823]:kh,[32824]:"polygonOffset",[10752]:"polygonOffset",[35977]:kh,[32926]:kh,[32928]:kh,[32938]:"sampleCoverage",[32939]:"sampleCoverage",[3089]:kh,[3088]:(t,e)=>t.scissor(...e),[2960]:kh,[2961]:(t,e)=>t.clearStencil(e),[2968]:(t,e)=>t.stencilMaskSeparate(1028,e),[36005]:(t,e)=>t.stencilMaskSeparate(1029,e),[2962]:"stencilFuncFront",[2967]:"stencilFuncFront",[2963]:"stencilFuncFront",[34816]:"stencilFuncBack",[36003]:"stencilFuncBack",[36004]:"stencilFuncBack",[2964]:"stencilOpFront",[2965]:"stencilOpFront",[2966]:"stencilOpFront",[34817]:"stencilOpBack",[34818]:"stencilOpBack",[34819]:"stencilOpBack",[2978]:(t,e)=>t.viewport(...e),[34383]:kh,[10754]:kh,[12288]:kh,[12289]:kh,[12290]:kh,[12291]:kh,[12292]:kh,[12293]:kh,[12294]:kh,[12295]:kh,[3333]:Um,[3317]:Um,[37440]:Um,[37441]:Um,[37443]:Um,[3330]:Um,[3332]:Um,[3331]:Um,[3314]:Um,[32878]:Um,[3316]:Um,[3315]:Um,[32877]:Um,framebuffer:(t,e)=>{let r=e&&"handle"in e?e.handle:e;return t.bindFramebuffer(36160,r)},blend:(t,e)=>e?t.enable(3042):t.disable(3042),blendColor:(t,e)=>t.blendColor(...e),blendEquation:(t,e)=>{let r=typeof e=="number"?[e,e]:e;t.blendEquationSeparate(...r)},blendFunc:(t,e)=>{let r=e?.length===2?[...e,...e]:e;t.blendFuncSeparate(...r)},clearColor:(t,e)=>t.clearColor(...e),clearDepth:(t,e)=>t.clearDepth(e),clearStencil:(t,e)=>t.clearStencil(e),colorMask:(t,e)=>t.colorMask(...e),cull:(t,e)=>e?t.enable(2884):t.disable(2884),cullFace:(t,e)=>t.cullFace(e),depthTest:(t,e)=>e?t.enable(2929):t.disable(2929),depthFunc:(t,e)=>t.depthFunc(e),depthMask:(t,e)=>t.depthMask(e),depthRange:(t,e)=>t.depthRange(...e),dither:(t,e)=>e?t.enable(3024):t.disable(3024),derivativeHint:(t,e)=>{t.hint(35723,e)},frontFace:(t,e)=>t.frontFace(e),mipmapHint:(t,e)=>t.hint(33170,e),lineWidth:(t,e)=>t.lineWidth(e),polygonOffsetFill:(t,e)=>e?t.enable(32823):t.disable(32823),polygonOffset:(t,e)=>t.polygonOffset(...e),sampleCoverage:(t,e)=>t.sampleCoverage(e[0],e[1]||!1),scissorTest:(t,e)=>e?t.enable(3089):t.disable(3089),scissor:(t,e)=>t.scissor(...e),stencilTest:(t,e)=>e?t.enable(2960):t.disable(2960),stencilMask:(t,e)=>{e=G9(e)?e:[e,e];let[r,i]=e;t.stencilMaskSeparate(1028,r),t.stencilMaskSeparate(1029,i)},stencilFunc:(t,e)=>{e=G9(e)&&e.length===3?[...e,...e]:e;let[r,i,n,o,s,c]=e;t.stencilFuncSeparate(1028,r,i,n),t.stencilFuncSeparate(1029,o,s,c)},stencilOp:(t,e)=>{e=G9(e)&&e.length===3?[...e,...e]:e;let[r,i,n,o,s,c]=e;t.stencilOpSeparate(1028,r,i,n),t.stencilOpSeparate(1029,o,s,c)},viewport:(t,e)=>t.viewport(...e)};Nse={blendEquation:(t,e,r)=>t.blendEquationSeparate(Wu(32777,e,r),Wu(34877,e,r)),blendFunc:(t,e,r)=>t.blendFuncSeparate(Wu(32969,e,r),Wu(32968,e,r),Wu(32971,e,r),Wu(32970,e,r)),polygonOffset:(t,e,r)=>t.polygonOffset(Wu(32824,e,r),Wu(10752,e,r)),sampleCoverage:(t,e,r)=>t.sampleCoverage(Wu(32938,e,r),Wu(32939,e,r)),stencilFuncFront:(t,e,r)=>t.stencilFuncSeparate(1028,Wu(2962,e,r),Wu(2967,e,r),Wu(2963,e,r)),stencilFuncBack:(t,e,r)=>t.stencilFuncSeparate(1029,Wu(34816,e,r),Wu(36003,e,r),Wu(36004,e,r)),stencilOpFront:(t,e,r)=>t.stencilOpSeparate(1028,Wu(2964,e,r),Wu(2965,e,r),Wu(2966,e,r)),stencilOpBack:(t,e,r)=>t.stencilOpSeparate(1029,Wu(34817,e,r),Wu(34818,e,r),Wu(34819,e,r))},W9={enable:(t,e)=>t({[e]:!0}),disable:(t,e)=>t({[e]:!1}),pixelStorei:(t,e,r)=>t({[e]:r}),hint:(t,e,r)=>t({[e]:r}),useProgram:(t,e)=>t({[35725]:e}),bindRenderbuffer:(t,e,r)=>t({[36007]:r}),bindTransformFeedback:(t,e,r)=>t({[36389]:r}),bindVertexArray:(t,e)=>t({[34229]:e}),bindFramebuffer:(t,e,r)=>{switch(e){case 36160:return t({[36006]:r,[36010]:r});case 36009:return t({[36006]:r});case 36008:return t({[36010]:r});default:return null}},bindBuffer:(t,e,r)=>{let i={[34962]:[34964],[36662]:[36662],[36663]:[36663],[35051]:[35053],[35052]:[35055]}[e];return i?t({[i]:r}):{valueChanged:!0}},blendColor:(t,e,r,i,n)=>t({[32773]:new Float32Array([e,r,i,n])}),blendEquation:(t,e)=>t({[32777]:e,[34877]:e}),blendEquationSeparate:(t,e,r)=>t({[32777]:e,[34877]:r}),blendFunc:(t,e,r)=>t({[32969]:e,[32968]:r,[32971]:e,[32970]:r}),blendFuncSeparate:(t,e,r,i,n)=>t({[32969]:e,[32968]:r,[32971]:i,[32970]:n}),clearColor:(t,e,r,i,n)=>t({[3106]:new Float32Array([e,r,i,n])}),clearDepth:(t,e)=>t({[2931]:e}),clearStencil:(t,e)=>t({[2961]:e}),colorMask:(t,e,r,i,n)=>t({[3107]:[e,r,i,n]}),cullFace:(t,e)=>t({[2885]:e}),depthFunc:(t,e)=>t({[2932]:e}),depthRange:(t,e,r)=>t({[2928]:new Float32Array([e,r])}),depthMask:(t,e)=>t({[2930]:e}),frontFace:(t,e)=>t({[2886]:e}),lineWidth:(t,e)=>t({[2849]:e}),polygonOffset:(t,e,r)=>t({[32824]:e,[10752]:r}),sampleCoverage:(t,e,r)=>t({[32938]:e,[32939]:r}),scissor:(t,e,r,i,n)=>t({[3088]:new Int32Array([e,r,i,n])}),stencilMask:(t,e)=>t({[2968]:e,[36005]:e}),stencilMaskSeparate:(t,e,r)=>t({[e===1028?2968:36005]:r}),stencilFunc:(t,e,r,i)=>t({[2962]:e,[2967]:r,[2963]:i,[34816]:e,[36003]:r,[36004]:i}),stencilFuncSeparate:(t,e,r,i,n)=>t({[e===1028?2962:34816]:r,[e===1028?2967:36003]:i,[e===1028?2963:36004]:n}),stencilOp:(t,e,r,i)=>t({[2964]:e,[2965]:r,[2966]:i,[34817]:e,[34818]:r,[34819]:i}),stencilOpSeparate:(t,e,r,i,n)=>t({[e===1028?2964:34817]:r,[e===1028?2965:34818]:i,[e===1028?2966:34819]:n}),viewport:(t,e,r,i,n)=>t({[2978]:[e,r,i,n]})},s_=(t,e)=>t.isEnabled(e),q9={[3042]:s_,[2884]:s_,[2929]:s_,[3024]:s_,[32823]:s_,[32926]:s_,[32928]:s_,[3089]:s_,[2960]:s_,[35977]:s_},zse=new Set([34016,36388,36387,35983,35368,34965,35739,35738,3074,34853,34854,34855,34856,34857,34858,34859,34860,34861,34862,34863,34864,34865,34866,34867,34868,35097,32873,35869,32874,34068])});function F0(t,e){if(Lke(e))return;let r={};for(let n in e){let o=Number(n),s=kse[n];s&&(typeof s=="string"?r[s]=!0:s(t,e[n],o))}let i=t.lumaState?.cache;if(i)for(let n in r){let o=Nse[n];o(t,e,i)}}function Kk(t,e=jP){if(typeof e=="number"){let n=e,o=q9[n];return o?o(t,n):t.getParameter(n)}let r=Array.isArray(e)?e:Object.keys(e),i={};for(let n of r){let o=q9[n];i[n]=o?o(t,Number(n)):t.getParameter(Number(n))}return i}function Use(t){F0(t,jP)}function Lke(t){for(let e in t)return!1;return!0}var yS=Nt(()=>{$9()});function jse(t,e){if(t===e)return!0;if(Vse(t)&&Vse(e)&&t.length===e.length){for(let r=0;r{});function Gse(t,e){let r=t[e].bind(t);t[e]=function(n){if(n===void 0||zse.has(n))return r(n);let o=k0.get(t);return n in o.cache||(o.cache[n]=r(n)),o.enable?o.cache[n]:r(n)},Object.defineProperty(t[e],"name",{value:`${e}-from-cache`,configurable:!1})}function Dke(t,e,r){if(!t[e])return;let i=t[e].bind(t);t[e]=function(...o){let s=k0.get(t),{valueChanged:c,oldValue:f}=r(s._updateCache,...o);return c&&i(...o),f},Object.defineProperty(t[e],"name",{value:`${e}-to-cache`,configurable:!1})}function Oke(t){let e=t.useProgram.bind(t);t.useProgram=function(i){let n=k0.get(t);n.program!==i&&(e(i),n.program=i)}}var k0,X9=Nt(()=>{yS();Hse();$9();k0=class{static get(e){return e.lumaState}gl;program=null;stateStack=[];enable=!0;cache=null;log;initialized=!1;constructor(e,r){this.gl=e,this.log=r?.log||(()=>{}),this._updateCache=this._updateCache.bind(this),Object.seal(this)}push(e={}){this.stateStack.push({})}pop(){let e=this.stateStack[this.stateStack.length-1];F0(this.gl,e),this.stateStack.pop()}trackState(e,r){if(this.cache=r?.copyState?Kk(e):Object.assign({},jP),this.initialized)throw new Error("WebGLStateTracker");this.initialized=!0,this.gl.lumaState=this,Oke(e);for(let i in W9){let n=W9[i];Dke(e,i,n)}Gse(e,"getParameter"),Gse(e,"isEnabled")}_updateCache(e){let r=!1,i,n=this.stateStack.length>0?this.stateStack[this.stateStack.length-1]:null;for(let o in e){let s=e[o],c=this.cache[o];jse(s,c)||(r=!0,i=c,n&&!(o in n)&&(n[o]=c),this.cache[o]=s)}return{valueChanged:r,oldValue:i}}}});function Wse(t,e,r){let i="",n=f=>{let g=f.statusMessage;g&&(i||=g)};t.addEventListener("webglcontextcreationerror",n,!1);let o=r.failIfMajorPerformanceCaveat!==!0,s={preserveDrawingBuffer:!0,...r,failIfMajorPerformanceCaveat:!0},c=null;try{c||=t.getContext("webgl2",s),!c&&s.failIfMajorPerformanceCaveat&&(i||="Only software GPU is available. Set `failIfMajorPerformanceCaveat: false` to allow.");let f=!1;if(!c&&o&&(s.failIfMajorPerformanceCaveat=!1,c=t.getContext("webgl2",s),f=!0),c||(c=t.getContext("webgl",{}),c&&(c=null,i||="Your browser only supports WebGL1")),!c)throw i||="Your browser does not support WebGL",new Error(`Failed to create WebGL context: ${i}`);let g=j1(c);g.softwareRenderer=f;let{onContextLost:y,onContextRestored:I}=e;return t.addEventListener("webglcontextlost",F=>y(F),!1),t.addEventListener("webglcontextrestored",F=>I(F),!1),c}finally{t.removeEventListener("webglcontextcreationerror",n,!1)}}var qse=Nt(()=>{Zk()});function N0(t,e,r){return r[e]===void 0&&(r[e]=t.getExtension(e)||null),r[e]}var HP=Nt(()=>{});function $se(t,e){let r=t.getParameter(7936),i=t.getParameter(7937);N0(t,"WEBGL_debug_renderer_info",e);let n=e.WEBGL_debug_renderer_info,o=t.getParameter(n?n.UNMASKED_VENDOR_WEBGL:7936),s=t.getParameter(n?n.UNMASKED_RENDERER_WEBGL:7937),c=o||r,f=s||i,g=t.getParameter(7938),y=Xse(c,f),I=Fke(c,f),F=kke(c,f);return{type:"webgl",gpu:y,gpuType:F,gpuBackend:I,vendor:c,renderer:f,version:g,shadingLanguage:"glsl",shadingLanguageVersion:300}}function Xse(t,e){return/NVIDIA/i.exec(t)||/NVIDIA/i.exec(e)?"nvidia":/INTEL/i.exec(t)||/INTEL/i.exec(e)?"intel":/Apple/i.exec(t)||/Apple/i.exec(e)?"apple":/AMD/i.exec(t)||/AMD/i.exec(e)||/ATI/i.exec(t)||/ATI/i.exec(e)?"amd":/SwiftShader/i.exec(t)||/SwiftShader/i.exec(e)?"software":"unknown"}function Fke(t,e){return/Metal/i.exec(t)||/Metal/i.exec(e)?"metal":/ANGLE/i.exec(t)||/ANGLE/i.exec(e)?"opengl":"unknown"}function kke(t,e){if(/SwiftShader/i.exec(t)||/SwiftShader/i.exec(e))return"cpu";switch(Xse(t,e)){case"apple":return Nke(t,e)?"integrated":"unknown";case"intel":return"integrated";case"software":return"cpu";case"unknown":return"unknown";default:return"discrete"}}function Nke(t,e){return/Apple (M\d|A\d|GPU)/i.test(`${t} ${e}`)}var Zse=Nt(()=>{HP()});function Qk(t){switch(t){case"uint8":return 5121;case"sint8":return 5120;case"unorm8":return 5121;case"snorm8":return 5120;case"uint16":return 5123;case"sint16":return 5122;case"unorm16":return 5123;case"snorm16":return 5122;case"uint32":return 5125;case"sint32":return 5124;case"float16":return 5131;case"float32":return 5126}throw new Error(String(t))}var Z9=Nt(()=>{});function Qse(t){return t in eN}function eW(t,e,r){return Jse(t,e,r,new Set)}function Jse(t,e,r,i){let n=eN[e];if(!n||i.has(e))return!1;i.add(e);let o=(n.features||[]).every(s=>Jse(t,s,r,i));return i.delete(e),o?(n.extensions||[]).every(s=>Boolean(N0(t,s,r))):!1}function eae(t,e,r){let i=e.create,n=tN[e.format];n?.gl===void 0&&(i=!1),n?.x&&(i=i&&Boolean(N0(t,n.x,r))),e.format==="stencil8"&&(i=!1);let o=n?.r===!1?!1:n?.r===void 0||eW(t,n.r,r),s=i&&e.render&&o&&qke(t,e.format,r);return{format:e.format,create:i&&e.create,render:s,filter:i&&e.filter,blend:i&&e.blend,store:i&&e.store}}function qke(t,e,r){let i=tN[e],n=i?.gl;if(n===void 0||i?.x&&!N0(t,i.x,r))return!1;let o=t.getParameter(32873),s=t.getParameter(36006),c=t.createTexture(),f=t.createFramebuffer();if(!c||!f)return!1;let g=Number(0),y=Number(t.getError());for(;y!==g;)y=t.getError();let I=!1;try{if(t.bindTexture(3553,c),t.texStorage2D(3553,1,n,1,1),Number(t.getError())!==g)return!1;t.bindFramebuffer(36160,f),t.framebufferTexture2D(36160,36064,3553,c,0),I=Number(t.checkFramebufferStatus(36160))===Number(36053)&&Number(t.getError())===g}finally{t.bindFramebuffer(36160,s),t.deleteFramebuffer(f),t.bindTexture(3553,o),t.deleteTexture(c)}return I}function rN(t){let e=tN[t],r=Xke(t),i=ld.getInfo(t);return i.compressed&&(e.dataFormat=r),{internalFormat:r,format:e?.dataFormat||$ke(i.channels,i.integer,i.normalized,r),type:i.dataType?Qk(i.dataType):e?.types?.[0]||5121,compressed:i.compressed||!1}}function tae(t){switch(ld.getInfo(t).attachment){case"depth":return 36096;case"stencil":return 36128;case"depth-stencil":return 33306;default:throw new Error(`Not a depth stencil format: ${t}`)}}function $ke(t,e,r,i){if(i===6408||i===6407)return i;switch(t){case"r":return e&&!r?36244:6403;case"rg":return e&&!r?33320:33319;case"rgb":return e&&!r?36248:6407;case"rgba":return e&&!r?36249:6408;case"bgra":throw new Error("bgra pixels not supported by WebGL");default:return 6408}}function Xke(t){let r=tN[t]?.gl;if(r===void 0)throw new Error(`Unsupported texture format ${t}`);return r}var GP,WP,vS,xS,zke,Uke,Vke,jke,Hke,Gke,Yse,Kse,Y9,K9,Q9,J9,Jk,Wke,eN,tN,bS=Nt(()=>{Eo();HP();Z9();GP="WEBGL_compressed_texture_s3tc",WP="WEBGL_compressed_texture_s3tc_srgb",vS="EXT_texture_compression_rgtc",xS="EXT_texture_compression_bptc",zke="WEBGL_compressed_texture_etc",Uke="WEBGL_compressed_texture_astc",Vke="WEBGL_compressed_texture_etc1",jke="WEBGL_compressed_texture_pvrtc",Hke="WEBGL_compressed_texture_atc",Gke="EXT_texture_norm16",Yse="EXT_render_snorm",Kse="EXT_color_buffer_float",Y9="snorm8-renderable-webgl",K9="norm16-renderable-webgl",Q9="snorm16-renderable-webgl",J9="float16-renderable-webgl",Jk="float32-renderable-webgl",Wke="rgb9e5ufloat-renderable-webgl",eN={"float32-renderable-webgl":{extensions:[Kse]},"float16-renderable-webgl":{extensions:["EXT_color_buffer_half_float"]},"rgb9e5ufloat-renderable-webgl":{extensions:["WEBGL_render_shared_exponent"]},"snorm8-renderable-webgl":{extensions:[Yse]},"norm16-webgl":{extensions:[Gke]},"norm16-renderable-webgl":{features:["norm16-webgl"]},"snorm16-renderable-webgl":{features:["norm16-webgl"],extensions:[Yse]},"float32-filterable":{extensions:["OES_texture_float_linear"]},"float16-filterable-webgl":{extensions:["OES_texture_half_float_linear"]},"texture-filterable-anisotropic-webgl":{extensions:["EXT_texture_filter_anisotropic"]},"texture-blend-float-webgl":{extensions:["EXT_float_blend"]},"texture-compression-bc":{extensions:[GP,WP,vS,xS]},"texture-compression-bc5-webgl":{extensions:[vS]},"texture-compression-bc7-webgl":{extensions:[xS]},"texture-compression-etc2":{extensions:[zke]},"texture-compression-astc":{extensions:[Uke]},"texture-compression-etc1-webgl":{extensions:[Vke]},"texture-compression-pvrtc-webgl":{extensions:[jke]},"texture-compression-atc-webgl":{extensions:[Hke]}};tN={r8unorm:{gl:33321,rb:!0},r8snorm:{gl:36756,r:Y9},r8uint:{gl:33330,rb:!0},r8sint:{gl:33329,rb:!0},rg8unorm:{gl:33323,rb:!0},rg8snorm:{gl:36757,r:Y9},rg8uint:{gl:33336,rb:!0},rg8sint:{gl:33335,rb:!0},r16uint:{gl:33332,rb:!0},r16sint:{gl:33331,rb:!0},r16float:{gl:33325,rb:!0,r:J9},r16unorm:{gl:33322,rb:!0,r:K9},r16snorm:{gl:36760,r:Q9},"rgba4unorm-webgl":{gl:32854,rb:!0},"rgb565unorm-webgl":{gl:36194,rb:!0},"rgb5a1unorm-webgl":{gl:32855,rb:!0},"rgb8unorm-webgl":{gl:32849},"rgb8snorm-webgl":{gl:36758},rgba8unorm:{gl:32856},"rgba8unorm-srgb":{gl:35907},rgba8snorm:{gl:36759,r:Y9},rgba8uint:{gl:36220},rgba8sint:{gl:36238},bgra8unorm:{},"bgra8unorm-srgb":{},rg16uint:{gl:33338},rg16sint:{gl:33337},rg16float:{gl:33327,rb:!0,r:J9},rg16unorm:{gl:33324,r:K9},rg16snorm:{gl:36761,r:Q9},r32uint:{gl:33334,rb:!0},r32sint:{gl:33333,rb:!0},r32float:{gl:33326,r:Jk},rgb9e5ufloat:{gl:35901,r:Wke},rg11b10ufloat:{gl:35898,rb:!0},rgb10a2unorm:{gl:32857,rb:!0},rgb10a2uint:{gl:36975,rb:!0},"rgb16unorm-webgl":{gl:32852,r:!1},"rgb16snorm-webgl":{gl:36762,r:!1},rg32uint:{gl:33340,rb:!0},rg32sint:{gl:33339,rb:!0},rg32float:{gl:33328,rb:!0,r:Jk},rgba16uint:{gl:36214,rb:!0},rgba16sint:{gl:36232,rb:!0},rgba16float:{gl:34842,r:J9},rgba16unorm:{gl:32859,rb:!0,r:K9},rgba16snorm:{gl:36763,r:Q9},"rgb32float-webgl":{gl:34837,x:Kse,r:Jk,dataFormat:6407,types:[5126]},rgba32uint:{gl:36208,rb:!0},rgba32sint:{gl:36226,rb:!0},rgba32float:{gl:34836,rb:!0,r:Jk},stencil8:{gl:36168,rb:!0},depth16unorm:{gl:33189,dataFormat:6402,types:[5123],rb:!0},depth24plus:{gl:33190,dataFormat:6402,types:[5125]},depth32float:{gl:36012,dataFormat:6402,types:[5126],rb:!0},"depth24plus-stencil8":{gl:35056,rb:!0,depthTexture:!0,dataFormat:34041,types:[34042]},"depth32float-stencil8":{gl:36013,dataFormat:34041,types:[36269],rb:!0},"bc1-rgb-unorm-webgl":{gl:33776,x:GP},"bc1-rgb-unorm-srgb-webgl":{gl:35916,x:WP},"bc1-rgba-unorm":{gl:33777,x:GP},"bc1-rgba-unorm-srgb":{gl:35916,x:WP},"bc2-rgba-unorm":{gl:33778,x:GP},"bc2-rgba-unorm-srgb":{gl:35918,x:WP},"bc3-rgba-unorm":{gl:33779,x:GP},"bc3-rgba-unorm-srgb":{gl:35919,x:WP},"bc4-r-unorm":{gl:36283,x:vS},"bc4-r-snorm":{gl:36284,x:vS},"bc5-rg-unorm":{gl:36285,x:vS},"bc5-rg-snorm":{gl:36286,x:vS},"bc6h-rgb-ufloat":{gl:36495,x:xS},"bc6h-rgb-float":{gl:36494,x:xS},"bc7-rgba-unorm":{gl:36492,x:xS},"bc7-rgba-unorm-srgb":{gl:36493,x:xS},"etc2-rgb8unorm":{gl:37492},"etc2-rgb8unorm-srgb":{gl:37494},"etc2-rgb8a1unorm":{gl:37496},"etc2-rgb8a1unorm-srgb":{gl:37497},"etc2-rgba8unorm":{gl:37493},"etc2-rgba8unorm-srgb":{gl:37495},"eac-r11unorm":{gl:37488},"eac-r11snorm":{gl:37489},"eac-rg11unorm":{gl:37490},"eac-rg11snorm":{gl:37491},"astc-4x4-unorm":{gl:37808},"astc-4x4-unorm-srgb":{gl:37840},"astc-5x4-unorm":{gl:37809},"astc-5x4-unorm-srgb":{gl:37841},"astc-5x5-unorm":{gl:37810},"astc-5x5-unorm-srgb":{gl:37842},"astc-6x5-unorm":{gl:37811},"astc-6x5-unorm-srgb":{gl:37843},"astc-6x6-unorm":{gl:37812},"astc-6x6-unorm-srgb":{gl:37844},"astc-8x5-unorm":{gl:37813},"astc-8x5-unorm-srgb":{gl:37845},"astc-8x6-unorm":{gl:37814},"astc-8x6-unorm-srgb":{gl:37846},"astc-8x8-unorm":{gl:37815},"astc-8x8-unorm-srgb":{gl:37847},"astc-10x5-unorm":{gl:37816},"astc-10x5-unorm-srgb":{gl:37848},"astc-10x6-unorm":{gl:37817},"astc-10x6-unorm-srgb":{gl:37849},"astc-10x8-unorm":{gl:37818},"astc-10x8-unorm-srgb":{gl:37850},"astc-10x10-unorm":{gl:37819},"astc-10x10-unorm-srgb":{gl:37851},"astc-12x10-unorm":{gl:37820},"astc-12x10-unorm-srgb":{gl:37852},"astc-12x12-unorm":{gl:37821},"astc-12x12-unorm-srgb":{gl:37853},"pvrtc-rgb4unorm-webgl":{gl:35840},"pvrtc-rgba4unorm-webgl":{gl:35842},"pvrtc-rgb2unorm-webgl":{gl:35841},"pvrtc-rgba2unorm-webgl":{gl:35843},"etc1-rbg-unorm-webgl":{gl:36196},"atc-rgb-unorm-webgl":{gl:35986},"atc-rgba-unorm-webgl":{gl:35986},"atc-rgbai-unorm-webgl":{gl:34798}}});var rae,iN,iae=Nt(()=>{Eo();HP();bS();rae={"depth-clip-control":"EXT_depth_clamp","timestamp-query":"EXT_disjoint_timer_query_webgl2","compilation-status-async-webgl":"KHR_parallel_shader_compile","polygon-mode-webgl":"WEBGL_polygon_mode","provoking-vertex-webgl":"WEBGL_provoking_vertex","shader-clip-cull-distance-webgl":"WEBGL_clip_cull_distance","shader-noperspective-interpolation-webgl":"NV_shader_noperspective_interpolation","shader-conservative-depth-webgl":"EXT_conservative_depth"},iN=class extends QM{gl;extensions;testedFeatures=new Set;constructor(e,r,i){super([],i),this.gl=e,this.extensions=r,N0(e,"EXT_color_buffer_float",r)}*[Symbol.iterator](){let e=this.getFeatures();for(let r of e)this.has(r)&&(yield r);return[]}has(e){return this.disabledFeatures?.[e]?!1:(this.testedFeatures.has(e)||(this.testedFeatures.add(e),Qse(e)&&eW(this.gl,e,this.extensions)&&this.features.add(e),this.getWebGLFeature(e)&&this.features.add(e)),this.features.has(e))}initializeFeatures(){let e=this.getFeatures().filter(r=>r!=="polygon-mode-webgl");for(let r of e)this.has(r)}getFeatures(){return[...Object.keys(rae),...Object.keys(eN)]}getWebGLFeature(e){let r=rae[e];return Boolean(typeof r=="string"?N0(this.gl,r,this.extensions):r)}}});var nN,nae=Nt(()=>{Eo();nN=class extends KM{get maxTextureDimension1D(){return 0}get maxTextureDimension2D(){return this.getParameter(3379)}get maxTextureDimension3D(){return this.getParameter(32883)}get maxTextureArrayLayers(){return this.getParameter(35071)}get maxBindGroups(){return 0}get maxDynamicUniformBuffersPerPipelineLayout(){return 0}get maxDynamicStorageBuffersPerPipelineLayout(){return 0}get maxSampledTexturesPerShaderStage(){return this.getParameter(35660)}get maxSamplersPerShaderStage(){return this.getParameter(35661)}get maxStorageBuffersPerShaderStage(){return 0}get maxStorageTexturesPerShaderStage(){return 0}get maxUniformBuffersPerShaderStage(){return this.getParameter(35375)}get maxUniformBufferBindingSize(){return this.getParameter(35376)}get maxStorageBufferBindingSize(){return 0}get minUniformBufferOffsetAlignment(){return this.getParameter(35380)}get minStorageBufferOffsetAlignment(){return 0}get maxVertexBuffers(){return 16}get maxVertexAttributes(){return this.getParameter(34921)}get maxVertexBufferArrayStride(){return 2048}get maxInterStageShaderVariables(){return this.getParameter(35659)}get maxComputeWorkgroupStorageSize(){return 0}get maxComputeInvocationsPerWorkgroup(){return 0}get maxComputeWorkgroupSizeX(){return 0}get maxComputeWorkgroupSizeY(){return 0}get maxComputeWorkgroupSizeZ(){return 0}get maxComputeWorkgroupsPerDimension(){return 0}gl;limits={};constructor(e){super(),this.gl=e}getParameter(e){return this.limits[e]===void 0&&(this.limits[e]=this.gl.getParameter(e)),this.limits[e]||0}}});function Zke(t){return t<34069?t+34069:t}function Yke(t){switch(t){case 36053:return"success";case 36054:return"Mismatched attachments";case 36055:return"No attachments";case 36057:return"Height/width mismatch";case 36061:return"Unsupported or split attachments";case 36182:return"Samples mismatch";default:return`${t}`}}var a_,oN=Nt(()=>{Eo();bS();a_=class extends KA{device;gl;handle;colorAttachments=[];depthStencilAttachment=null;constructor(e,r){super(e,r);let i=r.handle===null;this.device=e,this.gl=e.gl,this.handle=this.props.handle||i?this.props.handle:this.gl.createFramebuffer(),i||(e._setWebGLDebugMetadata(this.handle,this,{spector:this.props}),r.handle||(this.autoCreateAttachmentTextures(),this.updateAttachments()))}destroy(){super.destroy(),!this.destroyed&&this.handle!==null&&!this.props.handle&&this.gl.deleteFramebuffer(this.handle)}updateAttachments(){let e=this.gl.bindFramebuffer(36160,this.handle);for(let r=0;r{Eo();oN();sN=class extends GT{device;handle=null;_framebuffer=null;get[Symbol.toStringTag](){return"WebGLCanvasContext"}constructor(e,r){super(r),this.device=e,this._setAutoCreatedCanvasId(`${this.device.id}-canvas`),this._configureDevice()}_configureDevice(){(this.drawingBufferWidth!==this._framebuffer?.width||this.drawingBufferHeight!==this._framebuffer?.height)&&this._framebuffer?.resize([this.drawingBufferWidth,this.drawingBufferHeight])}_getCurrentFramebuffer(){return this._framebuffer||=new a_(this.device,{id:"canvas-context-framebuffer",handle:null,width:this.drawingBufferWidth,height:this.drawingBufferHeight}),this._framebuffer}}});var aN,sae=Nt(()=>{Eo();aN=class extends tP{device;handle=null;context2d;get[Symbol.toStringTag](){return"WebGLPresentationContext"}constructor(e,r={}){super(r),this.device=e;let i=`${this[Symbol.toStringTag]}(${this.id})`;if(!this.device.getDefaultCanvasContext().offscreenCanvas)throw new Error(`${i}: WebGL PresentationContext requires the default CanvasContext canvas to be an OffscreenCanvas`);let o=this.canvas.getContext("2d");if(!o)throw new Error(`${i}: Failed to create 2d presentation context`);this.context2d=o,this._setAutoCreatedCanvasId(`${this.device.id}-presentation-canvas`),this._configureDevice(),this._startObservers()}present(){this._resizeDrawingBufferIfNeeded(),this.device.submit();let e=this.device.getDefaultCanvasContext(),[r,i]=e.getDrawingBufferSize();if(!(this.drawingBufferWidth===0||this.drawingBufferHeight===0||r===0||i===0||e.canvas.width===0||e.canvas.height===0)){if(r!==this.drawingBufferWidth||i!==this.drawingBufferHeight||e.canvas.width!==this.drawingBufferWidth||e.canvas.height!==this.drawingBufferHeight)throw new Error(`${this[Symbol.toStringTag]}(${this.id}): Default canvas context size ${r}x${i} does not match presentation size ${this.drawingBufferWidth}x${this.drawingBufferHeight}`);this.context2d.clearRect(0,0,this.drawingBufferWidth,this.drawingBufferHeight),this.context2d.drawImage(e.canvas,0,0)}}_configureDevice(){}_getCurrentFramebuffer(e){let r=this.device.getDefaultCanvasContext();return r.setDrawingBufferSize(this.drawingBufferWidth,this.drawingBufferHeight),r.getCurrentFramebuffer(e)}}});function aae(t="id"){tW[t]=tW[t]||1;let e=tW[t]++;return`${t}-${e}`}var tW,lae=Nt(()=>{tW={}});function Kke(t){return t&lo.INDEX?34963:t&lo.VERTEX?34962:t&lo.UNIFORM?35345:34962}function Qke(t){return t&lo.INDEX||t&lo.VERTEX?35044:t&lo.UNIFORM?35048:35044}var z0,lN=Nt(()=>{Eo();z0=class extends lo{device;gl;handle;glTarget;glUsage;glIndexType=5123;byteLength=0;bytesUsed=0;constructor(e,r={}){super(e,r),this.device=e,this.gl=this.device.gl;let i=typeof r=="object"?r.handle:void 0;this.handle=i||this.gl.createBuffer(),e._setWebGLDebugMetadata(this.handle,this,{spector:{...this.props,data:typeof this.props.data}}),this.glTarget=Kke(this.props.usage),this.glUsage=Qke(this.props.usage),this.glIndexType=this.props.indexType==="uint32"?5125:5123,r.data?this._initWithData(r.data,r.byteOffset,r.byteLength):this._initWithByteLength(r.byteLength||0)}destroy(){!this.destroyed&&this.handle&&(this.removeStats(),this.props.handle?this.trackDeallocatedReferencedMemory("Buffer"):(this.trackDeallocatedMemory(),this.gl.deleteBuffer(this.handle)),this.destroyed=!0,this.handle=null)}_initWithData(e,r=0,i=e.byteLength+r){let n=this.glTarget;this.gl.bindBuffer(n,this.handle),this.gl.bufferData(n,i,this.glUsage),this.gl.bufferSubData(n,r,e),this.gl.bindBuffer(n,null),this.bytesUsed=i,this.byteLength=i,this._setDebugData(e,r,i),this.props.handle?this.trackReferencedMemory(i,"Buffer"):this.trackAllocatedMemory(i)}_initWithByteLength(e){let r=e;e===0&&(r=new Float32Array(0));let i=this.glTarget;return this.gl.bindBuffer(i,this.handle),this.gl.bufferData(i,r,this.glUsage),this.gl.bindBuffer(i,null),this.bytesUsed=e,this.byteLength=e,this._setDebugData(null,0,e),this.props.handle?this.trackReferencedMemory(e,"Buffer"):this.trackAllocatedMemory(e),this}write(e,r=0){let i=ArrayBuffer.isView(e)?e:new Uint8Array(e),n=0,o=void 0,s=36663;this.gl.bindBuffer(s,this.handle),n!==0||o!==void 0?this.gl.bufferSubData(s,r,i,n,o):this.gl.bufferSubData(s,r,i),this.gl.bindBuffer(s,null),this._setDebugData(e,r,e.byteLength)}async mapAndWriteAsync(e,r=0,i=this.byteLength-r){let n=new ArrayBuffer(i);await e(n,"copied"),this.write(n,r)}async readAsync(e=0,r){return this.readSyncWebGL(e,r)}async mapAndReadAsync(e,r=0,i){let n=await this.readAsync(r,i);return await e(n.buffer,"copied")}readSyncWebGL(e=0,r){r=r??this.byteLength-e;let i=new Uint8Array(r),n=0;return this.gl.bindBuffer(36662,this.handle),this.gl.getBufferSubData(36662,e,i,n,r),this.gl.bindBuffer(36662,null),this._setDebugData(i,e,r),i}}});function cae(t){let e=t.split(/\r?\n/),r=[];for(let i of e){if(i.length<=1)continue;let n=i.trim(),o=i.split(":"),s=o[0]?.trim();if(o.length===2){let[k,U]=o;if(!k||!U){r.push({message:n,type:cN(s||"info"),lineNum:0,linePos:0});continue}r.push({message:U.trim(),type:cN(k),lineNum:0,linePos:0});continue}let[c,f,g,...y]=o;if(!c||!f||!g){r.push({message:o.slice(1).join(":").trim()||n,type:cN(s||"info"),lineNum:0,linePos:0});continue}let I=parseInt(g,10);Number.isNaN(I)&&(I=0);let F=parseInt(f,10);Number.isNaN(F)&&(F=0),r.push({message:y.join(":").trim(),type:cN(c),lineNum:I,linePos:F})}return r}function cN(t){let e=["warning","error","info"],r=t.toLowerCase();return e.includes(r)?r:"info"}var uae=Nt(()=>{});var uN,hae=Nt(()=>{Eo();uae();uN=class extends Qv{device;handle;constructor(e,r){switch(super(e,r),this.device=e,this.props.stage){case"vertex":this.handle=this.props.handle||this.device.gl.createShader(35633);break;case"fragment":this.handle=this.props.handle||this.device.gl.createShader(35632);break;default:throw new Error(this.props.stage)}e._setWebGLDebugMetadata(this.handle,this,{spector:this.props});let i=this._compile(this.source);i&&typeof i.catch=="function"&&i.catch(()=>{this.compilationStatus="error"})}destroy(){this.handle&&(this.removeStats(),this.device.gl.deleteShader(this.handle),this.destroyed=!0,this.handle.destroyed=!0)}get asyncCompilationStatus(){return this._waitForCompilationComplete().then(()=>(this._getCompilationStatus(),this.compilationStatus))}async getCompilationInfo(){return await this._waitForCompilationComplete(),this.getCompilationInfoSync()}getCompilationInfoSync(){let e=this.device.gl.getShaderInfoLog(this.handle);return e?cae(e):[]}getTranslatedSource(){return this.device.getExtension("WEBGL_debug_shaders").WEBGL_debug_shaders?.getTranslatedShaderSource(this.handle)||null}_compile(e){e=e.startsWith("#version ")?e:`#version 300 es +${e}`;let{gl:r}=this.device;if(r.shaderSource(this.handle,e),r.compileShader(this.handle),!this.device.props.debug){this.compilationStatus="pending";return}if(!this.device.features.has("compilation-status-async-webgl")){if(this._getCompilationStatus(),this.debugShader(),this.compilationStatus==="error")throw new Error(`GLSL compilation errors in ${this.props.stage} shader ${this.props.id}`);return}return Dr.once(1,"Shader compilation is asynchronous")(),this._waitForCompilationComplete().then(()=>{Dr.info(2,`Shader ${this.id} - async compilation complete: ${this.compilationStatus}`)(),this._getCompilationStatus(),this.debugShader()})}async _waitForCompilationComplete(){let e=async n=>await new Promise(o=>setTimeout(o,n));if(!this.device.features.has("compilation-status-async-webgl")){await e(10);return}let{gl:i}=this.device;for(;;){if(i.getShaderParameter(this.handle,37297))return;await e(10)}}_getCompilationStatus(){this.compilationStatus=this.device.gl.getShaderParameter(this.handle,35713)?"success":"error"}}});function dae(t,e,r,i){if(rNe(e))return i(t);let n=t;n.pushState();try{return Jke(t,e),F0(n.gl,r),i(t)}finally{n.popState()}}function Jke(t,e){let r=t,{gl:i}=r;if(e.cullMode)switch(e.cullMode){case"none":i.disable(2884);break;case"front":i.enable(2884),i.cullFace(1028);break;case"back":i.enable(2884),i.cullFace(1029);break}if(e.frontFace&&i.frontFace(H1("frontFace",e.frontFace,{ccw:2305,cw:2304})),e.unclippedDepth&&t.features.has("depth-clip-control")&&i.enable(34383),e.depthBias!==void 0&&(i.enable(32823),i.polygonOffset(e.depthBias,e.depthBiasSlopeScale||0)),e.provokingVertex&&t.features.has("provoking-vertex-webgl")){let o=r.getExtension("WEBGL_provoking_vertex").WEBGL_provoking_vertex,s=H1("provokingVertex",e.provokingVertex,{first:36429,last:36430});o?.provokingVertexWEBGL(s)}if((e.polygonMode||e.polygonOffsetLine)&&t.features.has("polygon-mode-webgl")){if(e.polygonMode){let o=r.getExtension("WEBGL_polygon_mode").WEBGL_polygon_mode,s=H1("polygonMode",e.polygonMode,{fill:6914,line:6913});o?.polygonModeWEBGL(1028,s),o?.polygonModeWEBGL(1029,s)}e.polygonOffsetLine&&i.enable(10754)}if(t.features.has("shader-clip-cull-distance-webgl")&&(e.clipDistance0&&i.enable(12288),e.clipDistance1&&i.enable(12289),e.clipDistance2&&i.enable(12290),e.clipDistance3&&i.enable(12291),e.clipDistance4&&i.enable(12292),e.clipDistance5&&i.enable(12293),e.clipDistance6&&i.enable(12294),e.clipDistance7&&i.enable(12295)),e.depthWriteEnabled!==void 0&&i.depthMask(tNe("depthWriteEnabled",e.depthWriteEnabled)),e.depthCompare&&(e.depthCompare!=="always"?i.enable(2929):i.disable(2929),i.depthFunc(fN("depthCompare",e.depthCompare))),e.clearDepth!==void 0&&i.clearDepth(e.clearDepth),e.stencilWriteMask){let n=e.stencilWriteMask;i.stencilMaskSeparate(1028,n),i.stencilMaskSeparate(1029,n)}if(e.stencilReadMask&&Dr.warn("stencilReadMask not supported under WebGL"),e.stencilCompare){let n=e.stencilReadMask||4294967295,o=fN("depthCompare",e.stencilCompare);e.stencilCompare!=="always"?i.enable(2960):i.disable(2960),i.stencilFuncSeparate(1028,o,0,n),i.stencilFuncSeparate(1029,o,0,n)}if(e.stencilPassOperation&&e.stencilFailOperation&&e.stencilDepthFailOperation){let n=rW("stencilPassOperation",e.stencilPassOperation),o=rW("stencilFailOperation",e.stencilFailOperation),s=rW("stencilDepthFailOperation",e.stencilDepthFailOperation);i.stencilOpSeparate(1028,o,s,n),i.stencilOpSeparate(1029,o,s,n)}switch(e.blend){case!0:i.enable(3042);break;case!1:i.disable(3042);break;default:}if(e.blendColorOperation||e.blendAlphaOperation){let n=fae("blendColorOperation",e.blendColorOperation||"add"),o=fae("blendAlphaOperation",e.blendAlphaOperation||"add");i.blendEquationSeparate(n,o);let s=hN("blendColorSrcFactor",e.blendColorSrcFactor||"one"),c=hN("blendColorDstFactor",e.blendColorDstFactor||"zero"),f=hN("blendAlphaSrcFactor",e.blendAlphaSrcFactor||"one"),g=hN("blendAlphaDstFactor",e.blendAlphaDstFactor||"zero");i.blendFuncSeparate(s,c,f,g)}}function fN(t,e){return H1(t,e,{never:512,less:513,equal:514,"less-equal":515,greater:516,"not-equal":517,"greater-equal":518,always:519})}function rW(t,e){return H1(t,e,{keep:7680,zero:0,replace:7681,invert:5386,"increment-clamp":7682,"decrement-clamp":7683,"increment-wrap":34055,"decrement-wrap":34056})}function fae(t,e){return H1(t,e,{add:32774,subtract:32778,"reverse-subtract":32779,min:32775,max:32776})}function hN(t,e,r="color"){return H1(t,e,{one:1,zero:0,src:768,"one-minus-src":769,dst:774,"one-minus-dst":775,"src-alpha":770,"one-minus-src-alpha":771,"dst-alpha":772,"one-minus-dst-alpha":773,"src-alpha-saturated":776,constant:r==="color"?32769:32771,"one-minus-constant":r==="color"?32770:32772,src1:768,"one-minus-src1":769,"src1-alpha":770,"one-minus-src1-alpha":771})}function eNe(t,e){return`Illegal parameter ${e} for ${t}`}function H1(t,e,r){if(!(e in r))throw new Error(eNe(t,e));return r[e]}function tNe(t,e){return e}function rNe(t){let e=!0;for(let r in t){e=!1;break}return e}var iW=Nt(()=>{Eo();yS()});function dN(t){let e={};return t.addressModeU&&(e[10242]=nW(t.addressModeU)),t.addressModeV&&(e[10243]=nW(t.addressModeV)),t.addressModeW&&(e[32882]=nW(t.addressModeW)),t.magFilter&&(e[10240]=oW(t.magFilter)),(t.minFilter||t.mipmapFilter)&&(e[10241]=iNe(t.minFilter||"linear",t.mipmapFilter)),t.lodMinClamp!==void 0&&(e[33082]=t.lodMinClamp),t.lodMaxClamp!==void 0&&(e[33083]=t.lodMaxClamp),t.type==="comparison-sampler"&&(e[34892]=34894),t.compare&&(e[34893]=fN("compare",t.compare)),t.maxAnisotropy&&(e[34046]=t.maxAnisotropy),e}function nW(t){switch(t){case"clamp-to-edge":return 33071;case"repeat":return 10497;case"mirror-repeat":return 33648}}function oW(t){switch(t){case"nearest":return 9728;case"linear":return 9729}}function iNe(t,e="none"){if(!e)return oW(t);switch(e){case"none":return oW(t);case"nearest":switch(t){case"nearest":return 9984;case"linear":return 9985}break;case"linear":switch(t){case"nearest":return 9986;case"linear":return 9987}}}var sW=Nt(()=>{iW()});var pN,pae=Nt(()=>{Eo();sW();pN=class extends Dd{device;handle;parameters;constructor(e,r){super(e,r),this.device=e,this.parameters=dN(r),this.handle=r.handle||this.device.gl.createSampler(),this._setSamplerParameters(this.parameters)}destroy(){this.handle&&(this.device.gl.deleteSampler(this.handle),this.handle=void 0)}toString(){return`Sampler(${this.id},${JSON.stringify(this.props)})`}_setSamplerParameters(e){for(let[r,i]of Object.entries(e)){let n=Number(r);switch(n){case 33082:case 33083:this.device.gl.samplerParameterf(this.handle,n,i);break;default:this.device.gl.samplerParameteri(this.handle,n,i);break}}}}});function l_(t,e,r){if(nNe(e))return r(t);let{nocatch:i=!0}=e,n=k0.get(t);n.push(),F0(t,e);let o;if(i)o=r(t),n.pop();else try{o=r(t)}finally{n.pop()}return o}function nNe(t){for(let e in t)return!1;return!0}var mN=Nt(()=>{yS();X9()});var c_,aW=Nt(()=>{Eo();c_=class extends Dg{device;gl;handle;texture;constructor(e,r){super(e,{...oo.defaultProps,...r}),this.device=e,this.gl=this.device.gl,this.handle=null,this.texture=r.texture}}});function gN(t){return oNe[t]}var oNe,lW=Nt(()=>{oNe={[5124]:"sint32",[5125]:"uint32",[5122]:"sint16",[5123]:"uint16",[5120]:"sint8",[5121]:"uint8",[5126]:"float32",[5131]:"float16",[33635]:"uint16",[32819]:"uint16",[32820]:"uint16",[33640]:"uint32",[35899]:"uint32",[35902]:"uint32",[34042]:"uint32",[36269]:"uint32"}});function sNe(t,e=0){return e?new t.constructor(t.buffer,t.byteOffset+e,(t.byteLength-e)/t.BYTES_PER_ELEMENT):t}function aNe(t,e){if(e%t.BYTES_PER_ELEMENT!==0)throw new Error(`Texture byteOffset ${e} must align to typed array element size ${t.BYTES_PER_ELEMENT}`);return e/t.BYTES_PER_ELEMENT}function lNe(t){switch(t){case"1d":break;case"2d":return 3553;case"3d":return 32879;case"cube":return 34067;case"2d-array":return 35866;case"cube-array":break}throw new Error(t)}function AN(t,e,r){return e==="cube"?34069+r:t}var u_,_N=Nt(()=>{Eo();bS();sW();mN();aW();lW();u_=class extends oo{device;gl;handle;sampler=void 0;view;glTarget;glFormat;glType;glInternalFormat;compressed;_textureUnit=0;_framebuffer=null;_framebufferAttachmentKey=null;constructor(e,r){super(e,r,{byteAlignment:1}),this.device=e,this.gl=this.device.gl;let i=rN(this.props.format);this.glTarget=lNe(this.props.dimension),this.glInternalFormat=i.internalFormat,this.glFormat=i.format,this.glType=i.type,this.compressed=i.compressed,this.handle=this.props.handle||this.gl.createTexture(),this.device._setWebGLDebugMetadata(this.handle,this,{spector:this.props}),this.gl.bindTexture(this.glTarget,this.handle);let{dimension:n,width:o,height:s,depth:c,mipLevels:f,glTarget:g,glInternalFormat:y}=this;if(!this.compressed)switch(n){case"2d":case"cube":this.gl.texStorage2D(g,f,y,o,s);break;case"2d-array":case"3d":this.gl.texStorage3D(g,f,y,o,s,c);break;default:throw new Error(n)}this.gl.bindTexture(this.glTarget,null),this._initializeData(r.data),this.props.handle?this.trackReferencedMemory(this.getAllocatedByteLength(),"Texture"):this.trackAllocatedMemory(this.getAllocatedByteLength(),"Texture"),this.setSampler(this.props.sampler),this.view=new c_(this.device,{...this.props,texture:this}),Object.seal(this)}destroy(){this.handle&&(this._framebuffer?.destroy(),this._framebuffer=null,this._framebufferAttachmentKey=null,this.removeStats(),this.props.handle?this.trackDeallocatedReferencedMemory("Texture"):(this.gl.deleteTexture(this.handle),this.trackDeallocatedMemory("Texture")),this.destroyed=!0)}createView(e){return new c_(this.device,{...e,texture:this})}setSampler(e={}){super.setSampler(e);let r=dN(this.sampler.props);this._setSamplerParameters(r)}copyExternalImage(e){let r=this._normalizeCopyExternalImageOptions(e);if(r.sourceX||r.sourceY)throw new Error("WebGL does not support sourceX/sourceY)");let{glFormat:i,glType:n}=this,{image:o,depth:s,mipLevel:c,x:f,y:g,z:y,width:I,height:F}=r,k=AN(this.glTarget,this.dimension,y),U=r.flipY?{[37440]:!0}:{};return this.gl.bindTexture(this.glTarget,this.handle),l_(this.gl,U,()=>{switch(this.dimension){case"2d":case"cube":this.gl.texSubImage2D(k,c,f,g,I,F,i,n,o);break;case"2d-array":case"3d":this.gl.texSubImage3D(k,c,f,g,y,I,F,s,i,n,o);break;default:}}),this.gl.bindTexture(this.glTarget,null),{width:r.width,height:r.height}}copyImageData(e){super.copyImageData(e)}readBuffer(e={},r){if(!r)throw new Error(`${this} readBuffer requires a destination buffer`);let i=this._getSupportedColorReadOptions(e),n=e.byteOffset??0,o=this.computeMemoryLayout(i);if(r.byteLength{this.gl.readPixels(i.x,i.y,i.width,i.height,this.glFormat,this.glType,n+c)})}finally{this.gl.bindBuffer(35051,null)}return r}async readDataAsync(e={}){throw new Error(`${this} readDataAsync is deprecated; use readBuffer() with an explicit destination buffer or DynamicTexture.readAsync()`)}writeBuffer(e,r={}){let i=this._normalizeTextureWriteOptions(r),{width:n,height:o,depthOrArrayLayers:s,mipLevel:c,byteOffset:f,x:g,y,z:I}=i,{glFormat:F,glType:k,compressed:U}=this,K=AN(this.glTarget,this.dimension,I);if(U)throw new Error("writeBuffer for compressed textures is not implemented in WebGL");let{bytesPerPixel:ee}=this.device.getTextureFormatInfo(this.format),he=ee?i.bytesPerRow/ee:void 0,xe={[3317]:this.byteAlignment,...he!==void 0?{[3314]:he}:{},[32878]:i.rowsPerImage};this.gl.bindTexture(this.glTarget,this.handle),this.gl.bindBuffer(35052,e.handle),l_(this.gl,xe,()=>{switch(this.dimension){case"2d":case"cube":this.gl.texSubImage2D(K,c,g,y,n,o,F,k,f);break;case"2d-array":case"3d":this.gl.texSubImage3D(K,c,g,y,I,n,o,s,F,k,f);break;default:}}),this.gl.bindBuffer(35052,null),this.gl.bindTexture(this.glTarget,null)}writeData(e,r={}){let i=this._normalizeTextureWriteOptions(r),n=ArrayBuffer.isView(e)?e:new Uint8Array(e),{width:o,height:s,depthOrArrayLayers:c,mipLevel:f,x:g,y,z:I,byteOffset:F}=i,{glFormat:k,glType:U,compressed:K}=this,ee=AN(this.glTarget,this.dimension,I),he;if(!K){let{bytesPerPixel:Ge}=this.device.getTextureFormatInfo(this.format);Ge&&(he=i.bytesPerRow/Ge)}let xe=this.compressed?{}:{[3317]:this.byteAlignment,...he!==void 0?{[3314]:he}:{},[32878]:i.rowsPerImage},me=aNe(n,F),Se=K?sNe(n,F):n,Oe=this._getMipLevelSize(f),ne=g===0&&y===0&&I===0&&o===Oe.width&&s===Oe.height&&c===Oe.depthOrArrayLayers;this.gl.bindTexture(this.glTarget,this.handle),this.gl.bindBuffer(35052,null),l_(this.gl,xe,()=>{switch(this.dimension){case"2d":case"cube":K?ne?this.gl.compressedTexImage2D(ee,f,k,o,s,0,Se):this.gl.compressedTexSubImage2D(ee,f,g,y,o,s,k,Se):this.gl.texSubImage2D(ee,f,g,y,o,s,k,U,n,me);break;case"2d-array":case"3d":K?ne?this.gl.compressedTexImage3D(ee,f,k,o,s,c,0,Se):this.gl.compressedTexSubImage3D(ee,f,g,y,I,o,s,c,k,Se):this.gl.texSubImage3D(ee,f,g,y,I,o,s,c,k,U,n,me);break;default:}}),this.gl.bindTexture(this.glTarget,null)}_getRowByteAlignment(e,r){return 1}_getFramebuffer(){return this._framebuffer||=this.device.createFramebuffer({id:`framebuffer-for-${this.id}`,width:this.width,height:this.height,colorAttachments:[this]}),this._framebuffer}readDataSyncWebGL(e={}){let r=this._getSupportedColorReadOptions(e),i=this.computeMemoryLayout(r),n=gN(this.glType),o=nP(n),s=new o(i.byteLength/o.BYTES_PER_ELEMENT);return this._readColorTextureLayers(r,i,c=>{let f=new o(s.buffer,s.byteOffset+c,i.bytesPerImage/o.BYTES_PER_ELEMENT);this.gl.readPixels(r.x,r.y,r.width,r.height,this.glFormat,this.glType,f)}),s.buffer}_readColorTextureLayers(e,r,i){let n=this._getFramebuffer(),o=r.bytesPerRow/r.bytesPerPixel,s={[3333]:this.byteAlignment,...o!==e.width?{[3330]:o}:{}},c=this.gl.getParameter(3074),f=this.gl.bindFramebuffer(36160,n.handle);try{this.gl.readBuffer(36064),l_(this.gl,s,()=>{for(let g=0;g{});function Aae(t){switch(t){case"point-list":return 0;case"line-list":return 1;case"line-strip":return 3;case"triangle-list":return 4;case"triangle-strip":return 5;default:throw new Error(t)}}function _ae(t){switch(t){case"point-list":return 0;case"line-list":return 1;case"line-strip":return 1;case"triangle-list":return 4;case"triangle-strip":return 4;default:throw new Error(t)}}var cW=Nt(()=>{});function cNe(t,e){let r={...t,attributes:t.attributes.map(i=>({...i})),bindings:t.bindings.map(i=>({...i}))};for(let i of e?.attributes||[]){let n=r.attributes.find(o=>o.name===i.name);n?(n.type=i.type||n.type,n.stepMode=i.stepMode||n.stepMode):Dr.warn(`shader layout attribute ${i.name} not present in shader`)}for(let i of e?.bindings||[]){let n=vae(r,i.name);if(!n){Dr.warn(`shader layout binding ${i.name} not present in shader`);continue}Object.assign(n,i)}return r}function vae(t,e){return t.bindings.find(r=>r.name===e||r.name===`${e}Uniforms`||`${r.name}Uniforms`===e)}function yae(t,e){return t[e]||t[`${e}Uniforms`]||t[e.replace(/Uniforms$/,"")]}var yN,xae=Nt(()=>{Eo();iW();gae();lN();oN();_N();aW();cW();yN=class extends km{device;handle;vs;fs;introspectedLayout;bindings={};uniforms={};varyings=null;_uniformCount=0;_uniformSetters={};get[Symbol.toStringTag](){return"WEBGLRenderPipeline"}constructor(e,r){super(e,r),this.device=e;let i=this.sharedRenderPipeline||this.device._createSharedRenderPipelineWebGL(r);this.sharedRenderPipeline=i,this.handle=i.handle,this.vs=i.vs,this.fs=i.fs,this.linkStatus=i.linkStatus,this.introspectedLayout=i.introspectedLayout,this.device._setWebGLDebugMetadata(this.handle,this,{spector:{id:this.props.id}}),this.shaderLayout=r.shaderLayout?cNe(this.introspectedLayout,r.shaderLayout):this.introspectedLayout}destroy(){this.destroyed||(this.sharedRenderPipeline&&!this.props._sharedRenderPipeline&&this.sharedRenderPipeline.destroy(),this.destroyResource())}setBindings(e,r){let i=ZF(iP(this.shaderLayout,e));for(let[n,o]of Object.entries(i)){let s=vae(this.shaderLayout,n);if(s){switch(o||Dr.warn(`Unsetting binding "${n}" in render pipeline "${this.id}"`)(),s.type){case"uniform":if(!(o instanceof z0)&&!(o.buffer instanceof z0))throw new Error("buffer value");break;case"texture":if(!(o instanceof c_||o instanceof u_||o instanceof a_))throw new Error(`${this} Bad texture binding for ${n}`);break;case"sampler":Dr.warn(`Ignoring sampler ${n}`)();break;default:throw new Error(s.type)}this.bindings[n]=o}else{let c=this.shaderLayout.bindings.map(f=>`"${f.name}"`).join(", ");r?.disableWarnings||Dr.warn(`No binding "${n}" in render pipeline "${this.id}", expected one of ${c}`,o)()}}}draw(e){this._syncLinkStatus();let r=e.bindGroups?ZF(e.bindGroups):e.bindings||this.bindings,{renderPass:i,parameters:n=this.props.parameters,topology:o=this.props.topology,vertexArray:s,vertexCount:c,instanceCount:f,isInstanced:g=!1,firstVertex:y=0,transformFeedback:I,uniforms:F=this.uniforms}=e,k=Aae(o),U=Boolean(s.indexBuffer),K=s.indexBuffer?.glIndexType;if(this.linkStatus!=="success")return Dr.info(2,`RenderPipeline:${this.id}.draw() aborted - waiting for shader linking`)(),!1;if(!this._areTexturesRenderable(r))return Dr.info(2,`RenderPipeline:${this.id}.draw() aborted - textures not yet loaded`)(),!1;this.device.gl.useProgram(this.handle),s.bindBeforeRender(i),I&&I.begin(this.props.topology),this._applyBindings(r,{disableWarnings:this.props.disableWarnings}),this._applyUniforms(F);let ee=i;return dae(this.device,n,ee.glParameters,()=>{U&&g?this.device.gl.drawElementsInstanced(k,c||0,K,y,f||0):U?this.device.gl.drawElements(k,c||0,K,y):g?this.device.gl.drawArraysInstanced(k,y,c||0,f||0):this.device.gl.drawArrays(k,y,c||0),I&&I.end()}),s.unbindAfterRender(i),!0}_areTexturesRenderable(e){let r=!0;for(let i of this.shaderLayout.bindings)yae(e,i.name)||(Dr.warn(`Binding ${i.name} not found in ${this.id}`)(),r=!1);return r}_applyBindings(e,r){if(this._syncLinkStatus(),this.linkStatus!=="success")return;let{gl:i}=this.device;i.useProgram(this.handle);let n=0,o=0;for(let s of this.shaderLayout.bindings){let c=yae(e,s.name);if(!c)throw new Error(`No value for binding ${s.name} in ${this.id}`);switch(s.type){case"uniform":let{name:f}=s,g=i.getUniformBlockIndex(this.handle,f);if(g===4294967295)throw new Error(`Invalid uniform block name ${f}`);if(i.uniformBlockBinding(this.handle,g,o),c instanceof z0)i.bindBufferBase(35345,o,c.handle);else{let I=c;i.bindBufferRange(35345,o,I.buffer.handle,I.offset||0,I.size||I.buffer.byteLength-(I.offset||0))}o+=1;break;case"texture":if(!(c instanceof c_||c instanceof u_||c instanceof a_))throw new Error("texture");let y;if(c instanceof c_)y=c.texture;else if(c instanceof u_)y=c;else if(c instanceof a_&&c.colorAttachments[0]instanceof c_)Dr.warn("Passing framebuffer in texture binding may be deprecated. Use fbo.colorAttachments[0] instead")(),y=c.colorAttachments[0].texture;else throw new Error("No texture");i.activeTexture(33984+n),i.bindTexture(y.glTarget,y.handle),n+=1;break;case"sampler":break;case"storage":case"read-only-storage":throw new Error(`binding type '${s.type}' not supported in WebGL`)}}}_applyUniforms(e){for(let r of this.shaderLayout.uniforms||[]){let{name:i,location:n,type:o,textureUnit:s}=r,c=e[i]??s;c!==void 0&&mae(this.device.gl,n,o,c)}}_syncLinkStatus(){this.linkStatus=this.sharedRenderPipeline.linkStatus}}});function bae(t){return hNe[t]}function vN(t){return uNe[t]}function xN(t){return Boolean(Tae[t])}function wae(t){return Tae[t]}var uNe,Tae,hNe,bN=Nt(()=>{uNe={[5126]:"f32",[35664]:"vec2",[35665]:"vec3",[35666]:"vec4",[5124]:"i32",[35667]:"vec2",[35668]:"vec3",[35669]:"vec4",[5125]:"u32",[36294]:"vec2",[36295]:"vec3",[36296]:"vec4",[35670]:"f32",[35671]:"vec2",[35672]:"vec3",[35673]:"vec4",[35674]:"mat2x2",[35685]:"mat2x3",[35686]:"mat2x4",[35687]:"mat3x2",[35675]:"mat3x3",[35688]:"mat3x4",[35689]:"mat4x2",[35690]:"mat4x3",[35676]:"mat4x4"},Tae={[35678]:{viewDimension:"2d",sampleType:"float"},[35680]:{viewDimension:"cube",sampleType:"float"},[35679]:{viewDimension:"3d",sampleType:"float"},[35682]:{viewDimension:"3d",sampleType:"depth"},[36289]:{viewDimension:"2d-array",sampleType:"float"},[36292]:{viewDimension:"2d-array",sampleType:"depth"},[36293]:{viewDimension:"cube",sampleType:"float"},[36298]:{viewDimension:"2d",sampleType:"sint"},[36299]:{viewDimension:"3d",sampleType:"sint"},[36300]:{viewDimension:"cube",sampleType:"sint"},[36303]:{viewDimension:"2d-array",sampleType:"uint"},[36306]:{viewDimension:"2d",sampleType:"uint"},[36307]:{viewDimension:"3d",sampleType:"uint"},[36308]:{viewDimension:"cube",sampleType:"uint"},[36311]:{viewDimension:"2d-array",sampleType:"uint"}},hNe={uint8:5121,sint8:5120,unorm8:5121,snorm8:5120,uint16:5123,sint16:5122,unorm16:5123,snorm16:5122,uint32:5125,sint32:5124,float16:5131,float32:5126}});function Sae(t,e){let r={attributes:[],bindings:[]};r.attributes=fNe(t,e);let i=mNe(t,e);for(let c of i){let f=c.uniforms.map(g=>({name:g.name,format:g.format,byteOffset:g.byteOffset,byteStride:g.byteStride,arrayLength:g.arrayLength}));r.bindings.push({type:"uniform",name:c.name,group:0,location:c.location,visibility:(c.vertex?1:0)&(c.fragment?2:0),minBindingSize:c.byteLength,uniforms:f})}let n=pNe(t,e),o=0;for(let c of n)if(xN(c.type)){let{viewDimension:f,sampleType:g}=wae(c.type);r.bindings.push({type:"texture",name:c.name,group:0,location:o,viewDimension:f,sampleType:g}),c.textureUnit=o,o+=1}n.length&&(r.uniforms=n);let s=dNe(t,e);return s?.length&&(r.varyings=s),r}function fNe(t,e){let r=[],i=t.getProgramParameter(e,35721);for(let n=0;n=0){let g=vN(c),y=/instance/i.test(s)?"instance":"vertex";r.push({name:s,location:f,stepMode:y,type:g})}}return r.sort((n,o)=>n.location-o.location),r}function dNe(t,e){let r=[],i=t.getProgramParameter(e,35971);for(let n=0;nn.location-o.location),r}function pNe(t,e){let r=[],i=t.getProgramParameter(e,35718);for(let n=0;n1)for(let k=0;kt.getActiveUniformBlockParameter(e,o,s),i=[],n=t.getProgramParameter(e,35382);for(let o=0;oU.name.split(".")[0]).filter(U=>Boolean(U))),k=s.name.replace(/Uniforms$/,"");if(F.size===1&&!F.has(s.name)&&!F.has(k)){let[U]=F;Dr.warn(`Uniform block "${s.name}" uses GLSL instance "${U}". luma.gl binds uniform buffers by block name ("${s.name}") and alias ("${k}"). Prefer matching the instance name to one of those to avoid confusing silent mismatches.`)()}i.push(s)}return i.sort((o,s)=>o.location-s.location),i}function gNe(t){if(t[t.length-1]!=="]")return{name:t,length:1,isArray:!1};let r=/([^[]*)(\[[0-9]+\])?/.exec(t);return{name:S1(r?.[1],`Failed to parse GLSL uniform name ${t}`),length:r?.[2]?1:0,isArray:Boolean(r?.[2])}}var Eae=Nt(()=>{Eo();bN()});var Cae,wN,Iae=Nt(()=>{Eo();Eae();bN();Cae=4,wN=class extends rP{device;handle;vs;fs;introspectedLayout={attributes:[],bindings:[],uniforms:[]};linkStatus="pending";constructor(e,r){super(e,r),this.device=e,this.handle=r.handle||this.device.gl.createProgram(),this.vs=r.vs,this.fs=r.fs,r.varyings&&r.varyings.length>0&&this.device.gl.transformFeedbackVaryings(this.handle,r.varyings,r.bufferMode||35981),this._linkShaders(),Dr.time(3,`RenderPipeline ${this.id} - shaderLayout introspection`)(),this.introspectedLayout=Sae(this.device.gl,this.handle),Dr.timeEnd(3,`RenderPipeline ${this.id} - shaderLayout introspection`)()}destroy(){this.destroyed||(this.device.gl.useProgram(null),this.device.gl.deleteProgram(this.handle),this.handle.destroyed=!0,this.destroyResource())}async _linkShaders(){let{gl:e}=this.device;if(e.attachShader(this.handle,this.vs.handle),e.attachShader(this.handle,this.fs.handle),Dr.time(Cae,`linkProgram for ${this.id}`)(),e.linkProgram(this.handle),Dr.timeEnd(Cae,`linkProgram for ${this.id}`)(),!this.device.features.has("compilation-status-async-webgl")){let i=this._getLinkStatus();this._reportLinkStatus(i);return}Dr.once(1,"RenderPipeline linking is asynchronous")(),await this._waitForLinkComplete(),Dr.info(2,`RenderPipeline ${this.id} - async linking complete: ${this.linkStatus}`)();let r=this._getLinkStatus();this._reportLinkStatus(r)}async _reportLinkStatus(e){switch(e){case"success":return;default:let r=e==="link-error"?"Link error":"Validation error";switch(this.vs.compilationStatus){case"error":throw this.vs.debugShader(),new Error(`${this} ${r} during compilation of ${this.vs}`);case"pending":await this.vs.asyncCompilationStatus,this.vs.debugShader();break;case"success":break}switch(this.fs?.compilationStatus){case"error":throw this.fs.debugShader(),new Error(`${this} ${r} during compilation of ${this.fs}`);case"pending":await this.fs.asyncCompilationStatus,this.fs.debugShader();break;case"success":break}let i=this.device.gl.getProgramInfoLog(this.handle);this.device.reportError(new Error(`${r} during ${e}: ${i}`),this)(),this.device.debug()}}_getLinkStatus(){let{gl:e}=this.device;return e.getProgramParameter(this.handle,35714)?(this._initializeSamplerUniforms(),e.validateProgram(this.handle),e.getProgramParameter(this.handle,35715)?(this.linkStatus="success","success"):(this.linkStatus="error","validation-error")):(this.linkStatus="error","link-error")}_initializeSamplerUniforms(){let{gl:e}=this.device;e.useProgram(this.handle);let r=0,i=e.getProgramParameter(this.handle,35718);for(let n=0;n1){let s=Int32Array.from({length:r.size},(c,f)=>n+f);return o.uniform1iv(e,s),n+r.size}return o.uniform1i(e,n),n+1}async _waitForLinkComplete(){let e=async n=>await new Promise(o=>setTimeout(o,n));if(!this.device.features.has("compilation-status-async-webgl")){await e(10);return}let{gl:i}=this.device;for(;;){if(i.getProgramParameter(this.handle,37297))return;await e(10)}}}});function ANe(t,e){let r=e.sourceBuffer,i=e.destinationBuffer;t.gl.bindBuffer(36662,r.handle),t.gl.bindBuffer(36663,i.handle),t.gl.copyBufferSubData(36662,36663,e.sourceOffset??0,e.destinationOffset??0,e.size),t.gl.bindBuffer(36662,null),t.gl.bindBuffer(36663,null)}function _Ne(t,e){throw new Error("copyBufferToTexture is not supported in WebGL")}function yNe(t,e){let{sourceTexture:r,mipLevel:i=0,aspect:n="all",width:o=e.sourceTexture.width,height:s=e.sourceTexture.height,depthOrArrayLayers:c,origin:f=[0,0,0],destinationBuffer:g,byteOffset:y=0,bytesPerRow:I,rowsPerImage:F}=e;if(r instanceof oo){r.readBuffer({x:f[0]??0,y:f[1]??0,z:f[2]??0,width:o,height:s,depthOrArrayLayers:c,mipLevel:i,aspect:n,byteOffset:y},g);return}if(n!=="all")throw new Error("aspect not supported in WebGL");if(i!==0||c!==void 0||I||F)throw new Error("not implemented");let{framebuffer:k,destroyFramebuffer:U}=Mae(r),K;try{let ee=g,he=o||k.width,xe=s||k.height,me=S1(k.colorAttachments[0]),Se=rN(me.texture.props.format),Oe=Se.format,ne=Se.type;t.gl.bindBuffer(35051,ee.handle),K=t.gl.bindFramebuffer(36160,k.handle),t.gl.readPixels(f[0],f[1],he,xe,Oe,ne,y)}finally{t.gl.bindBuffer(35051,null),K!==void 0&&t.gl.bindFramebuffer(36160,K),U&&k.destroy()}}function vNe(t,e){let{sourceTexture:r,destinationMipLevel:i=0,origin:n=[0,0],destinationOrigin:o=[0,0,0],destinationTexture:s}=e,{width:c=e.destinationTexture.width,height:f=e.destinationTexture.height}=e,{framebuffer:g,destroyFramebuffer:y}=Mae(r),[I=0,F=0]=n,[k,U,K]=o,ee=t.gl.bindFramebuffer(36160,g.handle),he,xe;if(s instanceof u_)he=s,c=Number.isFinite(c)?c:he.width,f=Number.isFinite(f)?f:he.height,he._bind(0),xe=he.glTarget;else throw new Error("invalid destination");switch(xe){case 3553:case 34067:t.gl.copyTexSubImage2D(xe,i,k,U,I,F,c,f);break;case 35866:case 32879:t.gl.copyTexSubImage3D(xe,i,k,U,K,I,F,c,f);break;default:}he&&he._unbind(),t.gl.bindFramebuffer(36160,ee),y&&g.destroy()}function Mae(t){if(t instanceof oo){let{width:e,height:r,id:i}=t;return{framebuffer:t.device.createFramebuffer({id:`framebuffer-for-${i}`,width:e,height:r,colorAttachments:[t]}),destroyFramebuffer:!0}}return{framebuffer:t,destroyFramebuffer:!1}}var TN,Pae=Nt(()=>{Eo();bS();_N();TN=class extends ZT{device;handle=null;commands=[];constructor(e,r={}){super(e,r),this.device=e}_executeCommands(e=this.commands){for(let r of e)switch(r.name){case"copy-buffer-to-buffer":ANe(this.device,r.options);break;case"copy-buffer-to-texture":_Ne(this.device,r.options);break;case"copy-texture-to-buffer":yNe(this.device,r.options);break;case"copy-texture-to-texture":vNe(this.device,r.options);break;default:throw new Error(r.name)}}}});var xNe,SN,Rae=Nt(()=>{Eo();mN();yS();xNe=[1,2,4,8],SN=class extends gy{device;handle=null;glParameters={};constructor(e,r){super(e,r),this.device=e;let i=this.props.framebuffer,n=!i||i.handle===null;n&&e.getDefaultCanvasContext()._resizeDrawingBufferIfNeeded();let o;if(!r?.parameters?.viewport)if(!n&&i){let{width:s,height:c}=i;o=[0,0,s,c]}else{let[s,c]=e.getDefaultCanvasContext().getDrawingBufferSize();o=[0,0,s,c]}if(this.device.pushState(),this.setParameters({viewport:o,...this.props.parameters}),!n&&i?.colorAttachments.length){let s=i.colorAttachments.map((c,f)=>36064+f);this.device.gl.drawBuffers(s)}else n&&this.device.gl.drawBuffers([1029]);this.clear(),this.props.timestampQuerySet&&this.props.beginTimestampIndex!==void 0&&this.props.timestampQuerySet.writeTimestamp(this.props.beginTimestampIndex)}end(){this.destroyed||(this.props.timestampQuerySet&&this.props.endTimestampIndex!==void 0&&this.props.timestampQuerySet.writeTimestamp(this.props.endTimestampIndex),this.device.popState(),this.destroy())}pushDebugGroup(e){}popDebugGroup(){}insertDebugMarker(e){}setParameters(e={}){let r={...this.glParameters};r.framebuffer=this.props.framebuffer||null,this.props.depthReadOnly&&(r.depthMask=!this.props.depthReadOnly),r.stencilMask=this.props.stencilReadOnly?0:1,r[35977]=this.props.discard,e.viewport&&(e.viewport.length>=6?(r.viewport=e.viewport.slice(0,4),r.depthRange=[e.viewport[4],e.viewport[5]]):r.viewport=e.viewport),e.scissorRect&&(r.scissorTest=!0,r.scissor=e.scissorRect),e.blendConstant&&(r.blendColor=e.blendConstant),e.stencilReference!==void 0&&(r[2967]=e.stencilReference,r[36003]=e.stencilReference),"colorMask"in e&&(r.colorMask=xNe.map(i=>Boolean(i&e.colorMask))),this.glParameters=r,F0(this.device.gl,r)}beginOcclusionQuery(e){this.props.occlusionQuerySet?.beginOcclusionQuery()}endOcclusionQuery(){this.props.occlusionQuerySet?.endOcclusionQuery()}clear(){let e={...this.glParameters},r=0;this.props.clearColors&&this.props.clearColors.forEach((i,n)=>{i&&this.clearColorBuffer(n,i)}),this.props.clearColor!==!1&&this.props.clearColors===void 0&&(r|=16384,e.clearColor=this.props.clearColor),this.props.clearDepth!==!1&&(r|=256,e.clearDepth=this.props.clearDepth),this.props.clearStencil!==!1&&(r|=1024,e.clearStencil=this.props.clearStencil),r!==0&&l_(this.device.gl,e,()=>{this.device.gl.clear(r)})}clearColorBuffer(e=0,r=[0,0,0,0]){l_(this.device.gl,{framebuffer:this.props.framebuffer},()=>{switch(r.constructor){case Int8Array:case Int16Array:case Int32Array:this.device.gl.clearBufferiv(6144,e,r);break;case Uint8Array:case Uint8ClampedArray:case Uint16Array:case Uint32Array:this.device.gl.clearBufferuiv(6144,e,r);break;case Float32Array:this.device.gl.clearBufferfv(6144,e,r);break;default:throw new Error("clearColorBuffer: color must be typed array")}})}}});var qP,Bae=Nt(()=>{Eo();Pae();Rae();qP=class extends XT{device;handle=null;commandBuffer;constructor(e,r){super(e,r),this.device=e,this.commandBuffer=new TN(e,{id:`${this.props.id}-command-buffer`})}destroy(){this.destroyResource()}finish(e){return e?.id&&this.commandBuffer.id!==e.id&&(this.commandBuffer.id=e.id,this.commandBuffer.props.id=e.id),this.destroy(),this.commandBuffer}beginRenderPass(e={}){return new SN(this.device,this._applyTimeProfilingToPassProps(e))}beginComputePass(e={}){throw new Error("ComputePass not supported in WebGL")}copyBufferToBuffer(e){this.commandBuffer.commands.push({name:"copy-buffer-to-buffer",options:e})}copyBufferToTexture(e){this.commandBuffer.commands.push({name:"copy-buffer-to-texture",options:e})}copyTextureToBuffer(e){this.commandBuffer.commands.push({name:"copy-texture-to-buffer",options:e})}copyTextureToTexture(e){this.commandBuffer.commands.push({name:"copy-texture-to-texture",options:e})}pushDebugGroup(e){}popDebugGroup(){}insertDebugMarker(e){}resolveQuerySet(e,r,i){throw new Error("resolveQuerySet is not supported in WebGL")}writeTimestamp(e,r){e.writeTimestamp(r)}}});function Lae(t){let{target:e,source:r,start:i=0,count:n=1}=t,o=r.length,s=n*o,c=0;for(let f=i;c{});function bNe(t){return Array.isArray(t)?new Float32Array(t):t}function wNe(t,e){if(!t||!e||t.length!==e.length||t.constructor!==e.constructor)return!1;for(let r=0;r{Eo();Iv();Z9();Dae();wS=class extends KT{get[Symbol.toStringTag](){return"VertexArray"}device;handle;buffer=null;bufferValue=null;static isConstantAttributeZeroSupported(e){return U8()==="Chrome"}constructor(e,r){super(e,r),this.device=e,this.handle=this.device.gl.createVertexArray()}destroy(){super.destroy(),this.buffer&&this.buffer?.destroy(),this.handle&&(this.device.gl.deleteVertexArray(this.handle),this.handle=void 0)}setIndexBuffer(e){let r=e;if(r&&r.glTarget!==34963)throw new Error("Use .setBuffer()");this.device.gl.bindVertexArray(this.handle),this.device.gl.bindBuffer(34963,r?r.handle:null),this.indexBuffer=r,this.device.gl.bindVertexArray(null)}setBuffer(e,r){let i=r;if(i.glTarget===34963)throw new Error("Use .setIndexBuffer()");let{size:n,type:o,stride:s,offset:c,normalized:f,integer:g,divisor:y}=this._getAccessor(e);this.device.gl.bindVertexArray(this.handle),this.device.gl.bindBuffer(34962,i.handle),g?this.device.gl.vertexAttribIPointer(e,n,o,s,c):this.device.gl.vertexAttribPointer(e,n,o,f,s,c),this.device.gl.bindBuffer(34962,null),this.device.gl.enableVertexAttribArray(e),this.device.gl.vertexAttribDivisor(e,y||0),this.attributes[e]=i,this.device.gl.bindVertexArray(null)}setConstantWebGL(e,r){this._enable(e,!1),this.attributes[e]=r}bindBeforeRender(){this.device.gl.bindVertexArray(this.handle),this._applyConstantAttributes()}unbindAfterRender(){this.device.gl.bindVertexArray(null)}_applyConstantAttributes(){for(let e=0;e{Eo();$P();cW();EN=class extends QT{device;gl;handle;layout;buffers={};unusedBuffers={};bindOnUse=!0;_bound=!1;constructor(e,r){super(e,r),this.device=e,this.gl=e.gl,this.handle=this.props.handle||this.gl.createTransformFeedback(),this.layout=this.props.layout,r.buffers&&this.setBuffers(r.buffers),Object.seal(this)}destroy(){this.gl.deleteTransformFeedback(this.handle),super.destroy()}begin(e="point-list"){this.gl.bindTransformFeedback(36386,this.handle),this.bindOnUse&&this._bindBuffers(),this.gl.beginTransformFeedback(_ae(e))}end(){this.gl.endTransformFeedback(),this.bindOnUse&&this._unbindBuffers(),this.gl.bindTransformFeedback(36386,null)}setBuffers(e){this.buffers={},this.unusedBuffers={},this.bind(()=>{for(let[r,i]of Object.entries(e))this.setBuffer(r,i)})}setBuffer(e,r){let i=this._getVaryingIndex(e),{buffer:n,byteLength:o,byteOffset:s}=this._getBufferRange(r);if(i<0){this.unusedBuffers[e]=n,Dr.warn(`${this.id} unusedBuffers varying buffer ${e}`)();return}this.buffers[i]={buffer:n,byteLength:o,byteOffset:s},this.bindOnUse||this._bindBuffer(i,n,s,o)}getBuffer(e){if(Fae(e))return this.buffers[e]||null;let r=this._getVaryingIndex(e);return this.buffers[r]??null}bind(e=this.handle){if(typeof e!="function")return this.gl.bindTransformFeedback(36386,e),this;let r;return this._bound?r=e():(this.gl.bindTransformFeedback(36386,this.handle),this._bound=!0,r=e(),this._bound=!1,this.gl.bindTransformFeedback(36386,null)),r}unbind(){this.bind(null)}_getBufferRange(e){if(e instanceof z0)return{buffer:e,byteOffset:0,byteLength:e.byteLength};let{buffer:r,byteOffset:i=0,byteLength:n=e.buffer.byteLength}=e;return{buffer:r,byteOffset:i,byteLength:n}}_getVaryingIndex(e){if(Fae(e))return Number(e);for(let r of this.layout.varyings||[])if(e===r.name)return r.location;return-1}_bindBuffers(){for(let[e,r]of Object.entries(this.buffers)){let{buffer:i,byteLength:n,byteOffset:o}=this._getBufferRange(r);this._bindBuffer(Number(e),i,o,n)}}_unbindBuffers(){for(let e in this.buffers)this.gl.bindBufferBase(35982,Number(e),null)}_bindBuffer(e,r,i=0,n){let o=r&&r.handle;!o||n===void 0?this.gl.bindBufferBase(35982,e,o):this.gl.bindBufferRange(35982,e,o,i,n)}}});var CN,Nae=Nt(()=>{Eo();CN=class extends JT{device;handle;_timestampPairs=[];_pendingReads=new Set;_occlusionQuery=null;_occlusionActive=!1;get[Symbol.toStringTag](){return"QuerySet"}constructor(e,r){if(super(e,r),this.device=e,r.type==="timestamp"){if(r.count<2)throw new Error("Timestamp QuerySet requires at least two query slots");this._timestampPairs=new Array(Math.ceil(r.count/2)).fill(null).map(()=>({activeQuery:null,completedQueries:[]})),this.handle=null}else{if(r.count>1)throw new Error("WebGL occlusion QuerySet can only have one value");let i=this.device.gl.createQuery();if(!i)throw new Error("WebGL query not supported");this.handle=i}Object.seal(this)}destroy(){if(!this.destroyed){this.handle&&this.device.gl.deleteQuery(this.handle);for(let e of this._timestampPairs){e.activeQuery&&(this._cancelPendingQuery(e.activeQuery),this.device.gl.deleteQuery(e.activeQuery.handle));for(let r of e.completedQueries)this._cancelPendingQuery(r),this.device.gl.deleteQuery(r.handle)}this._occlusionQuery&&(this._cancelPendingQuery(this._occlusionQuery),this.device.gl.deleteQuery(this._occlusionQuery.handle));for(let e of Array.from(this._pendingReads))this._cancelPendingQuery(e);this.destroyResource()}}isResultAvailable(e){return this.props.type==="timestamp"?e===void 0?this._timestampPairs.some((r,i)=>this._isTimestampPairAvailable(i)):this._isTimestampPairAvailable(this._getTimestampPairIndex(e)):this._occlusionQuery?this._pollQueryAvailability(this._occlusionQuery):!1}async readResults(e){let r=e?.firstQuery||0,i=e?.queryCount||this.props.count-r;if(this._validateRange(r,i),this.props.type==="timestamp"){let n=new Array(i).fill(0n),o=Math.floor(r/2),s=Math.floor((r+i-1)/2);for(let c=o;c<=s;c++){let f=await this._consumeTimestampPairResult(c),g=c*2,y=g+1;g>=r&&g=r&&y=this.props.count||r<=e)throw new Error("Timestamp duration range is out of bounds");if(e%2!==0||r!==e+1)throw new Error("WebGL timestamp durations require adjacent even/odd query indices");let i=await this._consumeTimestampPairResult(this._getTimestampPairIndex(e));return Number(i)/1e6}beginOcclusionQuery(){if(this.props.type!=="occlusion")throw new Error("Occlusion queries require an occlusion QuerySet");if(!this.handle)throw new Error("WebGL occlusion query is not available");if(this._occlusionActive)throw new Error("Occlusion query is already active");this.device.gl.beginQuery(35887,this.handle),this._occlusionQuery={handle:this.handle,promise:null,result:null,disjoint:!1,cancelled:!1,pollRequestId:null,resolve:null,reject:null},this._occlusionActive=!0}endOcclusionQuery(){if(!this._occlusionActive)throw new Error("Occlusion query is not active");this.device.gl.endQuery(35887),this._occlusionActive=!1}writeTimestamp(e){if(this.props.type!=="timestamp")throw new Error("Timestamp writes require a timestamp QuerySet");let r=this._getTimestampPairIndex(e),i=this._timestampPairs[r];if(e%2===0){if(i.activeQuery)throw new Error("Timestamp query pair is already active");let n=this.device.gl.createQuery();if(!n)throw new Error("WebGL query not supported");let o={handle:n,promise:null,result:null,disjoint:!1,cancelled:!1,pollRequestId:null,resolve:null,reject:null};this.device.gl.beginQuery(35007,n),i.activeQuery=o;return}if(!i.activeQuery)throw new Error("Timestamp query pair was ended before it was started");this.device.gl.endQuery(35007),i.completedQueries.push(i.activeQuery),i.activeQuery=null}_validateRange(e,r){if(e<0||r<0||e+r>this.props.count)throw new Error("Query read range is out of bounds")}_getTimestampPairIndex(e){if(e<0||e>=this.props.count)throw new Error("Query index is out of bounds");return Math.floor(e/2)}_isTimestampPairAvailable(e){let r=this._timestampPairs[e];return!r||r.completedQueries.length===0?!1:this._pollQueryAvailability(r.completedQueries[0])}_pollQueryAvailability(e){if(e.cancelled||this.destroyed)return e.result=0n,!0;if(e.result!==null||e.disjoint)return!0;if(!this.device.gl.getQueryParameter(e.handle,34919))return!1;let i=Boolean(this.device.gl.getParameter(36795));return e.disjoint=i,e.result=i?0n:BigInt(this.device.gl.getQueryParameter(e.handle,34918)),!0}async _consumeTimestampPairResult(e){let r=this._timestampPairs[e];if(!r||r.completedQueries.length===0)throw new Error("Timestamp query pair has no completed result");let i=r.completedQueries.shift();try{return await this._consumeQueryResult(i)}finally{this.device.gl.deleteQuery(i.handle)}}_consumeQueryResult(e){return e.promise||(this._pendingReads.add(e),e.promise=new Promise((r,i)=>{e.resolve=r,e.reject=i;let n=()=>{if(e.pollRequestId=null,e.cancelled||this.destroyed){this._pendingReads.delete(e),e.promise=null,e.resolve=null,e.reject=null,r(0n);return}if(!this._pollQueryAvailability(e)){e.pollRequestId=this._requestAnimationFrame(n);return}this._pendingReads.delete(e),e.promise=null,e.resolve=null,e.reject=null,e.disjoint?i(new Error("GPU timestamp query was invalidated by a disjoint event")):r(e.result||0n)};n()})),e.promise}_cancelPendingQuery(e){if(this._pendingReads.delete(e),e.cancelled=!0,e.pollRequestId!==null&&(this._cancelAnimationFrame(e.pollRequestId),e.pollRequestId=null),e.resolve){let r=e.resolve;e.promise=null,e.resolve=null,e.reject=null,r(0n)}}_requestAnimationFrame(e){return requestAnimationFrame(e)}_cancelAnimationFrame(e){cancelAnimationFrame(e)}}});var IN,zae=Nt(()=>{Eo();IN=class extends eS{device;gl;handle;signaled;_signaled=!1;constructor(e,r={}){super(e,{}),this.device=e,this.gl=e.gl;let i=this.props.handle||this.gl.fenceSync(this.gl.SYNC_GPU_COMMANDS_COMPLETE,0);if(!i)throw new Error("Failed to create WebGL fence");this.handle=i,this.signaled=new Promise(n=>{let o=()=>{let s=this.gl.clientWaitSync(this.handle,0,0);s===this.gl.ALREADY_SIGNALED||s===this.gl.CONDITION_SATISFIED?(this._signaled=!0,n()):setTimeout(o,1)};o()})}isSignaled(){if(this._signaled)return!0;let e=this.gl.getSyncParameter(this.handle,this.gl.SYNC_STATUS);return this._signaled=e===this.gl.SIGNALED,this._signaled}destroy(){this.destroyed||this.gl.deleteSync(this.handle)}}});function uW(t){switch(t){case 6406:case 33326:case 6403:case 36244:return 1;case 33339:case 33340:case 33328:case 33320:case 33319:return 2;case 6407:case 36248:case 34837:return 3;case 6408:case 36249:case 34836:return 4;default:return 0}}function Uae(t){switch(t){case 5121:return 1;case 33635:case 32819:case 32820:return 2;case 5126:return 4;default:return 0}}var Vae=Nt(()=>{});function jae(t,e){let{sourceX:r=0,sourceY:i=0,sourceAttachment:n=0}=e||{},{target:o=null,sourceWidth:s,sourceHeight:c,sourceDepth:f,sourceFormat:g,sourceType:y}=e||{},{framebuffer:I,deleteFramebuffer:F}=Gae(t),{gl:k,handle:U}=I;s||=I.width,c||=I.height;let K=I.colorAttachments[n]?.texture;if(!K)throw new Error(`Invalid framebuffer attachment ${n}`);f=K?.depth||1,g||=K?.glFormat||6408,y||=K?.glType||5121,o=SNe(o,y,g,s,c,f);let ee=cp.getDataType(o);y=y||bae(ee);let he=k.bindFramebuffer(36160,U);return k.readBuffer(36064+n),k.readPixels(r,i,s,c,g,y,o),k.readBuffer(36064),k.bindFramebuffer(36160,he||null),F&&I.destroy(),o}function Hae(t,e){let{target:r,sourceX:i=0,sourceY:n=0,sourceFormat:o=6408,targetByteOffset:s=0}=e||{},{sourceWidth:c,sourceHeight:f,sourceType:g}=e||{},{framebuffer:y,deleteFramebuffer:I}=Gae(t);c=c||y.width,f=f||y.height;let F=y;g=g||5121;let k=r;if(!k){let K=uW(o),ee=Uae(g),he=s+c*f*K*ee;k=F.device.createBuffer({byteLength:he})}let U=t.device.createCommandEncoder();return U.copyTextureToBuffer({sourceTexture:t,width:c,height:f,origin:[i,n],destinationBuffer:k,byteOffset:s}),U.destroy(),I&&y.destroy(),k}function Gae(t){return t instanceof KA?{framebuffer:t,deleteFramebuffer:!1}:{framebuffer:TNe(t),deleteFramebuffer:!0}}function TNe(t,e){let{device:r,width:i,height:n,id:o}=t;return r.createFramebuffer({...e,id:`framebuffer-for-${o}`,width:i,height:n,colorAttachments:[t]})}function SNe(t,e,r,i,n,o){if(t)return t;e||=5121;let s=gN(e),c=cp.getTypedArrayConstructor(s),f=uW(r);return new c(i*n*f)}var Wae=Nt(()=>{Eo();bN();Vae();lW()});var hW={};Ua(hW,{WebGLDevice:()=>tm});function ENe(t,e,r){switch(r.length){case 1:t.gl.vertexAttrib1fv(e,r);break;case 2:t.gl.vertexAttrib2fv(e,r);break;case 3:t.gl.vertexAttrib3fv(e,r);break;case 4:t.gl.vertexAttrib4fv(e,r);break;default:}}function CNe(t,e,r){t.gl.vertexAttribI4iv(e,r)}function INe(t,e,r){t.gl.vertexAttribI4uiv(e,r)}function MNe(t,e){if(!t||!e||t.length!==e.length||t.constructor!==e.constructor)return!1;for(let r=0;r{Eo();X9();qse();Zk();Zse();iae();nae();oae();sae();j9();H9();bS();lae();lN();hae();pae();_N();oN();xae();Iae();Bae();Oae();kae();Nae();zae();Wae();yS();mN();HP();tm=class extends Qp{static getDeviceFromContext(e){return e?e.luma?.device??null:null}type="webgl";handle;features;limits;info;canvasContext;preferredColorFormat="rgba8unorm";preferredDepthFormat="depth24plus";commandEncoder;lost;_resolveContextLost;gl;_constants;extensions;_polyfilled=!1;spectorJS;get[Symbol.toStringTag](){return"WebGLDevice"}toString(){return`${this[Symbol.toStringTag]}(${this.id})`}isVertexFormatSupported(e){switch(e){case"unorm8x4-bgra":return!1;default:return!0}}constructor(e){super({...e,id:e.id||aae("webgl-device")});let r=Qp._getCanvasContextProps(e);if(!r)throw new Error("WebGLDevice requires props.createCanvasContext to be set");let i=r.canvas?.gl??null,n=tm.getDeviceFromContext(i);if(n)throw new Error(`WebGL context already attached to device ${n.id}`);this.canvasContext=new sN(this,r),this.lost=new Promise(y=>{this._resolveContextLost=y});let o={...e.webgl};r.alphaMode==="premultiplied"&&(o.premultipliedAlpha=!0),e.powerPreference!==void 0&&(o.powerPreference=e.powerPreference),e.failIfMajorPerformanceCaveat!==void 0&&(o.failIfMajorPerformanceCaveat=e.failIfMajorPerformanceCaveat);let c=this.props._handle||Wse(this.canvasContext.canvas,{onContextLost:y=>this._resolveContextLost?.({reason:"destroyed",message:"Entered sleep mode, or too many apps or browser tabs are using the GPU."}),onContextRestored:y=>console.log("WebGL context restored")},o);if(!c)throw new Error("WebGL context creation failed");if(n=tm.getDeviceFromContext(c),n){if(e._reuseDevices)return Dr.log(1,`Not creating a new Device, instead returning a reference to Device ${n.id} already attached to WebGL context`,n)(),this.canvasContext.destroy(),n._reused=!0,n;throw new Error(`WebGL context already attached to device ${n.id}`)}this.handle=c,this.gl=c,this.spectorJS=Pse({...this.props,gl:this.handle});let f=j1(this.handle);f.device=this,f.extensions||(f.extensions={}),this.extensions=f.extensions,this.info=$se(this.gl,this.extensions),this.limits=new nN(this.gl),this.features=new iN(this.gl,this.extensions,this.props._disabledFeatures),this.props._initializeFeatures&&this.features.initializeFeatures(),new k0(this.gl,{log:(...y)=>Dr.log(1,...y)()}).trackState(this.gl,{copyState:!1}),(e.debug||e.debugWebGL)&&(this.gl=Dse(this.gl,{debugWebGL:!0,traceWebGL:e.debugWebGL}),Dr.warn("WebGL debug mode activated. Performance reduced.")()),e.debugWebGL&&(Dr.level=Math.max(Dr.level,1)),this.commandEncoder=new qP(this,{id:`${this}-command-encoder`}),this.canvasContext._startObservers()}destroy(){if(this.commandEncoder?.destroy(),!this.props._reuseDevices&&!this._reused){let e=j1(this.handle);e.device=null}}get isLost(){return this.gl.isContextLost()}createCanvasContext(e){throw new Error("WebGL only supports a single canvas")}createPresentationContext(e){return new aN(this,e||{})}createBuffer(e){let r=this._normalizeBufferProps(e);return new z0(this,r)}createTexture(e){return new u_(this,e)}createExternalTexture(e){throw new Error("createExternalTexture() not implemented")}createSampler(e){return new pN(this,e)}createShader(e){return new uN(this,e)}createFramebuffer(e){return new a_(this,e)}createVertexArray(e){return new wS(this,e)}createTransformFeedback(e){return new EN(this,e)}createQuerySet(e){return new CN(this,e)}createFence(){return new IN(this)}createRenderPipeline(e){return new yN(this,e)}_createSharedRenderPipelineWebGL(e){return new wN(this,e)}createComputePipeline(e){throw new Error("ComputePipeline not supported in WebGL")}createCommandEncoder(e={}){return new qP(this,e)}submit(e){let r=null;e||({submittedCommandEncoder:r,commandBuffer:e}=this._finalizeDefaultCommandEncoderForSubmit());try{e._executeCommands(),r&&r.resolveTimeProfilingQuerySet().then(()=>{this.commandEncoder._gpuTimeMs=r._gpuTimeMs}).catch(()=>{})}finally{e.destroy()}}_finalizeDefaultCommandEncoderForSubmit(){let e=this.commandEncoder,r=e.finish();return this.commandEncoder.destroy(),this.commandEncoder=this.createCommandEncoder({id:e.props.id,timeProfilingQuerySet:e.getTimeProfilingQuerySet()}),{submittedCommandEncoder:e,commandBuffer:r}}readPixelsToArrayWebGL(e,r){return jae(e,r)}readPixelsToBufferWebGL(e,r){return Hae(e,r)}setParametersWebGL(e){F0(this.gl,e)}getParametersWebGL(e){return Kk(this.gl,e)}withParametersWebGL(e,r){return l_(this.gl,e,r)}resetWebGL(){Dr.warn("WebGLDevice.resetWebGL is deprecated, use only for debugging")(),Use(this.gl)}_getDeviceSpecificTextureFormatCapabilities(e){return eae(this.gl,e,this.extensions)}loseDevice(){let e=!1,i=this.getExtension("WEBGL_lose_context").WEBGL_lose_context;return i&&(e=!0,i.loseContext()),this._resolveContextLost?.({reason:"destroyed",message:"Application triggered context loss"}),e}pushState(){k0.get(this.gl).push()}popState(){k0.get(this.gl).pop()}getGLKey(e,r){let i=Number(e);for(let n in this.gl)if(this.gl[n]===i)return`GL.${n}`;return r?.emptyIfUnknown?"":String(e)}getGLKeys(e){let r={emptyIfUnknown:!0};return Object.entries(e).reduce((i,[n,o])=>(i[`${n}:${this.getGLKey(n,r)}`]=`${o}:${this.getGLKey(o,r)}`,i),{})}setConstantAttributeWebGL(e,r){let i=this.limits.maxVertexAttributes;this._constants=this._constants||new Array(i).fill(null);let n=this._constants[e];switch(n&&MNe(n,r)&&Dr.info(1,`setConstantAttributeWebGL(${e}) could have been skipped, value unchanged`)(),this._constants[e]=r,r.constructor){case Float32Array:ENe(this,e,r);break;case Int32Array:CNe(this,e,r);break;case Uint32Array:INe(this,e,r);break;default:throw new Error("constant")}}getExtension(e){return N0(this.gl,e,this.extensions),this.extensions}_setWebGLDebugMetadata(e,r,i){e.luma=r;let n={props:i.spector,id:i.spector.id};e.__SPECTOR_Metadata=n}}});function PNe(t){return typeof WebGL2RenderingContext<"u"&&t instanceof WebGL2RenderingContext?!0:Boolean(t&&typeof t.createVertexArray=="function")}var XP,fW,ZP,qae=Nt(()=>{Eo();Cse();j9();H9();XP=1,fW=class extends JM{type="webgl";constructor(){super(),Qp.defaultProps={...Qp.defaultProps,...Yk}}enforceWebGL2(e){Ese(e)}isSupported(){return typeof WebGL2RenderingContext<"u"}isDeviceHandle(e){return typeof WebGL2RenderingContext<"u"&&e instanceof WebGL2RenderingContext?!0:(typeof WebGLRenderingContext<"u"&&e instanceof WebGLRenderingContext&&Dr.warn("WebGL1 is not supported",e)(),!1)}async attach(e,r={}){let{WebGLDevice:i}=await Promise.resolve().then(()=>(MN(),hW));if(e instanceof i)return e;let n=i.getDeviceFromContext(e);if(n)return n;if(!PNe(e))throw new Error("Invalid WebGL2RenderingContext");let o=r.createCanvasContext===!0?{}:r.createCanvasContext;return new i({...r,_handle:e,createCanvasContext:{canvas:e.canvas,autoResize:!1,...o}})}async create(e={}){let{WebGLDevice:r}=await Promise.resolve().then(()=>(MN(),hW)),i=[];(e.debugWebGL||e.debug)&&i.push(Lse()),e.debugSpectorJS&&i.push(Mse(e));let n=await Promise.allSettled(i);for(let o of n)o.status==="rejected"&&Dr.error(`Failed to initialize debug libraries ${o.reason}`)();try{let o=new r(e);Dr.groupCollapsed(XP,`WebGLDevice ${o.id} created`)();let s=`${o._reused?"Reusing":"Created"} device with WebGL2 ${o.props.debug?"debug ":""}context: ${o.info.vendor}, ${o.info.renderer} for canvas: ${o.canvasContext.id}`;return Dr.probe(XP,s)(),Dr.table(XP,o.info)(),o}finally{Dr.groupEnd(XP)(),Dr.info(XP,"%cWebGL call tracing: luma.log.set('debug-webgl') ","color: white; background: blue; padding: 2px 6px; border-radius: 3px;")()}}};ZP=new fW});var $P=Nt(()=>{qae();MN();lN()});var kle=Vi((RW,BW)=>{(function(t,e){typeof RW=="object"&&typeof BW<"u"?BW.exports=e():typeof define=="function"&&define.amd?define(e):(t=typeof globalThis<"u"?globalThis:t||self,t.maplibregl=e())})(RW,function(){"use strict";var t={},e={};function r(n,o,s){if(e[n]=s,n==="index"){var c="var sharedModule = {}; ("+e.shared+")(sharedModule); ("+e.worker+")(sharedModule);",f={};return e.shared(f),e.index(t,f),typeof window<"u"&&t.setWorkerUrl(window.URL.createObjectURL(new Blob([c],{type:"text/javascript"}))),t}}r("shared",["exports"],function(n){"use strict";function o(d,a,h,A){return new(h||(h=Promise))(function(C,D){function O(re){try{Z(A.next(re))}catch(ce){D(ce)}}function H(re){try{Z(A.throw(re))}catch(ce){D(ce)}}function Z(re){var ce;re.done?C(re.value):(ce=re.value,ce instanceof h?ce:new h(function(de){de(ce)})).then(O,H)}Z((A=A.apply(d,a||[])).next())})}function s(d,a){this.x=d,this.y=a}function c(d){return d&&d.__esModule&&Object.prototype.hasOwnProperty.call(d,"default")?d.default:d}var f,g;typeof SuppressedError=="function"&&SuppressedError,s.prototype={clone(){return new s(this.x,this.y)},add(d){return this.clone()._add(d)},sub(d){return this.clone()._sub(d)},multByPoint(d){return this.clone()._multByPoint(d)},divByPoint(d){return this.clone()._divByPoint(d)},mult(d){return this.clone()._mult(d)},div(d){return this.clone()._div(d)},rotate(d){return this.clone()._rotate(d)},rotateAround(d,a){return this.clone()._rotateAround(d,a)},matMult(d){return this.clone()._matMult(d)},unit(){return this.clone()._unit()},perp(){return this.clone()._perp()},round(){return this.clone()._round()},mag(){return Math.sqrt(this.x*this.x+this.y*this.y)},equals(d){return this.x===d.x&&this.y===d.y},dist(d){return Math.sqrt(this.distSqr(d))},distSqr(d){let a=d.x-this.x,h=d.y-this.y;return a*a+h*h},angle(){return Math.atan2(this.y,this.x)},angleTo(d){return Math.atan2(this.y-d.y,this.x-d.x)},angleWith(d){return this.angleWithSep(d.x,d.y)},angleWithSep(d,a){return Math.atan2(this.x*a-this.y*d,this.x*d+this.y*a)},_matMult(d){let a=d[2]*this.x+d[3]*this.y;return this.x=d[0]*this.x+d[1]*this.y,this.y=a,this},_add(d){return this.x+=d.x,this.y+=d.y,this},_sub(d){return this.x-=d.x,this.y-=d.y,this},_mult(d){return this.x*=d,this.y*=d,this},_div(d){return this.x/=d,this.y/=d,this},_multByPoint(d){return this.x*=d.x,this.y*=d.y,this},_divByPoint(d){return this.x/=d.x,this.y/=d.y,this},_unit(){return this._div(this.mag()),this},_perp(){let d=this.y;return this.y=this.x,this.x=-d,this},_rotate(d){let a=Math.cos(d),h=Math.sin(d),A=h*this.x+a*this.y;return this.x=a*this.x-h*this.y,this.y=A,this},_rotateAround(d,a){let h=Math.cos(d),A=Math.sin(d),C=a.y+A*(this.x-a.x)+h*(this.y-a.y);return this.x=a.x+h*(this.x-a.x)-A*(this.y-a.y),this.y=C,this},_round(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this},constructor:s},s.convert=function(d){if(d instanceof s)return d;if(Array.isArray(d))return new s(+d[0],+d[1]);if(d.x!==void 0&&d.y!==void 0)return new s(+d.x,+d.y);throw new Error("Expected [x, y] or {x, y} point format")};var y=function(){if(g)return f;function d(a,h,A,C){this.cx=3*a,this.bx=3*(A-a)-this.cx,this.ax=1-this.cx-this.bx,this.cy=3*h,this.by=3*(C-h)-this.cy,this.ay=1-this.cy-this.by,this.p1x=a,this.p1y=h,this.p2x=A,this.p2y=C}return g=1,f=d,d.prototype={sampleCurveX:function(a){return((this.ax*a+this.bx)*a+this.cx)*a},sampleCurveY:function(a){return((this.ay*a+this.by)*a+this.cy)*a},sampleCurveDerivativeX:function(a){return(3*this.ax*a+2*this.bx)*a+this.cx},solveCurveX:function(a,h){if(h===void 0&&(h=1e-6),a<0)return 0;if(a>1)return 1;for(var A=a,C=0;C<8;C++){var D=this.sampleCurveX(A)-a;if(Math.abs(D)D?H=A:Z=A,A=.5*(Z-H)+H;return A},solve:function(a,h){return this.sampleCurveY(this.solveCurveX(a,h))}},f}(),I=c(y);let F,k;function U(){return F==null&&(F=typeof OffscreenCanvas<"u"&&new OffscreenCanvas(1,1).getContext("2d")&&typeof createImageBitmap=="function"),F}function K(){if(k==null&&(k=!1,U())){let a=new OffscreenCanvas(5,5).getContext("2d",{willReadFrequently:!0});if(a){for(let A=0;A<5*5;A++){let C=4*A;a.fillStyle=`rgb(${C},${C+1},${C+2})`,a.fillRect(A%5,Math.floor(A/5),1,1)}let h=a.getImageData(0,0,5,5).data;for(let A=0;A<5*5*4;A++)if(A%4!=3&&h[A]!==A){k=!0;break}}}return k||!1}var ee=1e-6,he=typeof Float32Array<"u"?Float32Array:Array;function xe(){var d=new he(9);return he!=Float32Array&&(d[1]=0,d[2]=0,d[3]=0,d[5]=0,d[6]=0,d[7]=0),d[0]=1,d[4]=1,d[8]=1,d}function me(d){return d[0]=1,d[1]=0,d[2]=0,d[3]=0,d[4]=0,d[5]=1,d[6]=0,d[7]=0,d[8]=0,d[9]=0,d[10]=1,d[11]=0,d[12]=0,d[13]=0,d[14]=0,d[15]=1,d}function Se(){var d=new he(3);return he!=Float32Array&&(d[0]=0,d[1]=0,d[2]=0),d}function Oe(d){var a=d[0],h=d[1],A=d[2];return Math.sqrt(a*a+h*h+A*A)}function ne(d,a,h){var A=new he(3);return A[0]=d,A[1]=a,A[2]=h,A}function Ge(d,a,h){return d[0]=a[0]+h[0],d[1]=a[1]+h[1],d[2]=a[2]+h[2],d}function Xe(d,a,h){return d[0]=a[0]*h,d[1]=a[1]*h,d[2]=a[2]*h,d}function Ce(d,a,h){var A=a[0],C=a[1],D=a[2],O=h[0],H=h[1],Z=h[2];return d[0]=C*Z-D*H,d[1]=D*O-A*Z,d[2]=A*H-C*O,d}var _e,Je=Oe;function Et(d,a,h){var A=a[0],C=a[1],D=a[2],O=a[3];return d[0]=h[0]*A+h[4]*C+h[8]*D+h[12]*O,d[1]=h[1]*A+h[5]*C+h[9]*D+h[13]*O,d[2]=h[2]*A+h[6]*C+h[10]*D+h[14]*O,d[3]=h[3]*A+h[7]*C+h[11]*D+h[15]*O,d}function Ze(){var d=new he(4);return he!=Float32Array&&(d[0]=0,d[1]=0,d[2]=0),d[3]=1,d}function xt(d,a,h,A){var C=arguments.length>4&&arguments[4]!==void 0?arguments[4]:"zyx",D=Math.PI/360;a*=D,A*=D,h*=D;var O=Math.sin(a),H=Math.cos(a),Z=Math.sin(h),re=Math.cos(h),ce=Math.sin(A),de=Math.cos(A);switch(C){case"xyz":d[0]=O*re*de+H*Z*ce,d[1]=H*Z*de-O*re*ce,d[2]=H*re*ce+O*Z*de,d[3]=H*re*de-O*Z*ce;break;case"xzy":d[0]=O*re*de-H*Z*ce,d[1]=H*Z*de-O*re*ce,d[2]=H*re*ce+O*Z*de,d[3]=H*re*de+O*Z*ce;break;case"yxz":d[0]=O*re*de+H*Z*ce,d[1]=H*Z*de-O*re*ce,d[2]=H*re*ce-O*Z*de,d[3]=H*re*de+O*Z*ce;break;case"yzx":d[0]=O*re*de+H*Z*ce,d[1]=H*Z*de+O*re*ce,d[2]=H*re*ce-O*Z*de,d[3]=H*re*de-O*Z*ce;break;case"zxy":d[0]=O*re*de-H*Z*ce,d[1]=H*Z*de+O*re*ce,d[2]=H*re*ce+O*Z*de,d[3]=H*re*de-O*Z*ce;break;case"zyx":d[0]=O*re*de-H*Z*ce,d[1]=H*Z*de+O*re*ce,d[2]=H*re*ce-O*Z*de,d[3]=H*re*de+O*Z*ce;break;default:throw new Error("Unknown angle order "+C)}return d}function sr(){var d=new he(2);return he!=Float32Array&&(d[0]=0,d[1]=0),d}function Mr(d,a){var h=new he(2);return h[0]=d,h[1]=a,h}Se(),_e=new he(4),he!=Float32Array&&(_e[0]=0,_e[1]=0,_e[2]=0,_e[3]=0),Se(),ne(1,0,0),ne(0,1,0),Ze(),Ze(),xe(),sr();let hr=8192;function mi(d,a,h){return a*(hr/(d.tileSize*Math.pow(2,h-d.tileID.overscaledZ)))}function bi(d,a){return(d%a+a)%a}function un(d,a,h){return d*(1-h)+a*h}function Yr(d){if(d<=0)return 0;if(d>=1)return 1;let a=d*d,h=a*d;return 4*(d<.5?h:3*(d-a)+h-.75)}function Xi(d,a,h,A){let C=new I(d,a,h,A);return D=>C.solve(D)}let xi=Xi(.25,.1,.25,1);function ii(d,a,h){return Math.min(h,Math.max(a,d))}function Gn(d,a,h){let A=h-a,C=((d-a)%A+A)%A+a;return C===a?h:C}function Ve(d,...a){for(let h of a)for(let A in h)d[A]=h[A];return d}let nt=1;function Ft(d,a,h){let A={};for(let C in d)A[C]=a.call(this,d[C],C,d);return A}function mr(d,a,h){let A={};for(let C in d)a.call(this,d[C],C,d)&&(A[C]=d[C]);return A}function Xr(d){return Array.isArray(d)?d.map(Xr):typeof d=="object"&&d?Ft(d,Xr):d}let zr={};function ln(d){zr[d]||(typeof console<"u"&&console.warn(d),zr[d]=!0)}function Nn(d,a,h){return(h.y-d.y)*(a.x-d.x)>(a.y-d.y)*(h.x-d.x)}function Co(d){return typeof WorkerGlobalScope<"u"&&d!==void 0&&d instanceof WorkerGlobalScope}let Ho=null;function is(d){return typeof ImageBitmap<"u"&&d instanceof ImageBitmap}let mo="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQYV2NgAAIAAAUAAarVyFEAAAAASUVORK5CYII=";function zs(d,a,h,A,C){return o(this,void 0,void 0,function*(){if(typeof VideoFrame>"u")throw new Error("VideoFrame not supported");let D=new VideoFrame(d,{timestamp:0});try{let O=D?.format;if(!O||!O.startsWith("BGR")&&!O.startsWith("RGB"))throw new Error(`Unrecognized format ${O}`);let H=O.startsWith("BGR"),Z=new Uint8ClampedArray(A*C*4);if(yield D.copyTo(Z,function(re,ce,de,we,Ee){let De=4*Math.max(-ce,0),ke=(Math.max(0,de)-de)*we*4+De,qe=4*we,st=Math.max(0,ce),kt=Math.max(0,de);return{rect:{x:st,y:kt,width:Math.min(re.width,ce+we)-st,height:Math.min(re.height,de+Ee)-kt},layout:[{offset:ke,stride:qe}]}}(d,a,h,A,C)),H)for(let re=0;re{d.removeEventListener(a,h,A)}}}function ps(d){return d*Math.PI/180}function ws(d){return d/Math.PI*180}let Yt={touchstart:!0,touchmove:!0,touchmoveWindow:!0,touchend:!0,touchcancel:!0},Fe={dblclick:!0,click:!0,mouseover:!0,mouseout:!0,mousedown:!0,mousemove:!0,mousemoveWindow:!0,mouseup:!0,mouseupWindow:!0,contextmenu:!0,wheel:!0},Ne="AbortError";class rt extends Error{constructor(a=Ne){super(a instanceof Error?a.message:a),this.name=Ne,a instanceof Error&&a.stack&&(this.stack=a.stack)}}function Vt(d){return d.name===Ne}let Gt={MAX_PARALLEL_IMAGE_REQUESTS:16,MAX_PARALLEL_IMAGE_REQUESTS_PER_FRAME:8,MAX_TILE_CACHE_ZOOM_LEVELS:5,REGISTERED_PROTOCOLS:{},WORKER_URL:""};function yr(d){return Gt.REGISTERED_PROTOCOLS[d.substring(0,d.indexOf("://"))]}let fr="global-dispatcher";class nr extends Error{constructor(a,h,A,C){super(`AJAXError: ${h} (${a}): ${A}`),this.status=a,this.statusText=h,this.url=A,this.body=C}}let xr=()=>Co(self)?self.worker&&self.worker.referrer:(window.location.protocol==="blob:"?window.parent:window).location.href,ti=function(d,a){if(/:\/\//.test(d.url)&&!/^https?:|^file:/.test(d.url)){let A=yr(d.url);if(A)return A(d,a);if(Co(self)&&self.worker&&self.worker.actor)return self.worker.actor.sendAsync({type:"GR",data:d,targetMapId:fr},a)}if(!(/^file:/.test(h=d.url)||/^file:/.test(xr())&&!/^\w+:/.test(h))){if(fetch&&Request&&AbortController&&Object.prototype.hasOwnProperty.call(Request.prototype,"signal"))return function(A,C){return o(this,void 0,void 0,function*(){let D=new Request(A.url,{method:A.method||"GET",body:A.body,credentials:A.credentials,headers:A.headers,cache:A.cache,referrer:xr(),signal:C.signal}),O,H;A.type!=="json"||D.headers.has("Accept")||D.headers.set("Accept","application/json");try{O=yield fetch(D)}catch(re){throw Vt(re)?re:new nr(0,re.message,A.url,new Blob)}if(!O.ok){let re=yield O.blob();throw new nr(O.status,O.statusText,A.url,re)}H=A.type==="arrayBuffer"||A.type==="image"?O.arrayBuffer():A.type==="json"?O.json():O.text();let Z=yield H;return C.signal.throwIfAborted(),{data:Z,cacheControl:O.headers.get("Cache-Control"),expires:O.headers.get("Expires")}})}(d,a);if(Co(self)&&self.worker&&self.worker.actor)return self.worker.actor.sendAsync({type:"GR",data:d,mustQueue:!0,targetMapId:fr},a)}var h;return function(A,C){return new Promise((D,O)=>{var H;let Z=new XMLHttpRequest;Z.open(A.method||"GET",A.url,!0),A.type!=="arrayBuffer"&&A.type!=="image"||(Z.responseType="arraybuffer");for(let re in A.headers)Z.setRequestHeader(re,A.headers[re]);A.type==="json"&&(Z.responseType="text",!((H=A.headers)===null||H===void 0)&&H.Accept||Z.setRequestHeader("Accept","application/json")),Z.withCredentials=A.credentials==="include",Z.onerror=()=>{O(new Error(Z.statusText))},Z.onload=()=>{if(!C.signal.aborted)if((Z.status>=200&&Z.status<300||Z.status===0)&&Z.response!==null){let re=Z.response;if(A.type==="json")try{re=JSON.parse(Z.response)}catch(ce){return void O(ce)}D({data:re,cacheControl:Z.getResponseHeader("Cache-Control"),expires:Z.getResponseHeader("Expires")})}else{let re=new Blob([Z.response],{type:Z.getResponseHeader("Content-Type")});O(new nr(Z.status,Z.statusText,A.url,re))}},C.signal.addEventListener("abort",()=>{Z.abort(),O(new rt(C.signal.reason))}),Z.send(A.body)})}(d,a)};function Jr(d){if(!d||d.indexOf("://")<=0||d.indexOf("data:image/")===0||d.indexOf("blob:")===0)return!0;let a=new URL(d),h=window.location;return a.protocol===h.protocol&&a.host===h.host}function Wi(d,a,h){h[d]&&h[d].indexOf(a)!==-1||(h[d]=h[d]||[],h[d].push(a))}function fn(d,a,h){if(h&&h[d]){let A=h[d].indexOf(a);A!==-1&&h[d].splice(A,1)}}class Wn{constructor(a,h={}){Ve(this,h),this.type=a}}class bs extends Wn{constructor(a,h={}){super("error",Ve({error:a},h))}}class go{on(a,h){return this._listeners=this._listeners||{},Wi(a,h,this._listeners),{unsubscribe:()=>{this.off(a,h)}}}off(a,h){return fn(a,h,this._listeners),fn(a,h,this._oneTimeListeners),this}once(a,h){return h?(this._oneTimeListeners=this._oneTimeListeners||{},Wi(a,h,this._oneTimeListeners),this):new Promise(A=>this.once(a,A))}fire(a,h){typeof a=="string"&&(a=new Wn(a,h||{}));let A=a.type;if(this.listens(A)){a.target=this;let C=this._listeners&&this._listeners[A]?this._listeners[A].slice():[];for(let H of C)H.call(this,a);let D=this._oneTimeListeners&&this._oneTimeListeners[A]?this._oneTimeListeners[A].slice():[];for(let H of D)fn(A,H,this._oneTimeListeners),H.call(this,a);let O=this._eventedParent;O&&(Ve(a,typeof this._eventedParentData=="function"?this._eventedParentData():this._eventedParentData),O.fire(a))}else a instanceof bs&&console.error(a.error);return this}listens(a){return this._listeners&&this._listeners[a]&&this._listeners[a].length>0||this._oneTimeListeners&&this._oneTimeListeners[a]&&this._oneTimeListeners[a].length>0||this._eventedParent&&this._eventedParent.listens(a)}setEventedParent(a,h){return this._eventedParent=a,this._eventedParentData=h,this}}var wr={$version:8,$root:{version:{required:!0,type:"enum",values:[8]},name:{type:"string"},metadata:{type:"*"},center:{type:"array",value:"number"},centerAltitude:{type:"number"},zoom:{type:"number"},bearing:{type:"number",default:0,period:360,units:"degrees"},pitch:{type:"number",default:0,units:"degrees"},roll:{type:"number",default:0,units:"degrees"},state:{type:"state",default:{}},light:{type:"light"},sky:{type:"sky"},projection:{type:"projection"},terrain:{type:"terrain"},sources:{required:!0,type:"sources"},sprite:{type:"sprite"},glyphs:{type:"string"},"font-faces":{type:"array",value:"fontFaces"},transition:{type:"transition"},layers:{required:!0,type:"array",value:"layer"}},sources:{"*":{type:"source"}},source:["source_vector","source_raster","source_raster_dem","source_geojson","source_video","source_image"],source_vector:{type:{required:!0,type:"enum",values:{vector:{}}},url:{type:"string"},tiles:{type:"array",value:"string"},bounds:{type:"array",value:"number",length:4,default:[-180,-85.051129,180,85.051129]},scheme:{type:"enum",values:{xyz:{},tms:{}},default:"xyz"},minzoom:{type:"number",default:0},maxzoom:{type:"number",default:22},attribution:{type:"string"},promoteId:{type:"promoteId"},volatile:{type:"boolean",default:!1},encoding:{type:"enum",values:{mvt:{},mlt:{}},default:"mvt"},"*":{type:"*"}},source_raster:{type:{required:!0,type:"enum",values:{raster:{}}},url:{type:"string"},tiles:{type:"array",value:"string"},bounds:{type:"array",value:"number",length:4,default:[-180,-85.051129,180,85.051129]},minzoom:{type:"number",default:0},maxzoom:{type:"number",default:22},tileSize:{type:"number",default:512,units:"pixels"},scheme:{type:"enum",values:{xyz:{},tms:{}},default:"xyz"},attribution:{type:"string"},volatile:{type:"boolean",default:!1},"*":{type:"*"}},source_raster_dem:{type:{required:!0,type:"enum",values:{"raster-dem":{}}},url:{type:"string"},tiles:{type:"array",value:"string"},bounds:{type:"array",value:"number",length:4,default:[-180,-85.051129,180,85.051129]},minzoom:{type:"number",default:0},maxzoom:{type:"number",default:22},tileSize:{type:"number",default:512,units:"pixels"},attribution:{type:"string"},encoding:{type:"enum",values:{terrarium:{},mapbox:{},custom:{}},default:"mapbox"},redFactor:{type:"number",default:1},blueFactor:{type:"number",default:1},greenFactor:{type:"number",default:1},baseShift:{type:"number",default:0},volatile:{type:"boolean",default:!1},"*":{type:"*"}},source_geojson:{type:{required:!0,type:"enum",values:{geojson:{}}},data:{required:!0,type:"*"},maxzoom:{type:"number",default:18},attribution:{type:"string"},buffer:{type:"number",default:128,maximum:512,minimum:0},filter:{type:"*"},tolerance:{type:"number",default:.375},cluster:{type:"boolean",default:!1},clusterRadius:{type:"number",default:50,minimum:0},clusterMaxZoom:{type:"number"},clusterMinPoints:{type:"number"},clusterProperties:{type:"*"},lineMetrics:{type:"boolean",default:!1},generateId:{type:"boolean",default:!1},promoteId:{type:"promoteId"}},source_video:{type:{required:!0,type:"enum",values:{video:{}}},urls:{required:!0,type:"array",value:"string"},coordinates:{required:!0,type:"array",length:4,value:{type:"array",length:2,value:"number"}}},source_image:{type:{required:!0,type:"enum",values:{image:{}}},url:{required:!0,type:"string"},coordinates:{required:!0,type:"array",length:4,value:{type:"array",length:2,value:"number"}}},layer:{id:{type:"string",required:!0},type:{type:"enum",values:{fill:{},line:{},symbol:{},circle:{},heatmap:{},"fill-extrusion":{},raster:{},hillshade:{},"color-relief":{},background:{}},required:!0},metadata:{type:"*"},source:{type:"string"},"source-layer":{type:"string"},minzoom:{type:"number",minimum:0,maximum:24},maxzoom:{type:"number",minimum:0,maximum:24},filter:{type:"filter"},layout:{type:"layout"},paint:{type:"paint"}},layout:["layout_fill","layout_line","layout_circle","layout_heatmap","layout_fill-extrusion","layout_symbol","layout_raster","layout_hillshade","layout_color-relief","layout_background"],layout_background:{visibility:{type:"enum",values:{visible:{},none:{}},default:"visible","property-type":"constant"}},layout_fill:{"fill-sort-key":{type:"number",expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"data-driven"},visibility:{type:"enum",values:{visible:{},none:{}},default:"visible","property-type":"constant"}},layout_circle:{"circle-sort-key":{type:"number",expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"data-driven"},visibility:{type:"enum",values:{visible:{},none:{}},default:"visible","property-type":"constant"}},layout_heatmap:{visibility:{type:"enum",values:{visible:{},none:{}},default:"visible","property-type":"constant"}},"layout_fill-extrusion":{visibility:{type:"enum",values:{visible:{},none:{}},default:"visible","property-type":"constant"}},layout_line:{"line-cap":{type:"enum",values:{butt:{},round:{},square:{}},default:"butt",expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"line-join":{type:"enum",values:{bevel:{},round:{},miter:{}},default:"miter",expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"data-driven"},"line-miter-limit":{type:"number",default:2,requires:[{"line-join":"miter"}],expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"line-round-limit":{type:"number",default:1.05,requires:[{"line-join":"round"}],expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"line-sort-key":{type:"number",expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"data-driven"},visibility:{type:"enum",values:{visible:{},none:{}},default:"visible","property-type":"constant"}},layout_symbol:{"symbol-placement":{type:"enum",values:{point:{},line:{},"line-center":{}},default:"point",expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"symbol-spacing":{type:"number",default:250,minimum:1,units:"pixels",requires:[{"symbol-placement":"line"}],expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"symbol-avoid-edges":{type:"boolean",default:!1,expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"symbol-sort-key":{type:"number",expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"data-driven"},"symbol-z-order":{type:"enum",values:{auto:{},"viewport-y":{},source:{}},default:"auto",expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"icon-allow-overlap":{type:"boolean",default:!1,requires:["icon-image",{"!":"icon-overlap"}],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"icon-overlap":{type:"enum",values:{never:{},always:{},cooperative:{}},requires:["icon-image"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"icon-ignore-placement":{type:"boolean",default:!1,requires:["icon-image"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"icon-optional":{type:"boolean",default:!1,requires:["icon-image","text-field"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"icon-rotation-alignment":{type:"enum",values:{map:{},viewport:{},auto:{}},default:"auto",requires:["icon-image"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"icon-size":{type:"number",default:1,minimum:0,units:"factor of the original icon size",requires:["icon-image"],expression:{interpolated:!0,parameters:["zoom","feature"]},"property-type":"data-driven"},"icon-text-fit":{type:"enum",values:{none:{},width:{},height:{},both:{}},default:"none",requires:["icon-image","text-field"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"icon-text-fit-padding":{type:"array",value:"number",length:4,default:[0,0,0,0],units:"pixels",requires:["icon-image","text-field",{"icon-text-fit":["both","width","height"]}],expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"icon-image":{type:"resolvedImage",tokens:!0,expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"data-driven"},"icon-rotate":{type:"number",default:0,period:360,units:"degrees",requires:["icon-image"],expression:{interpolated:!0,parameters:["zoom","feature"]},"property-type":"data-driven"},"icon-padding":{type:"padding",default:[2],units:"pixels",requires:["icon-image"],expression:{interpolated:!0,parameters:["zoom","feature"]},"property-type":"data-driven"},"icon-keep-upright":{type:"boolean",default:!1,requires:["icon-image",{"icon-rotation-alignment":"map"},{"symbol-placement":["line","line-center"]}],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"icon-offset":{type:"array",value:"number",length:2,default:[0,0],requires:["icon-image"],expression:{interpolated:!0,parameters:["zoom","feature"]},"property-type":"data-driven"},"icon-anchor":{type:"enum",values:{center:{},left:{},right:{},top:{},bottom:{},"top-left":{},"top-right":{},"bottom-left":{},"bottom-right":{}},default:"center",requires:["icon-image"],expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"data-driven"},"icon-pitch-alignment":{type:"enum",values:{map:{},viewport:{},auto:{}},default:"auto",requires:["icon-image"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"text-pitch-alignment":{type:"enum",values:{map:{},viewport:{},auto:{}},default:"auto",requires:["text-field"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"text-rotation-alignment":{type:"enum",values:{map:{},viewport:{},"viewport-glyph":{},auto:{}},default:"auto",requires:["text-field"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"text-field":{type:"formatted",default:"",tokens:!0,expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"data-driven"},"text-font":{type:"array",value:"string",default:["Open Sans Regular","Arial Unicode MS Regular"],requires:["text-field"],expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"data-driven"},"text-size":{type:"number",default:16,minimum:0,units:"pixels",requires:["text-field"],expression:{interpolated:!0,parameters:["zoom","feature"]},"property-type":"data-driven"},"text-max-width":{type:"number",default:10,minimum:0,units:"ems",requires:["text-field"],expression:{interpolated:!0,parameters:["zoom","feature"]},"property-type":"data-driven"},"text-line-height":{type:"number",default:1.2,units:"ems",requires:["text-field"],expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"text-letter-spacing":{type:"number",default:0,units:"ems",requires:["text-field"],expression:{interpolated:!0,parameters:["zoom","feature"]},"property-type":"data-driven"},"text-justify":{type:"enum",values:{auto:{},left:{},center:{},right:{}},default:"center",requires:["text-field"],expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"data-driven"},"text-radial-offset":{type:"number",units:"ems",default:0,requires:["text-field"],"property-type":"data-driven",expression:{interpolated:!0,parameters:["zoom","feature"]}},"text-variable-anchor":{type:"array",value:"enum",values:{center:{},left:{},right:{},top:{},bottom:{},"top-left":{},"top-right":{},"bottom-left":{},"bottom-right":{}},requires:["text-field",{"symbol-placement":["point"]}],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"text-variable-anchor-offset":{type:"variableAnchorOffsetCollection",requires:["text-field",{"symbol-placement":["point"]}],expression:{interpolated:!0,parameters:["zoom","feature"]},"property-type":"data-driven"},"text-anchor":{type:"enum",values:{center:{},left:{},right:{},top:{},bottom:{},"top-left":{},"top-right":{},"bottom-left":{},"bottom-right":{}},default:"center",requires:["text-field",{"!":"text-variable-anchor"}],expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"data-driven"},"text-max-angle":{type:"number",default:45,units:"degrees",requires:["text-field",{"symbol-placement":["line","line-center"]}],expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"text-writing-mode":{type:"array",value:"enum",values:{horizontal:{},vertical:{}},requires:["text-field",{"symbol-placement":["point"]}],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"text-rotate":{type:"number",default:0,period:360,units:"degrees",requires:["text-field"],expression:{interpolated:!0,parameters:["zoom","feature"]},"property-type":"data-driven"},"text-padding":{type:"number",default:2,minimum:0,units:"pixels",requires:["text-field"],expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"text-keep-upright":{type:"boolean",default:!0,requires:["text-field",{"text-rotation-alignment":"map"},{"symbol-placement":["line","line-center"]}],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"text-transform":{type:"enum",values:{none:{},uppercase:{},lowercase:{}},default:"none",requires:["text-field"],expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"data-driven"},"text-offset":{type:"array",value:"number",units:"ems",length:2,default:[0,0],requires:["text-field",{"!":"text-radial-offset"}],expression:{interpolated:!0,parameters:["zoom","feature"]},"property-type":"data-driven"},"text-allow-overlap":{type:"boolean",default:!1,requires:["text-field",{"!":"text-overlap"}],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"text-overlap":{type:"enum",values:{never:{},always:{},cooperative:{}},requires:["text-field"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"text-ignore-placement":{type:"boolean",default:!1,requires:["text-field"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"text-optional":{type:"boolean",default:!1,requires:["text-field","icon-image"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},visibility:{type:"enum",values:{visible:{},none:{}},default:"visible","property-type":"constant"}},layout_raster:{visibility:{type:"enum",values:{visible:{},none:{}},default:"visible","property-type":"constant"}},layout_hillshade:{visibility:{type:"enum",values:{visible:{},none:{}},default:"visible","property-type":"constant"}},"layout_color-relief":{visibility:{type:"enum",values:{visible:{},none:{}},default:"visible","property-type":"constant"}},filter:{type:"array",value:"*"},filter_operator:{type:"enum",values:{"==":{},"!=":{},">":{},">=":{},"<":{},"<=":{},in:{},"!in":{},all:{},any:{},none:{},has:{},"!has":{}}},geometry_type:{type:"enum",values:{Point:{},LineString:{},Polygon:{}}},function:{expression:{type:"expression"},stops:{type:"array",value:"function_stop"},base:{type:"number",default:1,minimum:0},property:{type:"string",default:"$zoom"},type:{type:"enum",values:{identity:{},exponential:{},interval:{},categorical:{}},default:"exponential"},colorSpace:{type:"enum",values:{rgb:{},lab:{},hcl:{}},default:"rgb"},default:{type:"*",required:!1}},function_stop:{type:"array",minimum:0,maximum:24,value:["number","color"],length:2},expression:{type:"array",value:"*",minimum:1},light:{anchor:{type:"enum",default:"viewport",values:{map:{},viewport:{}},"property-type":"data-constant",transition:!1,expression:{interpolated:!1,parameters:["zoom"]}},position:{type:"array",default:[1.15,210,30],length:3,value:"number","property-type":"data-constant",transition:!0,expression:{interpolated:!0,parameters:["zoom"]}},color:{type:"color","property-type":"data-constant",default:"#ffffff",expression:{interpolated:!0,parameters:["zoom"]},transition:!0},intensity:{type:"number","property-type":"data-constant",default:.5,minimum:0,maximum:1,expression:{interpolated:!0,parameters:["zoom"]},transition:!0}},sky:{"sky-color":{type:"color","property-type":"data-constant",default:"#88C6FC",expression:{interpolated:!0,parameters:["zoom"]},transition:!0},"horizon-color":{type:"color","property-type":"data-constant",default:"#ffffff",expression:{interpolated:!0,parameters:["zoom"]},transition:!0},"fog-color":{type:"color","property-type":"data-constant",default:"#ffffff",expression:{interpolated:!0,parameters:["zoom"]},transition:!0},"fog-ground-blend":{type:"number","property-type":"data-constant",default:.5,minimum:0,maximum:1,expression:{interpolated:!0,parameters:["zoom"]},transition:!0},"horizon-fog-blend":{type:"number","property-type":"data-constant",default:.8,minimum:0,maximum:1,expression:{interpolated:!0,parameters:["zoom"]},transition:!0},"sky-horizon-blend":{type:"number","property-type":"data-constant",default:.8,minimum:0,maximum:1,expression:{interpolated:!0,parameters:["zoom"]},transition:!0},"atmosphere-blend":{type:"number","property-type":"data-constant",default:.8,minimum:0,maximum:1,expression:{interpolated:!0,parameters:["zoom"]},transition:!0}},terrain:{source:{type:"string",required:!0},exaggeration:{type:"number",minimum:0,default:1}},projection:{type:{type:"projectionDefinition",default:"mercator","property-type":"data-constant",transition:!1,expression:{interpolated:!0,parameters:["zoom"]}}},paint:["paint_fill","paint_line","paint_circle","paint_heatmap","paint_fill-extrusion","paint_symbol","paint_raster","paint_hillshade","paint_color-relief","paint_background"],paint_fill:{"fill-antialias":{type:"boolean",default:!0,expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"fill-opacity":{type:"number",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"fill-color":{type:"color",default:"#000000",transition:!0,requires:[{"!":"fill-pattern"}],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"fill-outline-color":{type:"color",transition:!0,requires:[{"!":"fill-pattern"},{"fill-antialias":!0}],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"fill-translate":{type:"array",value:"number",length:2,default:[0,0],transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"fill-translate-anchor":{type:"enum",values:{map:{},viewport:{}},default:"map",requires:["fill-translate"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"fill-pattern":{type:"resolvedImage",transition:!0,expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"cross-faded-data-driven"}},"paint_fill-extrusion":{"fill-extrusion-opacity":{type:"number",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"fill-extrusion-color":{type:"color",default:"#000000",transition:!0,requires:[{"!":"fill-extrusion-pattern"}],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"fill-extrusion-translate":{type:"array",value:"number",length:2,default:[0,0],transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"fill-extrusion-translate-anchor":{type:"enum",values:{map:{},viewport:{}},default:"map",requires:["fill-extrusion-translate"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"fill-extrusion-pattern":{type:"resolvedImage",transition:!0,expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"cross-faded-data-driven"},"fill-extrusion-height":{type:"number",default:0,minimum:0,units:"meters",transition:!0,expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"fill-extrusion-base":{type:"number",default:0,minimum:0,units:"meters",transition:!0,requires:["fill-extrusion-height"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"fill-extrusion-vertical-gradient":{type:"boolean",default:!0,transition:!1,expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"}},paint_line:{"line-opacity":{type:"number",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"line-color":{type:"color",default:"#000000",transition:!0,requires:[{"!":"line-pattern"}],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"line-translate":{type:"array",value:"number",length:2,default:[0,0],transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"line-translate-anchor":{type:"enum",values:{map:{},viewport:{}},default:"map",requires:["line-translate"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"line-width":{type:"number",default:1,minimum:0,transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"line-gap-width":{type:"number",default:0,minimum:0,transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"line-offset":{type:"number",default:0,transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"line-blur":{type:"number",default:0,minimum:0,transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"line-dasharray":{type:"array",value:"number",minimum:0,transition:!0,units:"line widths",requires:[{"!":"line-pattern"}],expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"cross-faded-data-driven"},"line-pattern":{type:"resolvedImage",transition:!0,expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"cross-faded-data-driven"},"line-gradient":{type:"color",transition:!1,requires:[{"!":"line-dasharray"},{"!":"line-pattern"},{source:"geojson",has:{lineMetrics:!0}}],expression:{interpolated:!0,parameters:["line-progress"]},"property-type":"color-ramp"}},paint_circle:{"circle-radius":{type:"number",default:5,minimum:0,transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"circle-color":{type:"color",default:"#000000",transition:!0,expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"circle-blur":{type:"number",default:0,transition:!0,expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"circle-opacity":{type:"number",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"circle-translate":{type:"array",value:"number",length:2,default:[0,0],transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"circle-translate-anchor":{type:"enum",values:{map:{},viewport:{}},default:"map",requires:["circle-translate"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"circle-pitch-scale":{type:"enum",values:{map:{},viewport:{}},default:"map",expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"circle-pitch-alignment":{type:"enum",values:{map:{},viewport:{}},default:"viewport",expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"circle-stroke-width":{type:"number",default:0,minimum:0,transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"circle-stroke-color":{type:"color",default:"#000000",transition:!0,expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"circle-stroke-opacity":{type:"number",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"}},paint_heatmap:{"heatmap-radius":{type:"number",default:30,minimum:1,transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"heatmap-weight":{type:"number",default:1,minimum:0,transition:!1,expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"heatmap-intensity":{type:"number",default:1,minimum:0,transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"heatmap-color":{type:"color",default:["interpolate",["linear"],["heatmap-density"],0,"rgba(0, 0, 255, 0)",.1,"royalblue",.3,"cyan",.5,"lime",.7,"yellow",1,"red"],transition:!1,expression:{interpolated:!0,parameters:["heatmap-density"]},"property-type":"color-ramp"},"heatmap-opacity":{type:"number",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"}},paint_symbol:{"icon-opacity":{type:"number",default:1,minimum:0,maximum:1,transition:!0,requires:["icon-image"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"icon-color":{type:"color",default:"#000000",transition:!0,requires:["icon-image"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"icon-halo-color":{type:"color",default:"rgba(0, 0, 0, 0)",transition:!0,requires:["icon-image"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"icon-halo-width":{type:"number",default:0,minimum:0,transition:!0,units:"pixels",requires:["icon-image"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"icon-halo-blur":{type:"number",default:0,minimum:0,transition:!0,units:"pixels",requires:["icon-image"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"icon-translate":{type:"array",value:"number",length:2,default:[0,0],transition:!0,units:"pixels",requires:["icon-image"],expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"icon-translate-anchor":{type:"enum",values:{map:{},viewport:{}},default:"map",requires:["icon-image","icon-translate"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"text-opacity":{type:"number",default:1,minimum:0,maximum:1,transition:!0,requires:["text-field"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"text-color":{type:"color",default:"#000000",transition:!0,overridable:!0,requires:["text-field"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"text-halo-color":{type:"color",default:"rgba(0, 0, 0, 0)",transition:!0,requires:["text-field"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"text-halo-width":{type:"number",default:0,minimum:0,transition:!0,units:"pixels",requires:["text-field"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"text-halo-blur":{type:"number",default:0,minimum:0,transition:!0,units:"pixels",requires:["text-field"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"text-translate":{type:"array",value:"number",length:2,default:[0,0],transition:!0,units:"pixels",requires:["text-field"],expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"text-translate-anchor":{type:"enum",values:{map:{},viewport:{}},default:"map",requires:["text-field","text-translate"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"}},paint_raster:{"raster-opacity":{type:"number",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"raster-hue-rotate":{type:"number",default:0,period:360,transition:!0,units:"degrees",expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"raster-brightness-min":{type:"number",default:0,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"raster-brightness-max":{type:"number",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"raster-saturation":{type:"number",default:0,minimum:-1,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"raster-contrast":{type:"number",default:0,minimum:-1,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"raster-resampling":{type:"enum",values:{linear:{},nearest:{}},default:"linear",expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"raster-fade-duration":{type:"number",default:300,minimum:0,transition:!1,units:"milliseconds",expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"}},paint_hillshade:{"hillshade-illumination-direction":{type:"numberArray",default:335,minimum:0,maximum:359,transition:!1,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"hillshade-illumination-altitude":{type:"numberArray",default:45,minimum:0,maximum:90,transition:!1,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"hillshade-illumination-anchor":{type:"enum",values:{map:{},viewport:{}},default:"viewport",expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"hillshade-exaggeration":{type:"number",default:.5,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"hillshade-shadow-color":{type:"colorArray",default:"#000000",transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"hillshade-highlight-color":{type:"colorArray",default:"#FFFFFF",transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"hillshade-accent-color":{type:"color",default:"#000000",transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"hillshade-method":{type:"enum",values:{standard:{},basic:{},combined:{},igor:{},multidirectional:{}},default:"standard",expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"}},"paint_color-relief":{"color-relief-opacity":{type:"number",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"color-relief-color":{type:"color",transition:!1,expression:{interpolated:!0,parameters:["elevation"]},"property-type":"color-ramp"}},paint_background:{"background-color":{type:"color",default:"#000000",transition:!0,requires:[{"!":"background-pattern"}],expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"background-pattern":{type:"resolvedImage",transition:!0,expression:{interpolated:!1,parameters:["zoom"]},"property-type":"cross-faded"},"background-opacity":{type:"number",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"}},transition:{duration:{type:"number",default:300,minimum:0,units:"milliseconds"},delay:{type:"number",default:0,minimum:0,units:"milliseconds"}},"property-type":{"data-driven":{type:"property-type"},"cross-faded":{type:"property-type"},"cross-faded-data-driven":{type:"property-type"},"color-ramp":{type:"property-type"},"data-constant":{type:"property-type"},constant:{type:"property-type"}},promoteId:{"*":{type:"string"}}};let Us=["type","source","source-layer","minzoom","maxzoom","filter","layout"];function ns(d,a){let h={};for(let A in d)A!=="ref"&&(h[A]=d[A]);return Us.forEach(A=>{A in a&&(h[A]=a[A])}),h}function Be(d,a){if(Array.isArray(d)){if(!Array.isArray(a)||d.length!==a.length)return!1;for(let h=0;h`:d.itemType.kind==="value"?"array":`array<${a}>`}return d.kind}let Ds=[si,Or,fi,pr,Di,Ii,po,Mi,uo(Ni),Ls,No,co,wo,Al];function ho(d,a){if(a.kind==="error")return null;if(d.kind==="array"){if(a.kind==="array"&&(a.N===0&&a.itemType.kind==="value"||!ho(d.itemType,a.itemType))&&(typeof d.N!="number"||d.N===a.N))return null}else{if(d.kind===a.kind)return null;if(d.kind==="value"){for(let h of Ds)if(!ho(h,a))return null}}return`Expected ${Qn(d)} but found ${Qn(a)} instead.`}function cs(d,a){return a.some(h=>h.kind===d.kind)}function _l(d,a){return a.some(h=>h==="null"?d===null:h==="array"?Array.isArray(d):h==="object"?d&&!Array.isArray(d)&&typeof d=="object":h===typeof d)}function zc(d,a){return d.kind==="array"&&a.kind==="array"?d.itemType.kind===a.itemType.kind&&typeof d.N=="number":d.kind===a.kind}let yl=.96422,Ya=.82521,md=4/29,os=6/29,ca=3*os*os,mf=os*os*os,Ll=Math.PI/180,Dl=180/Math.PI;function eu(d){return(d%=360)<0&&(d+=360),d}function ua([d,a,h,A]){let C,D,O=Uc((.2225045*(d=Tc(d))+.7168786*(a=Tc(a))+.0606169*(h=Tc(h)))/1);d===a&&a===h?C=D=O:(C=Uc((.4360747*d+.3850649*a+.1430804*h)/yl),D=Uc((.0139322*d+.0971045*a+.7141733*h)/Ya));let H=116*O-16;return[H<0?0:H,500*(C-O),200*(O-D),A]}function Tc(d){return d<=.04045?d/12.92:Math.pow((d+.055)/1.055,2.4)}function Uc(d){return d>mf?Math.pow(d,1/3):d/ca+md}function pm([d,a,h,A]){let C=(d+16)/116,D=isNaN(a)?C:C+a/500,O=isNaN(h)?C:C-h/200;return C=1*Iu(C),D=yl*Iu(D),O=Ya*Iu(O),[pu(3.1338561*D-1.6168667*C-.4906146*O),pu(-.9787684*D+1.9161415*C+.033454*O),pu(.0719453*D-.2289914*C+1.4052427*O),A]}function pu(d){return(d=d<=.00304?12.92*d:1.055*Math.pow(d,1/2.4)-.055)<0?0:d>1?1:d}function Iu(d){return d>os?d*d*d:ca*(d-md)}let Vh=Object.hasOwn||function(d,a){return Object.prototype.hasOwnProperty.call(d,a)};function Ma(d,a){return Vh(d,a)?d[a]:void 0}function Mu(d){return parseInt(d.padEnd(2,d),16)/255}function Sc(d,a){return pc(a?d/100:d,0,1)}function pc(d,a,h){return Math.min(Math.max(a,d),h)}function gf(d){return!d.some(Number.isNaN)}let gd={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]};function jh(d,a,h){return d+h*(a-d)}function Hh(d,a,h){return d.map((A,C)=>jh(A,a[C],h))}class Io{constructor(a,h,A,C=1,D=!0){this.r=a,this.g=h,this.b=A,this.a=C,D||(this.r*=C,this.g*=C,this.b*=C,C||this.overwriteGetter("rgb",[a,h,A,C]))}static parse(a){if(a instanceof Io)return a;if(typeof a!="string")return;let h=function(A){if((A=A.toLowerCase().trim())==="transparent")return[0,0,0,0];let C=Ma(gd,A);if(C){let[O,H,Z]=C;return[O/255,H/255,Z/255,1]}if(A.startsWith("#")&&/^#(?:[0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/.test(A)){let O=A.length<6?1:2,H=1;return[Mu(A.slice(H,H+=O)),Mu(A.slice(H,H+=O)),Mu(A.slice(H,H+=O)),Mu(A.slice(H,H+O)||"ff")]}if(A.startsWith("rgb")){let O=A.match(/^rgba?\(\s*([\de.+-]+)(%)?(?:\s+|\s*(,)\s*)([\de.+-]+)(%)?(?:\s+|\s*(,)\s*)([\de.+-]+)(%)?(?:\s*([,\/])\s*([\de.+-]+)(%)?)?\s*\)$/);if(O){let[H,Z,re,ce,de,we,Ee,De,ke,qe,st,kt]=O,pt=[ce||" ",Ee||" ",qe].join("");if(pt===" "||pt===" /"||pt===",,"||pt===",,,"){let _t=[re,we,ke].join(""),Ht=_t==="%%%"?100:_t===""?255:0;if(Ht){let Qt=[pc(+Z/Ht,0,1),pc(+de/Ht,0,1),pc(+De/Ht,0,1),st?Sc(+st,kt):1];if(gf(Qt))return Qt}}return}}let D=A.match(/^hsla?\(\s*([\de.+-]+)(?:deg)?(?:\s+|\s*(,)\s*)([\de.+-]+)%(?:\s+|\s*(,)\s*)([\de.+-]+)%(?:\s*([,\/])\s*([\de.+-]+)(%)?)?\s*\)$/);if(D){let[O,H,Z,re,ce,de,we,Ee,De]=D,ke=[Z||" ",ce||" ",we].join("");if(ke===" "||ke===" /"||ke===",,"||ke===",,,"){let qe=[+H,pc(+re,0,100),pc(+de,0,100),Ee?Sc(+Ee,De):1];if(gf(qe))return function([st,kt,pt,_t]){function Ht(Qt){let Ir=(Qt+st/30)%12,oi=kt*Math.min(pt,1-pt);return pt-oi*Math.max(-1,Math.min(Ir-3,9-Ir,1))}return st=eu(st),kt/=100,pt/=100,[Ht(0),Ht(8),Ht(4),_t]}(qe)}}}(a);return h?new Io(...h,!1):void 0}get rgb(){let{r:a,g:h,b:A,a:C}=this,D=C||1/0;return this.overwriteGetter("rgb",[a/D,h/D,A/D,C])}get hcl(){return this.overwriteGetter("hcl",function(a){let[h,A,C,D]=ua(a),O=Math.sqrt(A*A+C*C);return[Math.round(1e4*O)?eu(Math.atan2(C,A)*Dl):NaN,O,h,D]}(this.rgb))}get lab(){return this.overwriteGetter("lab",ua(this.rgb))}overwriteGetter(a,h){return Object.defineProperty(this,a,{value:h}),h}toString(){let[a,h,A,C]=this.rgb;return`rgba(${[a,h,A].map(D=>Math.round(255*D)).join(",")},${C})`}static interpolate(a,h,A,C="rgb"){switch(C){case"rgb":{let[D,O,H,Z]=Hh(a.rgb,h.rgb,A);return new Io(D,O,H,Z,!1)}case"hcl":{let[D,O,H,Z]=a.hcl,[re,ce,de,we]=h.hcl,Ee,De;if(isNaN(D)||isNaN(re))isNaN(D)?isNaN(re)?Ee=NaN:(Ee=re,H!==1&&H!==0||(De=ce)):(Ee=D,de!==1&&de!==0||(De=O));else{let pt=re-D;re>D&&pt>180?pt-=360:re180&&(pt+=360),Ee=D+A*pt}let[ke,qe,st,kt]=function([pt,_t,Ht,Qt]){return pt=isNaN(pt)?0:pt*Ll,pm([Ht,Math.cos(pt)*_t,Math.sin(pt)*_t,Qt])}([Ee,De??jh(O,ce,A),jh(H,de,A),jh(Z,we,A)]);return new Io(ke,qe,st,kt,!1)}case"lab":{let[D,O,H,Z]=pm(Hh(a.lab,h.lab,A));return new Io(D,O,H,Z,!1)}}}}Io.black=new Io(0,0,0,1),Io.white=new Io(1,1,1,1),Io.transparent=new Io(0,0,0,0),Io.red=new Io(1,0,0,1);class Sp{constructor(a,h,A){this.sensitivity=a?h?"variant":"case":h?"accent":"base",this.locale=A,this.collator=new Intl.Collator(this.locale?this.locale:[],{sensitivity:this.sensitivity,usage:"search"})}compare(a,h){return this.collator.compare(a,h)}resolvedLocale(){return new Intl.Collator(this.locale?this.locale:[]).resolvedOptions().locale}}let eg=["bottom","center","top"];class Ep{constructor(a,h,A,C,D,O){this.text=a,this.image=h,this.scale=A,this.fontStack=C,this.textColor=D,this.verticalAlign=O}}class Ql{constructor(a){this.sections=a}static fromString(a){return new Ql([new Ep(a,null,null,null,null,null)])}isEmpty(){return this.sections.length===0||!this.sections.some(a=>a.text.length!==0||a.image&&a.image.name.length!==0)}static factory(a){return a instanceof Ql?a:Ql.fromString(a)}toString(){return this.sections.length===0?"":this.sections.map(a=>a.text).join("")}}class Jl{constructor(a){this.values=a.slice()}static parse(a){if(a instanceof Jl)return a;if(typeof a=="number")return new Jl([a,a,a,a]);if(Array.isArray(a)&&!(a.length<1||a.length>4)){for(let h of a)if(typeof h!="number")return;switch(a.length){case 1:a=[a[0],a[0],a[0],a[0]];break;case 2:a=[a[0],a[1],a[0],a[1]];break;case 3:a=[a[0],a[1],a[2],a[1]]}return new Jl(a)}}toString(){return JSON.stringify(this.values)}static interpolate(a,h,A){return new Jl(Hh(a.values,h.values,A))}}class _a{constructor(a){this.values=a.slice()}static parse(a){if(a instanceof _a)return a;if(typeof a=="number")return new _a([a]);if(Array.isArray(a)){for(let h of a)if(typeof h!="number")return;return new _a(a)}}toString(){return JSON.stringify(this.values)}static interpolate(a,h,A){return new _a(Hh(a.values,h.values,A))}}class Zn{constructor(a){this.values=a.slice()}static parse(a){if(a instanceof Zn)return a;if(typeof a=="string"){let A=Io.parse(a);return A?new Zn([A]):void 0}if(!Array.isArray(a))return;let h=[];for(let A of a){if(typeof A!="string")return;let C=Io.parse(A);if(!C)return;h.push(C)}return new Zn(h)}toString(){return JSON.stringify(this.values)}static interpolate(a,h,A,C="rgb"){let D=[];if(a.values.length!=h.values.length)throw new Error(`colorArray: Arrays have mismatched length (${a.values.length} vs. ${h.values.length}), cannot interpolate.`);for(let O=0;O=0&&d<=255&&typeof a=="number"&&a>=0&&a<=255&&typeof h=="number"&&h>=0&&h<=255?A===void 0||typeof A=="number"&&A>=0&&A<=1?null:`Invalid rgba value [${[d,a,h,A].join(", ")}]: 'a' must be between 0 and 1.`:`Invalid rgba value [${(typeof A=="number"?[d,a,h,A]:[d,a,h]).join(", ")}]: 'r', 'g', and 'b' must be between 0 and 255.`}function tu(d){if(d===null||typeof d=="string"||typeof d=="boolean"||typeof d=="number"||d instanceof vl||d instanceof Io||d instanceof Sp||d instanceof Ql||d instanceof Jl||d instanceof _a||d instanceof Zn||d instanceof sl||d instanceof Ol)return!0;if(Array.isArray(d)){for(let a of d)if(!tu(a))return!1;return!0}if(typeof d=="object"){for(let a in d)if(!tu(d[a]))return!1;return!0}return!1}function La(d){if(d===null)return si;if(typeof d=="string")return fi;if(typeof d=="boolean")return pr;if(typeof d=="number")return Or;if(d instanceof Io)return Di;if(d instanceof vl)return Ii;if(d instanceof Sp)return zi;if(d instanceof Ql)return po;if(d instanceof Jl)return Ls;if(d instanceof _a)return No;if(d instanceof Zn)return co;if(d instanceof sl)return Al;if(d instanceof Ol)return wo;if(Array.isArray(d)){let a=d.length,h;for(let A of d){let C=La(A);if(h){if(h===C)continue;h=Ni;break}h=C}return uo(h||Ni,a)}return Mi}function xl(d){let a=typeof d;return d===null?"":a==="string"||a==="number"||a==="boolean"?String(d):d instanceof Io||d instanceof vl||d instanceof Ql||d instanceof Jl||d instanceof _a||d instanceof Zn||d instanceof sl||d instanceof Ol?d.toString():JSON.stringify(d)}class Ws{constructor(a,h){this.type=a,this.value=h}static parse(a,h){if(a.length!==2)return h.error(`'literal' expression requires exactly one argument, but found ${a.length-1} instead.`);if(!tu(a[1]))return h.error("invalid value");let A=a[1],C=La(A),D=h.expectedType;return C.kind!=="array"||C.N!==0||!D||D.kind!=="array"||typeof D.N=="number"&&D.N!==0||(C=D),new Ws(C,A)}evaluate(){return this.value}eachChild(){}outputDefined(){return!0}}let Gh={string:fi,number:Or,boolean:pr,object:Mi};class Ec{constructor(a,h){this.type=a,this.args=h}static parse(a,h){if(a.length<2)return h.error("Expected at least one argument.");let A,C=1,D=a[0];if(D==="array"){let H,Z;if(a.length>2){let re=a[1];if(typeof re!="string"||!(re in Gh)||re==="object")return h.error('The item type argument of "array" must be one of string, number, boolean',1);H=Gh[re],C++}else H=Ni;if(a.length>3){if(a[2]!==null&&(typeof a[2]!="number"||a[2]<0||a[2]!==Math.floor(a[2])))return h.error('The length argument to "array" must be a positive integer literal',2);Z=a[2],C++}A=uo(H,Z)}else{if(!Gh[D])throw new Error(`Types doesn't contain name = ${D}`);A=Gh[D]}let O=[];for(;Ca.outputDefined())}}let Gf={"to-boolean":pr,"to-color":Di,"to-number":Or,"to-string":fi};class Wh{constructor(a,h){this.type=a,this.args=h}static parse(a,h){if(a.length<2)return h.error("Expected at least one argument.");let A=a[0];if(!Gf[A])throw new Error(`Can't parse ${A} as it is not part of the known types`);if((A==="to-boolean"||A==="to-string")&&a.length!==2)return h.error("Expected one argument.");let C=Gf[A],D=[];for(let O=1;O4?`Invalid rgba value ${JSON.stringify(h)}: expected an array containing either three or four numeric values.`:Pu(h[0],h[1],h[2],h[3]),!A))return new Io(h[0]/255,h[1]/255,h[2]/255,h[3])}throw new Gs(A||`Could not parse color from value '${typeof h=="string"?h:JSON.stringify(h)}'`)}case"padding":{let h;for(let A of this.args){h=A.evaluate(a);let C=Jl.parse(h);if(C)return C}throw new Gs(`Could not parse padding from value '${typeof h=="string"?h:JSON.stringify(h)}'`)}case"numberArray":{let h;for(let A of this.args){h=A.evaluate(a);let C=_a.parse(h);if(C)return C}throw new Gs(`Could not parse numberArray from value '${typeof h=="string"?h:JSON.stringify(h)}'`)}case"colorArray":{let h;for(let A of this.args){h=A.evaluate(a);let C=Zn.parse(h);if(C)return C}throw new Gs(`Could not parse colorArray from value '${typeof h=="string"?h:JSON.stringify(h)}'`)}case"variableAnchorOffsetCollection":{let h;for(let A of this.args){h=A.evaluate(a);let C=sl.parse(h);if(C)return C}throw new Gs(`Could not parse variableAnchorOffsetCollection from value '${typeof h=="string"?h:JSON.stringify(h)}'`)}case"number":{let h=null;for(let A of this.args){if(h=A.evaluate(a),h===null)return 0;let C=Number(h);if(!isNaN(C))return C}throw new Gs(`Could not convert ${JSON.stringify(h)} to number.`)}case"formatted":return Ql.fromString(xl(this.args[0].evaluate(a)));case"resolvedImage":return Ol.fromString(xl(this.args[0].evaluate(a)));case"projectionDefinition":return this.args[0].evaluate(a);default:return xl(this.args[0].evaluate(a))}}eachChild(a){this.args.forEach(a)}outputDefined(){return this.args.every(a=>a.outputDefined())}}let Hd=["Unknown","Point","LineString","Polygon"];class Cp{constructor(){this.globals=null,this.feature=null,this.featureState=null,this.formattedSection=null,this._parseColorCache=new Map,this.availableImages=null,this.canonical=null}id(){return this.feature&&"id"in this.feature?this.feature.id:null}geometryType(){return this.feature?typeof this.feature.type=="number"?Hd[this.feature.type]:this.feature.type:null}geometry(){return this.feature&&"geometry"in this.feature?this.feature.geometry:null}canonicalID(){return this.canonical}properties(){return this.feature&&this.feature.properties||{}}parseColor(a){let h=this._parseColorCache.get(a);return h||(h=Io.parse(a),this._parseColorCache.set(a,h)),h}}class Af{constructor(a,h,A=[],C,D=new Hr,O=[]){this.registry=a,this.path=A,this.key=A.map(H=>`[${H}]`).join(""),this.scope=D,this.errors=O,this.expectedType=C,this._isConstant=h}parse(a,h,A,C,D={}){return h?this.concat(h,A,C)._parse(a,D):this._parse(a,D)}_parse(a,h){function A(C,D,O){return O==="assert"?new Ec(D,[C]):O==="coerce"?new Wh(D,[C]):C}if(a!==null&&typeof a!="string"&&typeof a!="boolean"&&typeof a!="number"||(a=["literal",a]),Array.isArray(a)){if(a.length===0)return this.error('Expected an array with at least one element. If you wanted a literal array, use ["literal", []].');let C=a[0];if(typeof C!="string")return this.error(`Expression name must be a string, but found ${typeof C} instead. If you wanted a literal array, use ["literal", [...]].`,0),null;let D=this.registry[C];if(D){let O=D.parse(a,this);if(!O)return null;if(this.expectedType){let H=this.expectedType,Z=O.type;if(H.kind!=="string"&&H.kind!=="number"&&H.kind!=="boolean"&&H.kind!=="object"&&H.kind!=="array"||Z.kind!=="value"){if(H.kind==="projectionDefinition"&&["string","array"].includes(Z.kind)||["color","formatted","resolvedImage"].includes(H.kind)&&["value","string"].includes(Z.kind)||["padding","numberArray"].includes(H.kind)&&["value","number","array"].includes(Z.kind)||H.kind==="colorArray"&&["value","string","array"].includes(Z.kind)||H.kind==="variableAnchorOffsetCollection"&&["value","array"].includes(Z.kind))O=A(O,H,h.typeAnnotation||"coerce");else if(this.checkSubtype(H,Z))return null}else O=A(O,H,h.typeAnnotation||"assert")}if(!(O instanceof Ws)&&O.type.kind!=="resolvedImage"&&this._isConstant(O)){let H=new Cp;try{O=new Ws(O.type,O.evaluate(H))}catch(Z){return this.error(Z.message),null}}return O}return this.error(`Unknown expression "${C}". If you wanted a literal array, use ["literal", [...]].`,0)}return this.error(a===void 0?"'undefined' value invalid. Use null instead.":typeof a=="object"?'Bare objects invalid. Use ["literal", {...}] instead.':`Expected an array, but found ${typeof a} instead.`)}concat(a,h,A){let C=typeof a=="number"?this.path.concat(a):this.path,D=A?this.scope.concat(A):this.scope;return new Af(this.registry,this._isConstant,C,h||null,D,this.errors)}error(a,...h){let A=`${this.key}${h.map(C=>`[${C}]`).join("")}`;this.errors.push(new ui(A,a))}checkSubtype(a,h){let A=ho(a,h);return A&&this.error(A),A}}class ia{constructor(a,h){this.type=h.type,this.bindings=[].concat(a),this.result=h}evaluate(a){return this.result.evaluate(a)}eachChild(a){for(let h of this.bindings)a(h[1]);a(this.result)}static parse(a,h){if(a.length<4)return h.error(`Expected at least 3 arguments, but found ${a.length-1} instead.`);let A=[];for(let D=1;D=A.length)throw new Gs(`Array index out of bounds: ${h} > ${A.length-1}.`);if(h!==Math.floor(h))throw new Gs(`Array index must be an integer, but found ${h} instead.`);return A[h]}eachChild(a){a(this.index),a(this.input)}outputDefined(){return!1}}class Ao{constructor(a,h){this.type=pr,this.needle=a,this.haystack=h}static parse(a,h){if(a.length!==3)return h.error(`Expected 2 arguments, but found ${a.length-1} instead.`);let A=h.parse(a[1],1,Ni),C=h.parse(a[2],2,Ni);return A&&C?cs(A.type,[pr,fi,Or,si,Ni])?new Ao(A,C):h.error(`Expected first argument to be of type boolean, string, number or null, but found ${Qn(A.type)} instead`):null}evaluate(a){let h=this.needle.evaluate(a),A=this.haystack.evaluate(a);if(!A)return!1;if(!_l(h,["boolean","string","number","null"]))throw new Gs(`Expected first argument to be of type boolean, string, number or null, but found ${Qn(La(h))} instead.`);if(!_l(A,["string","array"]))throw new Gs(`Expected second argument to be of type array or string, but found ${Qn(La(A))} instead.`);return A.indexOf(h)>=0}eachChild(a){a(this.needle),a(this.haystack)}outputDefined(){return!0}}class qh{constructor(a,h,A){this.type=Or,this.needle=a,this.haystack=h,this.fromIndex=A}static parse(a,h){if(a.length<=2||a.length>=5)return h.error(`Expected 2 or 3 arguments, but found ${a.length-1} instead.`);let A=h.parse(a[1],1,Ni),C=h.parse(a[2],2,Ni);if(!A||!C)return null;if(!cs(A.type,[pr,fi,Or,si,Ni]))return h.error(`Expected first argument to be of type boolean, string, number or null, but found ${Qn(A.type)} instead`);if(a.length===4){let D=h.parse(a[3],3,Or);return D?new qh(A,C,D):null}return new qh(A,C)}evaluate(a){let h=this.needle.evaluate(a),A=this.haystack.evaluate(a);if(!_l(h,["boolean","string","number","null"]))throw new Gs(`Expected first argument to be of type boolean, string, number or null, but found ${Qn(La(h))} instead.`);let C;if(this.fromIndex&&(C=this.fromIndex.evaluate(a)),_l(A,["string"])){let D=A.indexOf(h,C);return D===-1?-1:[...A.slice(0,D)].length}if(_l(A,["array"]))return A.indexOf(h,C);throw new Gs(`Expected second argument to be of type array or string, but found ${Qn(La(A))} instead.`)}eachChild(a){a(this.needle),a(this.haystack),this.fromIndex&&a(this.fromIndex)}outputDefined(){return!1}}class us{constructor(a,h,A,C,D,O){this.inputType=a,this.type=h,this.input=A,this.cases=C,this.outputs=D,this.otherwise=O}static parse(a,h){if(a.length<5)return h.error(`Expected at least 4 arguments, but found only ${a.length-1}.`);if(a.length%2!=1)return h.error("Expected an even number of arguments.");let A,C;h.expectedType&&h.expectedType.kind!=="value"&&(C=h.expectedType);let D={},O=[];for(let re=2;reNumber.MAX_SAFE_INTEGER)return we.error(`Branch labels must be integers no larger than ${Number.MAX_SAFE_INTEGER}.`);if(typeof De=="number"&&Math.floor(De)!==De)return we.error("Numeric branch labels must be integer values.");if(A){if(we.checkSubtype(A,La(De)))return null}else A=La(De);if(D[String(De)]!==void 0)return we.error("Branch labels must be unique.");D[String(De)]=O.length}let Ee=h.parse(de,re,C);if(!Ee)return null;C=C||Ee.type,O.push(Ee)}let H=h.parse(a[1],1,Ni);if(!H)return null;let Z=h.parse(a[a.length-1],a.length-1,C);return Z?H.type.kind!=="value"&&h.concat(1).checkSubtype(A,H.type)?null:new us(A,C,H,D,O,Z):null}evaluate(a){let h=this.input.evaluate(a);return(La(h)===this.inputType&&this.outputs[this.cases[h]]||this.otherwise).evaluate(a)}eachChild(a){a(this.input),this.outputs.forEach(a),a(this.otherwise)}outputDefined(){return this.outputs.every(a=>a.outputDefined())&&this.otherwise.outputDefined()}}class Gd{constructor(a,h,A){this.type=a,this.branches=h,this.otherwise=A}static parse(a,h){if(a.length<4)return h.error(`Expected at least 3 arguments, but found only ${a.length-1}.`);if(a.length%2!=0)return h.error("Expected an odd number of arguments.");let A;h.expectedType&&h.expectedType.kind!=="value"&&(A=h.expectedType);let C=[];for(let O=1;Oh.outputDefined())&&this.otherwise.outputDefined()}}class q{constructor(a,h,A,C){this.type=a,this.input=h,this.beginIndex=A,this.endIndex=C}static parse(a,h){if(a.length<=2||a.length>=5)return h.error(`Expected 2 or 3 arguments, but found ${a.length-1} instead.`);let A=h.parse(a[1],1,Ni),C=h.parse(a[2],2,Or);if(!A||!C)return null;if(!cs(A.type,[uo(Ni),fi,Ni]))return h.error(`Expected first argument to be of type array or string, but found ${Qn(A.type)} instead`);if(a.length===4){let D=h.parse(a[3],3,Or);return D?new q(A.type,A,C,D):null}return new q(A.type,A,C)}evaluate(a){let h=this.input.evaluate(a),A=this.beginIndex.evaluate(a),C;if(this.endIndex&&(C=this.endIndex.evaluate(a)),_l(h,["string"]))return[...h].slice(A,C).join("");if(_l(h,["array"]))return h.slice(A,C);throw new Gs(`Expected first argument to be of type array or string, but found ${Qn(La(h))} instead.`)}eachChild(a){a(this.input),a(this.beginIndex),this.endIndex&&a(this.endIndex)}outputDefined(){return!1}}function oe(d,a){let h=d.length-1,A,C,D=0,O=h,H=0;for(;D<=O;)if(H=Math.floor((D+O)/2),A=d[H],C=d[H+1],A<=a){if(H===h||aa))throw new Gs("Input is not a number.");O=H-1}return 0}class pe{constructor(a,h,A){this.type=a,this.input=h,this.labels=[],this.outputs=[];for(let[C,D]of A)this.labels.push(C),this.outputs.push(D)}static parse(a,h){if(a.length-1<4)return h.error(`Expected at least 4 arguments, but found only ${a.length-1}.`);if((a.length-1)%2!=0)return h.error("Expected an even number of arguments.");let A=h.parse(a[1],1,Or);if(!A)return null;let C=[],D=null;h.expectedType&&h.expectedType.kind!=="value"&&(D=h.expectedType);for(let O=1;O=H)return h.error('Input/output pairs for "step" expressions must be arranged with input values in strictly ascending order.',re);let de=h.parse(Z,ce,D);if(!de)return null;D=D||de.type,C.push([H,de])}return new pe(D,A,C)}evaluate(a){let h=this.labels,A=this.outputs;if(h.length===1)return A[0].evaluate(a);let C=this.input.evaluate(a);if(C<=h[0])return A[0].evaluate(a);let D=h.length;return C>=h[D-1]?A[D-1].evaluate(a):A[oe(h,C)].evaluate(a)}eachChild(a){a(this.input);for(let h of this.outputs)a(h)}outputDefined(){return this.outputs.every(a=>a.outputDefined())}}function be(d){return d&&d.__esModule&&Object.prototype.hasOwnProperty.call(d,"default")?d.default:d}var He,We,ot=function(){if(We)return He;function d(a,h,A,C){this.cx=3*a,this.bx=3*(A-a)-this.cx,this.ax=1-this.cx-this.bx,this.cy=3*h,this.by=3*(C-h)-this.cy,this.ay=1-this.cy-this.by,this.p1x=a,this.p1y=h,this.p2x=A,this.p2y=C}return We=1,He=d,d.prototype={sampleCurveX:function(a){return((this.ax*a+this.bx)*a+this.cx)*a},sampleCurveY:function(a){return((this.ay*a+this.by)*a+this.cy)*a},sampleCurveDerivativeX:function(a){return(3*this.ax*a+2*this.bx)*a+this.cx},solveCurveX:function(a,h){if(h===void 0&&(h=1e-6),a<0)return 0;if(a>1)return 1;for(var A=a,C=0;C<8;C++){var D=this.sampleCurveX(A)-a;if(Math.abs(D)D?H=A:Z=A,A=.5*(Z-H)+H;return A},solve:function(a,h){return this.sampleCurveY(this.solveCurveX(a,h))}},He}(),rr=be(ot);class Ut{constructor(a,h,A,C,D){this.type=a,this.operator=h,this.interpolation=A,this.input=C,this.labels=[],this.outputs=[];for(let[O,H]of D)this.labels.push(O),this.outputs.push(H)}static interpolationFactor(a,h,A,C){let D=0;if(a.name==="exponential")D=cr(h,a.base,A,C);else if(a.name==="linear")D=cr(h,1,A,C);else if(a.name==="cubic-bezier"){let O=a.controlPoints;D=new rr(O[0],O[1],O[2],O[3]).solve(cr(h,1,A,C))}return D}static parse(a,h){let[A,C,D,...O]=a;if(!Array.isArray(C)||C.length===0)return h.error("Expected an interpolation type expression.",1);if(C[0]==="linear")C={name:"linear"};else if(C[0]==="exponential"){let re=C[1];if(typeof re!="number")return h.error("Exponential interpolation requires a numeric base.",1,1);C={name:"exponential",base:re}}else{if(C[0]!=="cubic-bezier")return h.error(`Unknown interpolation type ${String(C[0])}`,1,0);{let re=C.slice(1);if(re.length!==4||re.some(ce=>typeof ce!="number"||ce<0||ce>1))return h.error("Cubic bezier interpolation requires four numeric arguments with values between 0 and 1.",1);C={name:"cubic-bezier",controlPoints:re}}}if(a.length-1<4)return h.error(`Expected at least 4 arguments, but found only ${a.length-1}.`);if((a.length-1)%2!=0)return h.error("Expected an even number of arguments.");if(D=h.parse(D,2,Or),!D)return null;let H=[],Z=null;A!=="interpolate-hcl"&&A!=="interpolate-lab"||h.expectedType==co?h.expectedType&&h.expectedType.kind!=="value"&&(Z=h.expectedType):Z=Di;for(let re=0;re=ce)return h.error('Input/output pairs for "interpolate" expressions must be arranged with input values in strictly ascending order.',we);let De=h.parse(de,Ee,Z);if(!De)return null;Z=Z||De.type,H.push([ce,De])}return zc(Z,Or)||zc(Z,Ii)||zc(Z,Di)||zc(Z,Ls)||zc(Z,No)||zc(Z,co)||zc(Z,Al)||zc(Z,uo(Or))?new Ut(Z,A,C,D,H):h.error(`Type ${Qn(Z)} is not interpolatable.`)}evaluate(a){let h=this.labels,A=this.outputs;if(h.length===1)return A[0].evaluate(a);let C=this.input.evaluate(a);if(C<=h[0])return A[0].evaluate(a);let D=h.length;if(C>=h[D-1])return A[D-1].evaluate(a);let O=oe(h,C),H=Ut.interpolationFactor(this.interpolation,C,h[O],h[O+1]),Z=A[O].evaluate(a),re=A[O+1].evaluate(a);switch(this.operator){case"interpolate":switch(this.type.kind){case"number":return jh(Z,re,H);case"color":return Io.interpolate(Z,re,H);case"padding":return Jl.interpolate(Z,re,H);case"colorArray":return Zn.interpolate(Z,re,H);case"numberArray":return _a.interpolate(Z,re,H);case"variableAnchorOffsetCollection":return sl.interpolate(Z,re,H);case"array":return Hh(Z,re,H);case"projectionDefinition":return vl.interpolate(Z,re,H)}case"interpolate-hcl":switch(this.type.kind){case"color":return Io.interpolate(Z,re,H,"hcl");case"colorArray":return Zn.interpolate(Z,re,H,"hcl")}case"interpolate-lab":switch(this.type.kind){case"color":return Io.interpolate(Z,re,H,"lab");case"colorArray":return Zn.interpolate(Z,re,H,"lab")}}}eachChild(a){a(this.input);for(let h of this.outputs)a(h)}outputDefined(){return this.outputs.every(a=>a.outputDefined())}}function cr(d,a,h,A){let C=A-h,D=d-h;return C===0?0:a===1?D/C:(Math.pow(a,D)-1)/(Math.pow(a,C)-1)}let Fr={color:Io.interpolate,number:jh,padding:Jl.interpolate,numberArray:_a.interpolate,colorArray:Zn.interpolate,variableAnchorOffsetCollection:sl.interpolate,array:Hh};class li{constructor(a,h){this.type=a,this.args=h}static parse(a,h){if(a.length<2)return h.error("Expected at least one argument.");let A=null,C=h.expectedType;C&&C.kind!=="value"&&(A=C);let D=[];for(let H of a.slice(1)){let Z=h.parse(H,1+D.length,A,void 0,{typeAnnotation:"omit"});if(!Z)return null;A=A||Z.type,D.push(Z)}if(!A)throw new Error("No output type");let O=C&&D.some(H=>ho(C,H.type));return new li(O?Ni:A,D)}evaluate(a){let h,A=null,C=0;for(let D of this.args)if(C++,A=D.evaluate(a),A&&A instanceof Ol&&!A.available&&(h||(h=A.name),A=null,C===this.args.length&&(A=h)),A!==null)break;return A}eachChild(a){this.args.forEach(a)}outputDefined(){return this.args.every(a=>a.outputDefined())}}function vr(d,a){return d==="=="||d==="!="?a.kind==="boolean"||a.kind==="string"||a.kind==="number"||a.kind==="null"||a.kind==="value":a.kind==="string"||a.kind==="number"||a.kind==="value"}function Bi(d,a,h,A){return A.compare(a,h)===0}function gn(d,a,h){let A=d!=="=="&&d!=="!=";return class Fle{constructor(D,O,H){this.type=pr,this.lhs=D,this.rhs=O,this.collator=H,this.hasUntypedArgument=D.type.kind==="value"||O.type.kind==="value"}static parse(D,O){if(D.length!==3&&D.length!==4)return O.error("Expected two or three arguments.");let H=D[0],Z=O.parse(D[1],1,Ni);if(!Z)return null;if(!vr(H,Z.type))return O.concat(1).error(`"${H}" comparisons are not supported for type '${Qn(Z.type)}'.`);let re=O.parse(D[2],2,Ni);if(!re)return null;if(!vr(H,re.type))return O.concat(2).error(`"${H}" comparisons are not supported for type '${Qn(re.type)}'.`);if(Z.type.kind!==re.type.kind&&Z.type.kind!=="value"&&re.type.kind!=="value")return O.error(`Cannot compare types '${Qn(Z.type)}' and '${Qn(re.type)}'.`);A&&(Z.type.kind==="value"&&re.type.kind!=="value"?Z=new Ec(re.type,[Z]):Z.type.kind!=="value"&&re.type.kind==="value"&&(re=new Ec(Z.type,[re])));let ce=null;if(D.length===4){if(Z.type.kind!=="string"&&re.type.kind!=="string"&&Z.type.kind!=="value"&&re.type.kind!=="value")return O.error("Cannot use collator to compare non-string types.");if(ce=O.parse(D[3],3,zi),!ce)return null}return new Fle(Z,re,ce)}evaluate(D){let O=this.lhs.evaluate(D),H=this.rhs.evaluate(D);if(A&&this.hasUntypedArgument){let Z=La(O),re=La(H);if(Z.kind!==re.kind||Z.kind!=="string"&&Z.kind!=="number")throw new Gs(`Expected arguments for "${d}" to be (string, string) or (number, number), but found (${Z.kind}, ${re.kind}) instead.`)}if(this.collator&&!A&&this.hasUntypedArgument){let Z=La(O),re=La(H);if(Z.kind!=="string"||re.kind!=="string")return a(D,O,H)}return this.collator?h(D,O,H,this.collator.evaluate(D)):a(D,O,H)}eachChild(D){D(this.lhs),D(this.rhs),this.collator&&D(this.collator)}outputDefined(){return!0}}}let gs=gn("==",function(d,a,h){return a===h},Bi),Mo=gn("!=",function(d,a,h){return a!==h},function(d,a,h,A){return!Bi(0,a,h,A)}),bl=gn("<",function(d,a,h){return a",function(d,a,h){return a>h},function(d,a,h,A){return A.compare(a,h)>0}),Da=gn("<=",function(d,a,h){return a<=h},function(d,a,h,A){return A.compare(a,h)<=0}),Ka=gn(">=",function(d,a,h){return a>=h},function(d,a,h,A){return A.compare(a,h)>=0});class Yn{constructor(a,h,A){this.type=zi,this.locale=A,this.caseSensitive=a,this.diacriticSensitive=h}static parse(a,h){if(a.length!==2)return h.error("Expected one argument.");let A=a[1];if(typeof A!="object"||Array.isArray(A))return h.error("Collator options argument must be an object.");let C=h.parse(A["case-sensitive"]!==void 0&&A["case-sensitive"],1,pr);if(!C)return null;let D=h.parse(A["diacritic-sensitive"]!==void 0&&A["diacritic-sensitive"],1,pr);if(!D)return null;let O=null;return A.locale&&(O=h.parse(A.locale,1,fi),!O)?null:new Yn(C,D,O)}evaluate(a){return new Sp(this.caseSensitive.evaluate(a),this.diacriticSensitive.evaluate(a),this.locale?this.locale.evaluate(a):null)}eachChild(a){a(this.caseSensitive),a(this.diacriticSensitive),this.locale&&a(this.locale)}outputDefined(){return!1}}class Er{constructor(a,h,A,C,D){this.type=fi,this.number=a,this.locale=h,this.currency=A,this.minFractionDigits=C,this.maxFractionDigits=D}static parse(a,h){if(a.length!==3)return h.error("Expected two arguments.");let A=h.parse(a[1],1,Or);if(!A)return null;let C=a[2];if(typeof C!="object"||Array.isArray(C))return h.error("NumberFormat options argument must be an object.");let D=null;if(C.locale&&(D=h.parse(C.locale,1,fi),!D))return null;let O=null;if(C.currency&&(O=h.parse(C.currency,1,fi),!O))return null;let H=null;if(C["min-fraction-digits"]&&(H=h.parse(C["min-fraction-digits"],1,Or),!H))return null;let Z=null;return C["max-fraction-digits"]&&(Z=h.parse(C["max-fraction-digits"],1,Or),!Z)?null:new Er(A,D,O,H,Z)}evaluate(a){return new Intl.NumberFormat(this.locale?this.locale.evaluate(a):[],{style:this.currency?"currency":"decimal",currency:this.currency?this.currency.evaluate(a):void 0,minimumFractionDigits:this.minFractionDigits?this.minFractionDigits.evaluate(a):void 0,maximumFractionDigits:this.maxFractionDigits?this.maxFractionDigits.evaluate(a):void 0}).format(this.number.evaluate(a))}eachChild(a){a(this.number),this.locale&&a(this.locale),this.currency&&a(this.currency),this.minFractionDigits&&a(this.minFractionDigits),this.maxFractionDigits&&a(this.maxFractionDigits)}outputDefined(){return!1}}class Gr{constructor(a){this.type=po,this.sections=a}static parse(a,h){if(a.length<2)return h.error("Expected at least one argument.");let A=a[1];if(!Array.isArray(A)&&typeof A=="object")return h.error("First argument must be an image or text section.");let C=[],D=!1;for(let O=1;O<=a.length-1;++O){let H=a[O];if(D&&typeof H=="object"&&!Array.isArray(H)){D=!1;let Z=null;if(H["font-scale"]&&(Z=h.parse(H["font-scale"],1,Or),!Z))return null;let re=null;if(H["text-font"]&&(re=h.parse(H["text-font"],1,uo(fi)),!re))return null;let ce=null;if(H["text-color"]&&(ce=h.parse(H["text-color"],1,Di),!ce))return null;let de=null;if(H["vertical-align"]){if(typeof H["vertical-align"]=="string"&&!eg.includes(H["vertical-align"]))return h.error(`'vertical-align' must be one of: 'bottom', 'center', 'top' but found '${H["vertical-align"]}' instead.`);if(de=h.parse(H["vertical-align"],1,fi),!de)return null}let we=C[C.length-1];we.scale=Z,we.font=re,we.textColor=ce,we.verticalAlign=de}else{let Z=h.parse(a[O],1,Ni);if(!Z)return null;let re=Z.type.kind;if(re!=="string"&&re!=="value"&&re!=="null"&&re!=="resolvedImage")return h.error("Formatted text type must be 'string', 'value', 'image' or 'null'.");D=!0,C.push({content:Z,scale:null,font:null,textColor:null,verticalAlign:null})}}return new Gr(C)}evaluate(a){return new Ql(this.sections.map(h=>{let A=h.content.evaluate(a);return La(A)===wo?new Ep("",A,null,null,null,h.verticalAlign?h.verticalAlign.evaluate(a):null):new Ep(xl(A),null,h.scale?h.scale.evaluate(a):null,h.font?h.font.evaluate(a).join(","):null,h.textColor?h.textColor.evaluate(a):null,h.verticalAlign?h.verticalAlign.evaluate(a):null)}))}eachChild(a){for(let h of this.sections)a(h.content),h.scale&&a(h.scale),h.font&&a(h.font),h.textColor&&a(h.textColor),h.verticalAlign&&a(h.verticalAlign)}outputDefined(){return!1}}class wi{constructor(a){this.type=wo,this.input=a}static parse(a,h){if(a.length!==2)return h.error("Expected two arguments.");let A=h.parse(a[1],1,fi);return A?new wi(A):h.error("No image name provided.")}evaluate(a){let h=this.input.evaluate(a),A=Ol.fromString(h);return A&&a.availableImages&&(A.available=a.availableImages.indexOf(h)>-1),A}eachChild(a){a(this.input)}outputDefined(){return!1}}class ni{constructor(a){this.type=Or,this.input=a}static parse(a,h){if(a.length!==2)return h.error(`Expected 1 argument, but found ${a.length-1} instead.`);let A=h.parse(a[1],1);return A?A.type.kind!=="array"&&A.type.kind!=="string"&&A.type.kind!=="value"?h.error(`Expected argument of type string or array, but found ${Qn(A.type)} instead.`):new ni(A):null}evaluate(a){let h=this.input.evaluate(a);if(typeof h=="string")return[...h].length;if(Array.isArray(h))return h.length;throw new Gs(`Expected value to be of type string or array, but found ${Qn(La(h))} instead.`)}eachChild(a){a(this.input)}outputDefined(){return!1}}let b=8192;function Po(d,a){let h=(180+d[0])/360,A=(180-180/Math.PI*Math.log(Math.tan(Math.PI/4+d[1]*Math.PI/360)))/360,C=Math.pow(2,a.z);return[Math.round(h*C*b),Math.round(A*C*b)]}function _o(d,a){let h=Math.pow(2,a.z);return[(C=(d[0]/b+a.x)/h,360*C-180),(A=(d[1]/b+a.y)/h,360/Math.PI*Math.atan(Math.exp((180-360*A)*Math.PI/180))-90)];var A,C}function Ye(d,a){d[0]=Math.min(d[0],a[0]),d[1]=Math.min(d[1],a[1]),d[2]=Math.max(d[2],a[0]),d[3]=Math.max(d[3],a[1])}function Ms(d,a){return!(d[0]<=a[0]||d[2]>=a[2]||d[1]<=a[1]||d[3]>=a[3])}function ao(d,a,h){let A=d[0]-a[0],C=d[1]-a[1],D=d[0]-h[0],O=d[1]-h[1];return A*O-D*C==0&&A*D<=0&&C*O<=0}function Ps(d,a,h,A){return(C=[A[0]-h[0],A[1]-h[1]])[0]*(D=[a[0]-d[0],a[1]-d[1]])[1]-C[1]*D[0]!=0&&!(!gh(d,a,h,A)||!gh(h,A,d,a));var C,D}function Rs(d,a,h){for(let A of h)for(let C=0;C(C=d)[1]!=(O=H[Z+1])[1]>C[1]&&C[0]<(O[0]-D[0])*(C[1]-D[1])/(O[1]-D[1])+D[0]&&(A=!A)}var C,D,O;return A}function Qs(d,a){for(let h of a)if(Go(d,h))return!0;return!1}function Ts(d,a){for(let h of d)if(!Go(h,a))return!1;for(let h=0;h0&&H<0||O<0&&H>0}function Ss(d,a,h){let A=[];for(let C=0;Ch[2]){let C=.5*A,D=d[0]-h[0]>C?-A:h[0]-d[0]>C?A:0;D===0&&(D=d[0]-h[2]>C?-A:h[2]-d[0]>C?A:0),d[0]+=D}Ye(a,d)}function Qa(d,a,h,A){let C=Math.pow(2,A.z)*b,D=[A.x*b,A.y*b],O=[];for(let H of d)for(let Z of H){let re=[Z.x+D[0],Z.y+D[1]];mc(re,a,h,C),O.push(re)}return O}function Ru(d,a,h,A){let C=Math.pow(2,A.z)*b,D=[A.x*b,A.y*b],O=[];for(let Z of d){let re=[];for(let ce of Z){let de=[ce.x+D[0],ce.y+D[1]];Ye(a,de),re.push(de)}O.push(re)}if(a[2]-a[0]<=C/2){(H=a)[0]=H[1]=1/0,H[2]=H[3]=-1/0;for(let Z of O)for(let re of Z)mc(re,a,h,C)}var H;return O}class gc{constructor(a,h){this.type=pr,this.geojson=a,this.geometries=h}static parse(a,h){if(a.length!==2)return h.error(`'within' expression requires exactly one argument, but found ${a.length-1} instead.`);if(tu(a[1])){let A=a[1];if(A.type==="FeatureCollection"){let C=[];for(let D of A.features){let{type:O,coordinates:H}=D.geometry;O==="Polygon"&&C.push(H),O==="MultiPolygon"&&C.push(...H)}if(C.length)return new gc(A,{type:"MultiPolygon",coordinates:C})}else if(A.type==="Feature"){let C=A.geometry.type;if(C==="Polygon"||C==="MultiPolygon")return new gc(A,A.geometry)}else if(A.type==="Polygon"||A.type==="MultiPolygon")return new gc(A,A)}return h.error("'within' expression requires valid geojson object that contains polygon geometry type.")}evaluate(a){if(a.geometry()!=null&&a.canonicalID()!=null){if(a.geometryType()==="Point")return function(h,A){let C=[1/0,1/0,-1/0,-1/0],D=[1/0,1/0,-1/0,-1/0],O=h.canonicalID();if(A.type==="Polygon"){let H=Ss(A.coordinates,D,O),Z=Qa(h.geometry(),C,D,O);if(!Ms(C,D))return!1;for(let re of Z)if(!Go(re,H))return!1}if(A.type==="MultiPolygon"){let H=Ah(A.coordinates,D,O),Z=Qa(h.geometry(),C,D,O);if(!Ms(C,D))return!1;for(let re of Z)if(!Qs(re,H))return!1}return!0}(a,this.geometries);if(a.geometryType()==="LineString")return function(h,A){let C=[1/0,1/0,-1/0,-1/0],D=[1/0,1/0,-1/0,-1/0],O=h.canonicalID();if(A.type==="Polygon"){let H=Ss(A.coordinates,D,O),Z=Ru(h.geometry(),C,D,O);if(!Ms(C,D))return!1;for(let re of Z)if(!Ts(re,H))return!1}if(A.type==="MultiPolygon"){let H=Ah(A.coordinates,D,O),Z=Ru(h.geometry(),C,D,O);if(!Ms(C,D))return!1;for(let re of Z)if(!Os(re,H))return!1}return!0}(a,this.geometries)}return!1}eachChild(){}outputDefined(){return!0}}let _h=class{constructor(d=[],a=(h,A)=>hA?1:0){if(this.data=d,this.length=this.data.length,this.compare=a,this.length>0)for(let h=(this.length>>1)-1;h>=0;h--)this._down(h)}push(d){this.data.push(d),this._up(this.length++)}pop(){if(this.length===0)return;let d=this.data[0],a=this.data.pop();return--this.length>0&&(this.data[0]=a,this._down(0)),d}peek(){return this.data[0]}_up(d){let{data:a,compare:h}=this,A=a[d];for(;d>0;){let C=d-1>>1,D=a[C];if(h(A,D)>=0)break;a[d]=D,d=C}a[d]=A}_down(d){let{data:a,compare:h}=this,A=this.length>>1,C=a[d];for(;d=0)break;a[d]=a[D],d=D}a[d]=C}};function Fl(d,a,h=0,A=d.length-1,C=qn){for(;A>h;){if(A-h>600){let Z=A-h+1,re=a-h+1,ce=Math.log(Z),de=.5*Math.exp(2*ce/3),we=.5*Math.sqrt(ce*de*(Z-de)/Z)*(re-Z/2<0?-1:1);Fl(d,a,Math.max(h,Math.floor(a-re*de/Z+we)),Math.min(A,Math.floor(a+(Z-re)*de/Z+we)),C)}let D=d[a],O=h,H=A;for(Ac(d,h,a),C(d[A],D)>0&&Ac(d,h,A);O0;)H--}C(d[h],D)===0?Ac(d,h,H):(H++,Ac(d,H,A)),H<=a&&(h=H+1),a<=H&&(A=H-1)}}function Ac(d,a,h){let A=d[a];d[a]=d[h],d[h]=A}function qn(d,a){return da?1:0}function dt(d,a){if(d.length<=1)return[d];let h=[],A,C;for(let D of d){let O=$h(D);O!==0&&(D.area=Math.abs(O),C===void 0&&(C=O<0),C===O<0?(A&&h.push(A),A=[D]):A.push(D))}if(A&&h.push(A),a>1)for(let D=0;D1?(re=a[Z+1][0],ce=a[Z+1][1]):Ee>0&&(re+=de/this.kx*Ee,ce+=we/this.ky*Ee)),de=this.wrap(h[0]-re)*this.kx,we=(h[1]-ce)*this.ky;let De=de*de+we*we;De180;)a-=360;return a}}function et(d,a){return a[0]-d[0]}function yf(d){return d[1]-d[0]+1}function Bu(d,a){return d[1]>=d[0]&&d[1]d[1])return[null,null];let h=yf(d);if(a){if(h===2)return[d,null];let C=Math.floor(h/2);return[[d[0],d[0]+C],[d[0]+C,d[1]]]}if(h===1)return[d,null];let A=Math.floor(h/2)-1;return[[d[0],d[0]+A],[d[0]+A+1,d[1]]]}function qf(d,a){if(!Bu(a,d.length))return[1/0,1/0,-1/0,-1/0];let h=[1/0,1/0,-1/0,-1/0];for(let A=a[0];A<=a[1];++A)Ye(h,d[A]);return h}function Bt(d){let a=[1/0,1/0,-1/0,-1/0];for(let h of d)for(let A of h)Ye(a,A);return a}function ar(d){return d[0]!==-1/0&&d[1]!==-1/0&&d[2]!==1/0&&d[3]!==1/0}function Br(d,a,h){if(!ar(d)||!ar(a))return NaN;let A=0,C=0;return d[2]a[2]&&(A=d[0]-a[2]),d[1]>a[3]&&(C=d[1]-a[3]),d[3]=A)return A;if(Ms(C,D)){if(To(d,a))return 0}else if(To(a,d))return 0;let O=1/0;for(let H of d)for(let Z=0,re=H.length,ce=re-1;Z0;){let Z=O.pop();if(Z[0]>=D)continue;let re=Z[1],ce=a?50:100;if(yf(re)<=ce){if(!Bu(re,d.length))return NaN;if(a){let de=sn(d,re,h,A);if(isNaN(de)||de===0)return de;D=Math.min(D,de)}else for(let de=re[0];de<=re[1];++de){let we=Pn(d[de],h,A);if(D=Math.min(D,we),D===0)return 0}}else{let de=Wf(re,a);Ti(O,D,A,d,H,de[0]),Ti(O,D,A,d,H,de[1])}}return D}function Fs(d,a,h,A,C,D=1/0){let O=Math.min(D,C.distance(d[0],h[0]));if(O===0)return O;let H=new _h([[0,[0,d.length-1],[0,h.length-1]]],et);for(;H.length>0;){let Z=H.pop();if(Z[0]>=O)continue;let re=Z[1],ce=Z[2],de=a?50:100,we=A?50:100;if(yf(re)<=de&&yf(ce)<=we){if(!Bu(re,d.length)&&Bu(ce,h.length))return NaN;let Ee;if(a&&A)Ee=Li(d,re,h,ce,C),O=Math.min(O,Ee);else if(a&&!A){let De=d.slice(re[0],re[1]+1);for(let ke=ce[0];ke<=ce[1];++ke)if(Ee=Ur(h[ke],De,C),O=Math.min(O,Ee),O===0)return O}else if(!a&&A){let De=h.slice(ce[0],ce[1]+1);for(let ke=re[0];ke<=re[1];++ke)if(Ee=Ur(d[ke],De,C),O=Math.min(O,Ee),O===0)return O}else Ee=yi(d,re,h,ce,C),O=Math.min(O,Ee)}else{let Ee=Wf(re,a),De=Wf(ce,A);Kn(H,O,C,d,h,Ee[0],De[0]),Kn(H,O,C,d,h,Ee[0],De[1]),Kn(H,O,C,d,h,Ee[1],De[0]),Kn(H,O,C,d,h,Ee[1],De[1])}}return O}function wl(d){return d.type==="MultiPolygon"?d.coordinates.map(a=>({type:"Polygon",coordinates:a})):d.type==="MultiLineString"?d.coordinates.map(a=>({type:"LineString",coordinates:a})):d.type==="MultiPoint"?d.coordinates.map(a=>({type:"Point",coordinates:a})):[d]}class yo{constructor(a,h){this.type=Or,this.geojson=a,this.geometries=h}static parse(a,h){if(a.length!==2)return h.error(`'distance' expression requires exactly one argument, but found ${a.length-1} instead.`);if(tu(a[1])){let A=a[1];if(A.type==="FeatureCollection")return new yo(A,A.features.map(C=>wl(C.geometry)).flat());if(A.type==="Feature")return new yo(A,wl(A.geometry));if("type"in A&&"coordinates"in A)return new yo(A,wl(A))}return h.error("'distance' expression requires valid geojson object that contains polygon geometry type.")}evaluate(a){if(a.geometry()!=null&&a.canonicalID()!=null){if(a.geometryType()==="Point")return function(h,A){let C=h.geometry(),D=C.flat().map(Z=>_o([Z.x,Z.y],h.canonical));if(C.length===0)return NaN;let O=new Ad(D[0][1]),H=1/0;for(let Z of A){switch(Z.type){case"Point":H=Math.min(H,Fs(D,!1,[Z.coordinates],!1,O,H));break;case"LineString":H=Math.min(H,Fs(D,!1,Z.coordinates,!0,O,H));break;case"Polygon":H=Math.min(H,zn(D,!1,Z.coordinates,O,H))}if(H===0)return H}return H}(a,this.geometries);if(a.geometryType()==="LineString")return function(h,A){let C=h.geometry(),D=C.flat().map(Z=>_o([Z.x,Z.y],h.canonical));if(C.length===0)return NaN;let O=new Ad(D[0][1]),H=1/0;for(let Z of A){switch(Z.type){case"Point":H=Math.min(H,Fs(D,!0,[Z.coordinates],!1,O,H));break;case"LineString":H=Math.min(H,Fs(D,!0,Z.coordinates,!0,O,H));break;case"Polygon":H=Math.min(H,zn(D,!0,Z.coordinates,O,H))}if(H===0)return H}return H}(a,this.geometries);if(a.geometryType()==="Polygon")return function(h,A){let C=h.geometry();if(C.length===0||C[0].length===0)return NaN;let D=dt(C,0).map(Z=>Z.map(re=>re.map(ce=>_o([ce.x,ce.y],h.canonical)))),O=new Ad(D[0][0][0][1]),H=1/0;for(let Z of A)for(let re of D){switch(Z.type){case"Point":H=Math.min(H,zn([Z.coordinates],!1,re,O,H));break;case"LineString":H=Math.min(H,zn(Z.coordinates,!0,re,O,H));break;case"Polygon":H=Math.min(H,Hi(re,Z.coordinates,O,H))}if(H===0)return H}return H}(a,this.geometries)}return NaN}eachChild(){}outputDefined(){return!0}}class tc{constructor(a){this.type=Ni,this.key=a}static parse(a,h){if(a.length!==2)return h.error(`Expected 1 argument, but found ${a.length-1} instead.`);let A=a[1];return A==null?h.error("Global state property must be defined."):typeof A!="string"?h.error(`Global state property must be string, but found ${typeof a[1]} instead.`):new tc(A)}evaluate(a){var h;let A=(h=a.globals)===null||h===void 0?void 0:h.globalState;return A&&Object.keys(A).length!==0?Ma(A,this.key):null}eachChild(){}outputDefined(){return!1}}let Tl={"==":gs,"!=":Mo,">":al,"<":bl,">=":Ka,"<=":Da,array:Ec,at:ms,boolean:Ec,case:Gd,coalesce:li,collator:Yn,format:Gr,image:wi,in:Ao,"index-of":qh,interpolate:Ut,"interpolate-hcl":Ut,"interpolate-lab":Ut,length:ni,let:ia,literal:Ws,match:us,number:Ec,"number-format":Er,object:Ec,slice:q,step:pe,string:Ec,"to-boolean":Wh,"to-color":Wh,"to-number":Wh,"to-string":Wh,var:mh,within:gc,distance:yo,"global-state":tc};class ll{constructor(a,h,A,C){this.name=a,this.type=h,this._evaluate=A,this.args=C}evaluate(a){return this._evaluate(a,this.args)}eachChild(a){this.args.forEach(a)}outputDefined(){return!1}static parse(a,h){let A=a[0],C=ll.definitions[A];if(!C)return h.error(`Unknown expression "${A}". If you wanted a literal array, use ["literal", [...]].`,0);let D=Array.isArray(C)?C[0]:C.type,O=Array.isArray(C)?[[C[1],C[2]]]:C.overloads,H=O.filter(([re])=>!Array.isArray(re)||re.length===a.length-1),Z=null;for(let[re,ce]of H){Z=new Af(h.registry,Pa,h.path,null,h.scope);let de=[],we=!1;for(let Ee=1;Ee{return we=de,Array.isArray(we)?`(${we.map(Qn).join(", ")})`:`(${Qn(we.type)}...)`;var we}).join(" | "),ce=[];for(let de=1;de{h=a?h&&Pa(A):h&&A instanceof Ws}),!!h&&Yi(d)&&qd(d,["zoom","heatmap-density","elevation","line-progress","accumulated","is-supported-script"])}function Yi(d){if(d instanceof ll&&(d.name==="get"&&d.args.length===1||d.name==="feature-state"||d.name==="has"&&d.args.length===1||d.name==="properties"||d.name==="geometry-type"||d.name==="id"||/^filter-/.test(d.name))||d instanceof gc||d instanceof yo)return!1;let a=!0;return d.eachChild(h=>{a&&!Yi(h)&&(a=!1)}),a}function Cc(d){if(d instanceof ll&&d.name==="feature-state")return!1;let a=!0;return d.eachChild(h=>{a&&!Cc(h)&&(a=!1)}),a}function qd(d,a){if(d instanceof ll&&a.indexOf(d.name)>=0)return!1;let h=!0;return d.eachChild(A=>{h&&!qd(A,a)&&(h=!1)}),h}function yd(d){return{result:"success",value:d}}function ru(d){return{result:"error",value:d}}function kl(d){return d["property-type"]==="data-driven"||d["property-type"]==="cross-faded-data-driven"}function Ip(d){return!!d.expression&&d.expression.parameters.indexOf("zoom")>-1}function Fi(d){return!!d.expression&&d.expression.interpolated}function Zo(d){return d instanceof Number?"number":d instanceof String?"string":d instanceof Boolean?"boolean":Array.isArray(d)?"array":d===null?"null":typeof d}function vd(d){return typeof d=="object"&&d!==null&&!Array.isArray(d)&&La(d)===Mi}function tg(d){return d}function Zu(d,a){let h=d.stops&&typeof d.stops[0][0]=="object",A=h||!(h||d.property!==void 0),C=d.type||(Fi(a)?"exponential":"interval"),D=function(ce){switch(ce.type){case"color":return Io.parse;case"padding":return Jl.parse;case"numberArray":return _a.parse;case"colorArray":return Zn.parse;default:return null}}(a);if(D&&((d=ei({},d)).stops&&(d.stops=d.stops.map(ce=>[ce[0],D(ce[1])])),d.default=D(d.default?d.default:a.default)),d.colorSpace&&(O=d.colorSpace)!=="rgb"&&O!=="hcl"&&O!=="lab")throw new Error(`Unknown color space: "${d.colorSpace}"`);var O;let H=function(ce){switch(ce){case"exponential":return ha;case"interval":return ig;case"categorical":return rg;case"identity":return mu;default:throw new Error(`Unknown function type "${ce}"`)}}(C),Z,re;if(C==="categorical"){Z=Object.create(null);for(let ce of d.stops)Z[ce[0]]=ce[1];re=typeof d.stops[0][0]}if(h){let ce={},de=[];for(let De=0;DeDe[0]),evaluate:({zoom:De},ke)=>ha({stops:we,base:d.base},a,De).evaluate(De,ke)}}if(A){let ce=C==="exponential"?{name:"exponential",base:d.base!==void 0?d.base:1}:null;return{kind:"camera",interpolationType:ce,interpolationFactor:Ut.interpolationFactor.bind(void 0,ce),zoomStops:d.stops.map(de=>de[0]),evaluate:({zoom:de})=>H(d,a,de,Z,re)}}return{kind:"source",evaluate(ce,de){let we=de&&de.properties?de.properties[d.property]:void 0;return we===void 0?Ic(d.default,a.default):H(d,a,we,Z,re)}}}function Ic(d,a,h){return d!==void 0?d:a!==void 0?a:h!==void 0?h:void 0}function rg(d,a,h,A,C){return Ic(typeof h===C?A[h]:void 0,d.default,a.default)}function ig(d,a,h){if(Zo(h)!=="number")return Ic(d.default,a.default);let A=d.stops.length;if(A===1||h<=d.stops[0][0])return d.stops[0][1];if(h>=d.stops[A-1][0])return d.stops[A-1][1];let C=oe(d.stops.map(D=>D[0]),h);return d.stops[C][1]}function ha(d,a,h){let A=d.base!==void 0?d.base:1;if(Zo(h)!=="number")return Ic(d.default,a.default);let C=d.stops.length;if(C===1||h<=d.stops[0][0])return d.stops[0][1];if(h>=d.stops[C-1][0])return d.stops[C-1][1];let D=oe(d.stops.map(ce=>ce[0]),h),O=function(ce,de,we,Ee){let De=Ee-we,ke=ce-we;return De===0?0:de===1?ke/De:(Math.pow(de,ke)-1)/(Math.pow(de,De)-1)}(h,A,d.stops[D][0],d.stops[D+1][0]),H=d.stops[D][1],Z=d.stops[D+1][1],re=Fr[a.type]||tg;return typeof H.evaluate=="function"?{evaluate(...ce){let de=H.evaluate.apply(void 0,ce),we=Z.evaluate.apply(void 0,ce);if(de!==void 0&&we!==void 0)return re(de,we,O,d.colorSpace)}}:re(H,Z,O,d.colorSpace)}function mu(d,a,h){switch(a.type){case"color":h=Io.parse(h);break;case"formatted":h=Ql.fromString(h.toString());break;case"resolvedImage":h=Ol.fromString(h.toString());break;case"padding":h=Jl.parse(h);break;case"colorArray":h=Zn.parse(h);break;case"numberArray":h=_a.parse(h);break;default:Zo(h)===a.type||a.type==="enum"&&a.values[h]||(h=void 0)}return Ic(h,d.default,a.default)}ll.register(Tl,{error:[{kind:"error"},[fi],(d,[a])=>{throw new Gs(a.evaluate(d))}],typeof:[fi,[Ni],(d,[a])=>Qn(La(a.evaluate(d)))],"to-rgba":[uo(Or,4),[Di],(d,[a])=>{let[h,A,C,D]=a.evaluate(d).rgb;return[255*h,255*A,255*C,D]}],rgb:[Di,[Or,Or,Or],Oa],rgba:[Di,[Or,Or,Or,Or],Oa],has:{type:pr,overloads:[[[fi],(d,[a])=>Sl(a.evaluate(d),d.properties())],[[fi,Mi],(d,[a,h])=>Sl(a.evaluate(d),h.evaluate(d))]]},get:{type:Ni,overloads:[[[fi],(d,[a])=>_d(a.evaluate(d),d.properties())],[[fi,Mi],(d,[a,h])=>_d(a.evaluate(d),h.evaluate(d))]]},"feature-state":[Ni,[fi],(d,[a])=>_d(a.evaluate(d),d.featureState||{})],properties:[Mi,[],d=>d.properties()],"geometry-type":[fi,[],d=>d.geometryType()],id:[Ni,[],d=>d.id()],zoom:[Or,[],d=>d.globals.zoom],"heatmap-density":[Or,[],d=>d.globals.heatmapDensity||0],elevation:[Or,[],d=>d.globals.elevation||0],"line-progress":[Or,[],d=>d.globals.lineProgress||0],accumulated:[Ni,[],d=>d.globals.accumulated===void 0?null:d.globals.accumulated],"+":[Or,vf(Or),(d,a)=>{let h=0;for(let A of a)h+=A.evaluate(d);return h}],"*":[Or,vf(Or),(d,a)=>{let h=1;for(let A of a)h*=A.evaluate(d);return h}],"-":{type:Or,overloads:[[[Or,Or],(d,[a,h])=>a.evaluate(d)-h.evaluate(d)],[[Or],(d,[a])=>-a.evaluate(d)]]},"/":[Or,[Or,Or],(d,[a,h])=>a.evaluate(d)/h.evaluate(d)],"%":[Or,[Or,Or],(d,[a,h])=>a.evaluate(d)%h.evaluate(d)],ln2:[Or,[],()=>Math.LN2],pi:[Or,[],()=>Math.PI],e:[Or,[],()=>Math.E],"^":[Or,[Or,Or],(d,[a,h])=>Math.pow(a.evaluate(d),h.evaluate(d))],sqrt:[Or,[Or],(d,[a])=>Math.sqrt(a.evaluate(d))],log10:[Or,[Or],(d,[a])=>Math.log(a.evaluate(d))/Math.LN10],ln:[Or,[Or],(d,[a])=>Math.log(a.evaluate(d))],log2:[Or,[Or],(d,[a])=>Math.log(a.evaluate(d))/Math.LN2],sin:[Or,[Or],(d,[a])=>Math.sin(a.evaluate(d))],cos:[Or,[Or],(d,[a])=>Math.cos(a.evaluate(d))],tan:[Or,[Or],(d,[a])=>Math.tan(a.evaluate(d))],asin:[Or,[Or],(d,[a])=>Math.asin(a.evaluate(d))],acos:[Or,[Or],(d,[a])=>Math.acos(a.evaluate(d))],atan:[Or,[Or],(d,[a])=>Math.atan(a.evaluate(d))],min:[Or,vf(Or),(d,a)=>Math.min(...a.map(h=>h.evaluate(d)))],max:[Or,vf(Or),(d,a)=>Math.max(...a.map(h=>h.evaluate(d)))],abs:[Or,[Or],(d,[a])=>Math.abs(a.evaluate(d))],round:[Or,[Or],(d,[a])=>{let h=a.evaluate(d);return h<0?-Math.round(-h):Math.round(h)}],floor:[Or,[Or],(d,[a])=>Math.floor(a.evaluate(d))],ceil:[Or,[Or],(d,[a])=>Math.ceil(a.evaluate(d))],"filter-==":[pr,[fi,Ni],(d,[a,h])=>d.properties()[a.value]===h.value],"filter-id-==":[pr,[Ni],(d,[a])=>d.id()===a.value],"filter-type-==":[pr,[fi],(d,[a])=>d.geometryType()===a.value],"filter-<":[pr,[fi,Ni],(d,[a,h])=>{let A=d.properties()[a.value],C=h.value;return typeof A==typeof C&&A{let h=d.id(),A=a.value;return typeof h==typeof A&&h":[pr,[fi,Ni],(d,[a,h])=>{let A=d.properties()[a.value],C=h.value;return typeof A==typeof C&&A>C}],"filter-id->":[pr,[Ni],(d,[a])=>{let h=d.id(),A=a.value;return typeof h==typeof A&&h>A}],"filter-<=":[pr,[fi,Ni],(d,[a,h])=>{let A=d.properties()[a.value],C=h.value;return typeof A==typeof C&&A<=C}],"filter-id-<=":[pr,[Ni],(d,[a])=>{let h=d.id(),A=a.value;return typeof h==typeof A&&h<=A}],"filter->=":[pr,[fi,Ni],(d,[a,h])=>{let A=d.properties()[a.value],C=h.value;return typeof A==typeof C&&A>=C}],"filter-id->=":[pr,[Ni],(d,[a])=>{let h=d.id(),A=a.value;return typeof h==typeof A&&h>=A}],"filter-has":[pr,[Ni],(d,[a])=>a.value in d.properties()],"filter-has-id":[pr,[],d=>d.id()!==null&&d.id()!==void 0],"filter-type-in":[pr,[uo(fi)],(d,[a])=>a.value.indexOf(d.geometryType())>=0],"filter-id-in":[pr,[uo(Ni)],(d,[a])=>a.value.indexOf(d.id())>=0],"filter-in-small":[pr,[fi,uo(Ni)],(d,[a,h])=>h.value.indexOf(d.properties()[a.value])>=0],"filter-in-large":[pr,[fi,uo(Ni)],(d,[a,h])=>function(A,C,D,O){for(;D<=O;){let H=D+O>>1;if(C[H]===A)return!0;C[H]>A?O=H-1:D=H+1}return!1}(d.properties()[a.value],h.value,0,h.value.length-1)],all:{type:pr,overloads:[[[pr,pr],(d,[a,h])=>a.evaluate(d)&&h.evaluate(d)],[vf(pr),(d,a)=>{for(let h of a)if(!h.evaluate(d))return!1;return!0}]]},any:{type:pr,overloads:[[[pr,pr],(d,[a,h])=>a.evaluate(d)||h.evaluate(d)],[vf(pr),(d,a)=>{for(let h of a)if(h.evaluate(d))return!0;return!1}]]},"!":[pr,[pr],(d,[a])=>!a.evaluate(d)],"is-supported-script":[pr,[fi],(d,[a])=>{let h=d.globals&&d.globals.isSupportedScript;return!h||h(a.evaluate(d))}],upcase:[fi,[fi],(d,[a])=>a.evaluate(d).toUpperCase()],downcase:[fi,[fi],(d,[a])=>a.evaluate(d).toLowerCase()],concat:[fi,vf(Ni),(d,a)=>a.map(h=>xl(h.evaluate(d))).join("")],"resolved-locale":[fi,[zi],(d,[a])=>a.evaluate(d).resolvedLocale()]});class Mc{constructor(a,h,A){this.expression=a,this._warningHistory={},this._evaluator=new Cp,this._defaultValue=h?function(C){if(C.type==="color"&&vd(C.default))return new Io(0,0,0,0);switch(C.type){case"color":return Io.parse(C.default)||null;case"padding":return Jl.parse(C.default)||null;case"numberArray":return _a.parse(C.default)||null;case"colorArray":return Zn.parse(C.default)||null;case"variableAnchorOffsetCollection":return sl.parse(C.default)||null;case"projectionDefinition":return vl.parse(C.default)||null;default:return C.default===void 0?null:C.default}}(h):null,this._enumValues=h&&h.type==="enum"?h.values:null,this._globalState=A}evaluateWithoutErrorHandling(a,h,A,C,D,O){return this._globalState&&(a=fa(a,this._globalState)),this._evaluator.globals=a,this._evaluator.feature=h,this._evaluator.featureState=A,this._evaluator.canonical=C,this._evaluator.availableImages=D||null,this._evaluator.formattedSection=O,this.expression.evaluate(this._evaluator)}evaluate(a,h,A,C,D,O){this._globalState&&(a=fa(a,this._globalState)),this._evaluator.globals=a,this._evaluator.feature=h||null,this._evaluator.featureState=A||null,this._evaluator.canonical=C,this._evaluator.availableImages=D||null,this._evaluator.formattedSection=O||null;try{let H=this.expression.evaluate(this._evaluator);if(H==null||typeof H=="number"&&H!=H)return this._defaultValue;if(this._enumValues&&!(H in this._enumValues))throw new Gs(`Expected value to be one of ${Object.keys(this._enumValues).map(Z=>JSON.stringify(Z)).join(", ")}, but found ${JSON.stringify(H)} instead.`);return H}catch(H){return this._warningHistory[H.message]||(this._warningHistory[H.message]=!0,typeof console<"u"&&console.warn(H.message)),this._defaultValue}}}function yh(d){return Array.isArray(d)&&d.length>0&&typeof d[0]=="string"&&d[0]in Tl}function $d(d,a,h){let A=new Af(Tl,Pa,[],a?function(D){let O={color:Di,string:fi,number:Or,enum:fi,boolean:pr,formatted:po,padding:Ls,numberArray:No,colorArray:co,projectionDefinition:Ii,resolvedImage:wo,variableAnchorOffsetCollection:Al};return D.type==="array"?uo(O[D.value]||Ni,D.length):O[D.type]}(a):void 0),C=A.parse(d,void 0,void 0,void 0,a&&a.type==="string"?{typeAnnotation:"coerce"}:void 0);return C?yd(new Mc(C,a,h)):ru(A.errors)}class $f{constructor(a,h,A){this.kind=a,this._styleExpression=h,this.isStateDependent=a!=="constant"&&!Cc(h.expression),this.globalStateRefs=Nl(h.expression),this._globalState=A}evaluateWithoutErrorHandling(a,h,A,C,D,O){return this._globalState&&(a=fa(a,this._globalState)),this._styleExpression.evaluateWithoutErrorHandling(a,h,A,C,D,O)}evaluate(a,h,A,C,D,O){return this._globalState&&(a=fa(a,this._globalState)),this._styleExpression.evaluate(a,h,A,C,D,O)}}class Yu{constructor(a,h,A,C,D){this.kind=a,this.zoomStops=A,this._styleExpression=h,this.isStateDependent=a!=="camera"&&!Cc(h.expression),this.globalStateRefs=Nl(h.expression),this.interpolationType=C,this._globalState=D}evaluateWithoutErrorHandling(a,h,A,C,D,O){return this._globalState&&(a=fa(a,this._globalState)),this._styleExpression.evaluateWithoutErrorHandling(a,h,A,C,D,O)}evaluate(a,h,A,C,D,O){return this._globalState&&(a=fa(a,this._globalState)),this._styleExpression.evaluate(a,h,A,C,D,O)}interpolationFactor(a,h,A){return this.interpolationType?Ut.interpolationFactor(this.interpolationType,a,h,A):0}}function gu(d,a,h){let A=$d(d,a,h);if(A.result==="error")return A;let C=A.value.expression,D=Yi(C);if(!D&&!kl(a))return ru([new ui("","data expressions not supported")]);let O=qd(C,["zoom"]);if(!O&&!Ip(a))return ru([new ui("","zoom expressions not supported")]);let H=Lu(C);return H||O?H instanceof ui?ru([H]):H instanceof Ut&&!Fi(a)?ru([new ui("",'"interpolate" expressions cannot be used with this property')]):yd(H?new Yu(D?"camera":"composite",A.value,H.labels,H instanceof Ut?H.interpolation:void 0,h):new $f(D?"constant":"source",A.value,h)):ru([new ui("",'"zoom" expression may only be used as input to a top-level "step" or "interpolate" expression.')])}class So{constructor(a,h){this._parameters=a,this._specification=h,ei(this,Zu(this._parameters,this._specification))}static deserialize(a){return new So(a._parameters,a._specification)}static serialize(a){return{_parameters:a._parameters,_specification:a._specification}}}function Lu(d){let a=null;if(d instanceof ia)a=Lu(d.result);else if(d instanceof li){for(let h of d.args)if(a=Lu(h),a)break}else(d instanceof pe||d instanceof Ut)&&d.input instanceof ll&&d.input.name==="zoom"&&(a=d);return a instanceof ui||d.eachChild(h=>{let A=Lu(h);A instanceof ui?a=A:!a&&A?a=new ui("",'"zoom" expression may only be used as input to a top-level "step" or "interpolate" expression.'):a&&A&&a!==A&&(a=new ui("",'Only one zoom-based "step" or "interpolate" subexpression may be used in an expression.'))}),a}function Nl(d,a=new Set){return d instanceof tc&&a.add(d.key),d.eachChild(h=>{Nl(h,a)}),a}function fa(d,a){let{zoom:h,heatmapDensity:A,elevation:C,lineProgress:D,isSupportedScript:O,accumulated:H}=d??{};return{zoom:h,heatmapDensity:A,elevation:C,lineProgress:D,isSupportedScript:O,accumulated:H,globalState:a}}function xf(d){if(d===!0||d===!1)return!0;if(!Array.isArray(d)||d.length===0)return!1;switch(d[0]){case"has":return d.length>=2&&d[1]!=="$id"&&d[1]!=="$type";case"in":return d.length>=3&&(typeof d[1]!="string"||Array.isArray(d[2]));case"!in":case"!has":case"none":return!1;case"==":case"!=":case">":case">=":case"<":case"<=":return d.length!==3||Array.isArray(d[1])||Array.isArray(d[2]);case"any":case"all":for(let a of d.slice(1))if(!xf(a)&&typeof a!="boolean")return!1;return!0;default:return!0}}let Xf={type:"boolean",default:!1,transition:!1,"property-type":"data-driven",expression:{interpolated:!1,parameters:["zoom","feature"]}};function Pc(d,a){if(d==null)return{filter:()=>!0,needGeometry:!1,getGlobalStateRefs:()=>new Set};xf(d)||(d=An(d));let h=$d(d,Xf,a);if(h.result==="error")throw new Error(h.value.map(A=>`${A.key}: ${A.message}`).join(", "));return{filter:(A,C,D)=>h.value.evaluate(A,C,{},D),needGeometry:Ku(d),getGlobalStateRefs:()=>Nl(h.value.expression)}}function El(d,a){return da?1:0}function Ku(d){if(!Array.isArray(d))return!1;if(d[0]==="within"||d[0]==="distance")return!0;for(let a=1;a"||a==="<="||a===">="?nn(d[1],d[2],a):a==="any"?(h=d.slice(1),["any"].concat(h.map(An))):a==="all"?["all"].concat(d.slice(1).map(An)):a==="none"?["all"].concat(d.slice(1).map(An).map(Au)):a==="in"?Xd(d[1],d.slice(2)):a==="!in"?Au(Xd(d[1],d.slice(2))):a==="has"?Vc(d[1]):a!=="!has"||Au(Vc(d[1]));var h}function nn(d,a,h){switch(d){case"$type":return[`filter-type-${h}`,a];case"$id":return[`filter-id-${h}`,a];default:return[`filter-${h}`,d,a]}}function Xd(d,a){if(a.length===0)return!1;switch(d){case"$type":return["filter-type-in",["literal",a]];case"$id":return["filter-id-in",["literal",a]];default:return a.length>200&&!a.some(h=>typeof h!=typeof a[0])?["filter-in-large",d,["literal",a.sort(El)]]:["filter-in-small",d,["literal",a]]}}function Vc(d){switch(d){case"$type":return!0;case"$id":return["filter-has-id"];default:return["filter-has",d]}}function Au(d){return["!",d]}function Cl(d){let a=typeof d;if(a==="number"||a==="boolean"||a==="string"||d==null)return JSON.stringify(d);if(Array.isArray(d)){let C="[";for(let D of d)C+=`${Cl(D)},`;return`${C}]`}let h=Object.keys(d).sort(),A="{";for(let C=0;CA.maximum?[new Ct(a,h,`${h} is greater than the maximum value ${A.maximum}`)]:[]}function Pp(d){let a=d.valueSpec,h=Ha(d.value.type),A,C,D,O={},H=h!=="categorical"&&d.value.property===void 0,Z=!H,re=Zo(d.value.stops)==="array"&&Zo(d.value.stops[0])==="array"&&Zo(d.value.stops[0][0])==="object",ce=da({key:d.key,value:d.value,valueSpec:d.styleSpec.function,validateSpec:d.validateSpec,style:d.style,styleSpec:d.styleSpec,objectElementValidators:{stops:function(Ee){if(h==="identity")return[new Ct(Ee.key,Ee.value,'identity function may not have a "stops" property')];let De=[],ke=Ee.value;return De=De.concat(Mp({key:Ee.key,value:ke,valueSpec:Ee.valueSpec,validateSpec:Ee.validateSpec,style:Ee.style,styleSpec:Ee.styleSpec,arrayElementValidator:de})),Zo(ke)==="array"&&ke.length===0&&De.push(new Ct(Ee.key,ke,"array must have at least one stop")),De},default:function(Ee){return Ee.validateSpec({key:Ee.key,value:Ee.value,valueSpec:a,validateSpec:Ee.validateSpec,style:Ee.style,styleSpec:Ee.styleSpec})}}});return h==="identity"&&H&&ce.push(new Ct(d.key,d.value,'missing required property "property"')),h==="identity"||d.value.stops||ce.push(new Ct(d.key,d.value,'missing required property "stops"')),h==="exponential"&&d.valueSpec.expression&&!Fi(d.valueSpec)&&ce.push(new Ct(d.key,d.value,"exponential functions not supported")),d.styleSpec.$version>=8&&(Z&&!kl(d.valueSpec)?ce.push(new Ct(d.key,d.value,"property functions not supported")):H&&!Ip(d.valueSpec)&&ce.push(new Ct(d.key,d.value,"zoom functions not supported"))),h!=="categorical"&&!re||d.value.property!==void 0||ce.push(new Ct(d.key,d.value,'"property" property is required')),ce;function de(Ee){let De=[],ke=Ee.value,qe=Ee.key;if(Zo(ke)!=="array")return[new Ct(qe,ke,`array expected, ${Zo(ke)} found`)];if(ke.length!==2)return[new Ct(qe,ke,`array length 2 expected, length ${ke.length} found`)];if(re){if(Zo(ke[0])!=="object")return[new Ct(qe,ke,`object expected, ${Zo(ke[0])} found`)];if(ke[0].zoom===void 0)return[new Ct(qe,ke,"object stop key must have zoom")];if(ke[0].value===void 0)return[new Ct(qe,ke,"object stop key must have value")];if(D&&D>Ha(ke[0].zoom))return[new Ct(qe,ke[0].zoom,"stop zoom values must appear in ascending order")];Ha(ke[0].zoom)!==D&&(D=Ha(ke[0].zoom),C=void 0,O={}),De=De.concat(da({key:`${qe}[0]`,value:ke[0],valueSpec:{zoom:{}},validateSpec:Ee.validateSpec,style:Ee.style,styleSpec:Ee.styleSpec,objectElementValidators:{zoom:Yh,value:we}}))}else De=De.concat(we({key:`${qe}[0]`,value:ke[0],validateSpec:Ee.validateSpec,style:Ee.style,styleSpec:Ee.styleSpec},ke));return yh(As(ke[1]))?De.concat([new Ct(`${qe}[1]`,ke[1],"expressions are not allowed in function stops.")]):De.concat(Ee.validateSpec({key:`${qe}[1]`,value:ke[1],valueSpec:a,validateSpec:Ee.validateSpec,style:Ee.style,styleSpec:Ee.styleSpec}))}function we(Ee,De){let ke=Zo(Ee.value),qe=Ha(Ee.value),st=Ee.value!==null?Ee.value:De;if(A){if(ke!==A)return[new Ct(Ee.key,st,`${ke} stop domain type must match previous stop domain type ${A}`)]}else A=ke;if(ke!=="number"&&ke!=="string"&&ke!=="boolean")return[new Ct(Ee.key,st,"stop domain value must be a number, string, or boolean")];if(ke!=="number"&&h!=="categorical"){let kt=`number expected, ${ke} found`;return kl(a)&&h===void 0&&(kt+='\nIf you intended to use a categorical function, specify `"type": "categorical"`.'),[new Ct(Ee.key,st,kt)]}return h!=="categorical"||ke!=="number"||isFinite(qe)&&Math.floor(qe)===qe?h!=="categorical"&&ke==="number"&&C!==void 0&&qenew Ct(`${d.key}${A.key}`,d.value,A.message));let h=a.value.expression||a.value._styleExpression.expression;if(d.expressionContext==="property"&&d.propertyKey==="text-font"&&!h.outputDefined())return[new Ct(d.key,d.value,`Invalid data expression for "${d.propertyKey}". Output values must be contained as literals within the expression.`)];if(d.expressionContext==="property"&&d.propertyType==="layout"&&!Cc(h))return[new Ct(d.key,d.value,'"feature-state" data expressions are not supported with layout properties.')];if(d.expressionContext==="filter"&&!Cc(h))return[new Ct(d.key,d.value,'"feature-state" data expressions are not supported with filters.')];if(d.expressionContext&&d.expressionContext.indexOf("cluster")===0){if(!qd(h,["zoom","feature-state"]))return[new Ct(d.key,d.value,'"zoom" and "feature-state" expressions are not supported with cluster properties.')];if(d.expressionContext==="cluster-initial"&&!Yi(h))return[new Ct(d.key,d.value,"Feature data expressions are not supported with initial expression part of cluster properties.")]}return[]}function Rc(d){let a=d.key,h=d.value,A=Zo(h);return A!=="string"?[new Ct(a,h,`color expected, ${A} found`)]:Io.parse(String(h))?[]:[new Ct(a,h,`color expected, "${h}" found`)]}function vh(d){let a=d.key,h=d.value,A=d.valueSpec,C=[];return Array.isArray(A.values)?A.values.indexOf(Ha(h))===-1&&C.push(new Ct(a,h,`expected one of [${A.values.join(", ")}], ${JSON.stringify(h)} found`)):Object.keys(A.values).indexOf(Ha(h))===-1&&C.push(new Ct(a,h,`expected one of [${Object.keys(A.values).join(", ")}], ${JSON.stringify(h)} found`)),C}function _u(d){return xf(As(d.value))?_c(ei({},d,{expressionContext:"filter",valueSpec:{value:"boolean"}})):Zf(d)}function Zf(d){let a=d.value,h=d.key;if(Zo(a)!=="array")return[new Ct(h,a,`array expected, ${Zo(a)} found`)];let A=d.styleSpec,C,D=[];if(a.length<1)return[new Ct(h,a,"filter array must have at least 1 element")];switch(D=D.concat(vh({key:`${h}[0]`,value:a[0],valueSpec:A.filter_operator,style:d.style,styleSpec:d.styleSpec})),Ha(a[0])){case"<":case"<=":case">":case">=":a.length>=2&&Ha(a[1])==="$type"&&D.push(new Ct(h,a,`"$type" cannot be use with operator "${a[0]}"`));case"==":case"!=":a.length!==3&&D.push(new Ct(h,a,`filter array for operator "${a[0]}" must have 3 elements`));case"in":case"!in":a.length>=2&&(C=Zo(a[1]),C!=="string"&&D.push(new Ct(`${h}[1]`,a[1],`string expected, ${C} found`)));for(let O=2;O{re in h&&a.push(new Ct(A,h[re],`"${re}" is prohibited for ref layers`))}),C.layers.forEach(re=>{Ha(re.id)===H&&(Z=re)}),Z?Z.ref?a.push(new Ct(A,h.ref,"ref cannot reference another ref layer")):O=Ha(Z.type):a.push(new Ct(A,h.ref,`ref layer "${H}" not found`))}else if(O!=="background")if(h.source){let Z=C.sources&&C.sources[h.source],re=Z&&Ha(Z.type);Z?re==="vector"&&O==="raster"?a.push(new Ct(A,h.source,`layer "${h.id}" requires a raster source`)):re!=="raster-dem"&&O==="hillshade"||re!=="raster-dem"&&O==="color-relief"?a.push(new Ct(A,h.source,`layer "${h.id}" requires a raster-dem source`)):re==="raster"&&O!=="raster"?a.push(new Ct(A,h.source,`layer "${h.id}" requires a vector source`)):re!=="vector"||h["source-layer"]?re==="raster-dem"&&O!=="hillshade"&&O!=="color-relief"?a.push(new Ct(A,h.source,"raster-dem source can only be used with layer type 'hillshade' or 'color-relief'.")):O!=="line"||!h.paint||!h.paint["line-gradient"]||re==="geojson"&&Z.lineMetrics||a.push(new Ct(A,h,`layer "${h.id}" specifies a line-gradient, which requires a GeoJSON source with \`lineMetrics\` enabled.`)):a.push(new Ct(A,h,`layer "${h.id}" must specify a "source-layer"`)):a.push(new Ct(A,h.source,`source "${h.source}" not found`))}else a.push(new Ct(A,h,'missing required property "source"'));return a=a.concat(da({key:A,value:h,valueSpec:D.layer,style:d.style,styleSpec:d.styleSpec,validateSpec:d.validateSpec,objectElementValidators:{"*":()=>[],type:()=>d.validateSpec({key:`${A}.type`,value:h.type,valueSpec:D.layer.type,style:d.style,styleSpec:d.styleSpec,validateSpec:d.validateSpec,object:h,objectKey:"type"}),filter:_u,layout:Z=>da({layer:h,key:Z.key,value:Z.value,style:Z.style,styleSpec:Z.styleSpec,validateSpec:Z.validateSpec,objectElementValidators:{"*":re=>mm(ei({layerType:O},re))}}),paint:Z=>da({layer:h,key:Z.key,value:Z.value,style:Z.style,styleSpec:Z.styleSpec,validateSpec:Z.validateSpec,objectElementValidators:{"*":re=>xd(ei({layerType:O},re))}})}})),a}function Qu(d){let a=d.value,h=d.key,A=Zo(a);return A!=="string"?[new Ct(h,a,`string expected, ${A} found`)]:[]}let Yd={promoteId:function({key:d,value:a}){if(Zo(a)==="string")return Qu({key:d,value:a});{let h=[];for(let A in a)h.push(...Qu({key:`${d}.${A}`,value:a[A]}));return h}}};function Kh(d){let a=d.value,h=d.key,A=d.styleSpec,C=d.style,D=d.validateSpec;if(!a.type)return[new Ct(h,a,'"type" is required')];let O=Ha(a.type),H;switch(O){case"vector":case"raster":return H=da({key:h,value:a,valueSpec:A[`source_${O.replace("-","_")}`],style:d.style,styleSpec:A,objectElementValidators:Yd,validateSpec:D}),H;case"raster-dem":return H=function(Z){var re;let ce=(re=Z.sourceName)!==null&&re!==void 0?re:"",de=Z.value,we=Z.styleSpec,Ee=we.source_raster_dem,De=Z.style,ke=[],qe=Zo(de);if(de===void 0)return ke;if(qe!=="object")return ke.push(new Ct("source_raster_dem",de,`object expected, ${qe} found`)),ke;let st=Ha(de.encoding)==="custom",kt=["redFactor","greenFactor","blueFactor","baseShift"],pt=Z.value.encoding?`"${Z.value.encoding}"`:"Default";for(let _t in de)!st&&kt.includes(_t)?ke.push(new Ct(_t,de[_t],`In "${ce}": "${_t}" is only valid when "encoding" is set to "custom". ${pt} encoding found`)):Ee[_t]?ke=ke.concat(Z.validateSpec({key:_t,value:de[_t],valueSpec:Ee[_t],validateSpec:Z.validateSpec,style:De,styleSpec:we})):ke.push(new Ct(_t,de[_t],`unknown property "${_t}"`));return ke}({sourceName:h,value:a,style:d.style,styleSpec:A,validateSpec:D}),H;case"geojson":if(H=da({key:h,value:a,valueSpec:A.source_geojson,style:C,styleSpec:A,validateSpec:D,objectElementValidators:Yd}),a.cluster)for(let Z in a.clusterProperties){let[re,ce]=a.clusterProperties[Z],de=typeof re=="string"?[re,["accumulated"],["get",Z]]:re;H.push(..._c({key:`${h}.${Z}.map`,value:ce,expressionContext:"cluster-map"})),H.push(..._c({key:`${h}.${Z}.reduce`,value:de,expressionContext:"cluster-reduce"}))}return H;case"video":return da({key:h,value:a,valueSpec:A.source_video,style:C,validateSpec:D,styleSpec:A});case"image":return da({key:h,value:a,valueSpec:A.source_image,style:C,validateSpec:D,styleSpec:A});case"canvas":return[new Ct(h,null,"Please use runtime APIs to add canvas sources, rather than including them in stylesheets.","source.canvas")];default:return vh({key:`${h}.type`,value:a.type,valueSpec:{values:["vector","raster","raster-dem","geojson","video","image"]}})}}function bh(d){let a=d.value,h=d.styleSpec,A=h.light,C=d.style,D=[],O=Zo(a);if(a===void 0)return D;if(O!=="object")return D=D.concat([new Ct("light",a,`object expected, ${O} found`)]),D;for(let H in a){let Z=H.match(/^(.*)-transition$/);D=D.concat(Z&&A[Z[1]]&&A[Z[1]].transition?d.validateSpec({key:H,value:a[H],valueSpec:h.transition,validateSpec:d.validateSpec,style:C,styleSpec:h}):A[H]?d.validateSpec({key:H,value:a[H],valueSpec:A[H],validateSpec:d.validateSpec,style:C,styleSpec:h}):[new Ct(H,a[H],`unknown property "${H}"`)])}return D}function Rp(d){let a=d.value,h=d.styleSpec,A=h.sky,C=d.style,D=Zo(a);if(a===void 0)return[];if(D!=="object")return[new Ct("sky",a,`object expected, ${D} found`)];let O=[];for(let H in a)O=O.concat(A[H]?d.validateSpec({key:H,value:a[H],valueSpec:A[H],style:C,styleSpec:h}):[new Ct(H,a[H],`unknown property "${H}"`)]);return O}function bf(d){let a=d.value,h=d.styleSpec,A=h.terrain,C=d.style,D=[],O=Zo(a);if(a===void 0)return D;if(O!=="object")return D=D.concat([new Ct("terrain",a,`object expected, ${O} found`)]),D;for(let H in a)D=D.concat(A[H]?d.validateSpec({key:H,value:a[H],valueSpec:A[H],validateSpec:d.validateSpec,style:C,styleSpec:h}):[new Ct(H,a[H],`unknown property "${H}"`)]);return D}function Du(d){let a=[],h=d.value,A=d.key;if(Array.isArray(h)){let C=[],D=[];for(let O in h)h[O].id&&C.includes(h[O].id)&&a.push(new Ct(A,h,`all the sprites' ids must be unique, but ${h[O].id} is duplicated`)),C.push(h[O].id),h[O].url&&D.includes(h[O].url)&&a.push(new Ct(A,h,`all the sprites' URLs must be unique, but ${h[O].url} is duplicated`)),D.push(h[O].url),a=a.concat(da({key:`${A}[${O}]`,value:h[O],valueSpec:{id:{type:"string",required:!0},url:{type:"string",required:!0}},validateSpec:d.validateSpec}));return a}return Qu({key:A,value:h})}function Bp(d){return a=d.value,Boolean(a)&&a.constructor===Object?[]:[new Ct(d.key,d.value,`object expected, ${Zo(d.value)} found`)];var a}let Kd={"*":()=>[],array:Mp,boolean:function(d){let a=d.value,h=d.key,A=Zo(a);return A!=="boolean"?[new Ct(h,a,`boolean expected, ${A} found`)]:[]},number:Yh,color:Rc,constants:ng,enum:vh,filter:_u,function:Pp,layer:xh,object:da,source:Kh,light:bh,sky:Rp,terrain:bf,projection:function(d){let a=d.value,h=d.styleSpec,A=h.projection,C=d.style,D=Zo(a);if(a===void 0)return[];if(D!=="object")return[new Ct("projection",a,`object expected, ${D} found`)];let O=[];for(let H in a)O=O.concat(A[H]?d.validateSpec({key:H,value:a[H],valueSpec:A[H],style:C,styleSpec:h}):[new Ct(H,a[H],`unknown property "${H}"`)]);return O},projectionDefinition:function(d){let a=d.key,h=d.value;h=h instanceof String?h.valueOf():h;let A=Zo(h);return A!=="array"||function(C){return Array.isArray(C)&&C.length===3&&typeof C[0]=="string"&&typeof C[1]=="string"&&typeof C[2]=="number"}(h)||function(C){return!!["interpolate","step","literal"].includes(C[0])}(h)?["array","string"].includes(A)?[]:[new Ct(a,h,`projection expected, invalid type "${A}" found`)]:[new Ct(a,h,`projection expected, invalid array ${JSON.stringify(h)} found`)]},string:Qu,formatted:function(d){return Qu(d).length===0?[]:_c(d)},resolvedImage:function(d){return Qu(d).length===0?[]:_c(d)},padding:function(d){let a=d.key,h=d.value;if(Zo(h)==="array"){if(h.length<1||h.length>4)return[new Ct(a,h,`padding requires 1 to 4 values; ${h.length} values found`)];let A={type:"number"},C=[];for(let D=0;D[]}})),d.constants&&(h=h.concat(ng({key:"constants",value:d.constants}))),S(h)}function M(d){return function(a){return d(Object.assign({},a,{validateSpec:Yf}))}}function S(d){return[].concat(d).sort((a,h)=>a.line-h.line)}function L(d){return function(...a){return S(d.apply(this,a))}}w.source=L(M(Kh)),w.sprite=L(M(Du)),w.glyphs=L(M(Qh)),w.light=L(M(bh)),w.sky=L(M(Rp)),w.terrain=L(M(bf)),w.state=L(M(Bp)),w.layer=L(M(xh)),w.filter=L(M(_u)),w.paintProperty=L(M(xd)),w.layoutProperty=L(M(mm));let Y=wr,ie=w,ae=ie.light,ge=ie.sky,Pe=ie.paintProperty,Ue=ie.layoutProperty;function ct(d,a){let h=!1;if(a&&a.length)for(let A of a)d.fire(new bs(new Error(A.message))),h=!0;return h}class ft{constructor(a,h,A){let C=this.cells=[];if(a instanceof ArrayBuffer){this.arrayBuffer=a;let O=new Int32Array(this.arrayBuffer);a=O[0],this.d=(h=O[1])+2*(A=O[2]);for(let Z=0;Z=de[De+0]&&C>=de[De+1])?(H[Ee]=!0,O.push(ce[Ee])):H[Ee]=!1}}}}_forEachCell(a,h,A,C,D,O,H,Z){let re=this._convertToCellCoord(a),ce=this._convertToCellCoord(h),de=this._convertToCellCoord(A),we=this._convertToCellCoord(C);for(let Ee=re;Ee<=de;Ee++)for(let De=ce;De<=we;De++){let ke=this.d*De+Ee;if((!Z||Z(this._convertFromCellCoord(Ee),this._convertFromCellCoord(De),this._convertFromCellCoord(Ee+1),this._convertFromCellCoord(De+1)))&&D.call(this,a,h,A,C,ke,O,H,Z))return}}_convertFromCellCoord(a){return(a-this.padding)/this.scale}_convertToCellCoord(a){return Math.max(0,Math.min(this.d-1,Math.floor(a*this.scale)+this.padding))}toArrayBuffer(){if(this.arrayBuffer)return this.arrayBuffer;let a=this.cells,h=3+this.cells.length+1+1,A=0;for(let O=0;O=0)continue;let O=d[D];C[D]=gt[h].shallow.indexOf(D)>=0?O:Zt(O,a)}d instanceof Error&&(C.message=d.message)}if(C.$name)throw new Error("$name property is reserved for worker serialization logic.");return h!=="Object"&&(C.$name=h),C}function ir(d){if(St(d))return d;if(Array.isArray(d))return d.map(ir);if(typeof d!="object")throw new Error("can't deserialize object of type "+typeof d);let a=Wt(d)||"Object";if(!gt[a])throw new Error(`can't deserialize unregistered class ${a}`);let{klass:h}=gt[a];if(!h)throw new Error(`can't deserialize unregistered class ${a}`);if(h.deserialize)return h.deserialize(d);let A=Object.create(h.prototype);for(let C of Object.keys(d)){if(C==="$name")continue;let D=d[C];A[C]=gt[a].shallow.indexOf(C)>=0?D:ir(D)}return A}class dr{constructor(){this.first=!0}update(a,h){let A=Math.floor(a);return this.first?(this.first=!1,this.lastIntegerZoom=A,this.lastIntegerZoomTime=0,this.lastZoom=a,this.lastFloorZoom=A,!0):(this.lastFloorZoom>A?(this.lastIntegerZoom=A+1,this.lastIntegerZoomTime=h):this.lastFloorZoom{try{return new RegExp(`\\p{sc=${h}}`,"u").source}catch{return null}}).filter(h=>h);return new RegExp(a.join("|"),"u")}let $i=Si(["Arab","Dupl","Mong","Ougr","Syrc"]);function bn(d){return!$i.test(String.fromCodePoint(d))}function Tn(d){return!(Lr(d)||(a=d,/[\xA7\xA9\xAE\xB1\xBC-\xBE\xD7\xF7\u2016\u2020\u2021\u2030\u2031\u203B\u203C\u2042\u2047-\u2049\u2051\u2100-\u218F\u221E\u2234\u2235\u2300-\u2307\u230C-\u231F\u2324-\u2328\u232B\u237D-\u239A\u23BE-\u23CD\u23CF\u23D1-\u23DB\u23E2-\u2422\u2424-\u24FF\u25A0-\u2619\u2620-\u2767\u2776-\u2793\u2B12-\u2B2F\u2B50-\u2B59\u2BB8-\u2BEB\u3000-\u303F\u30A0-\u30FF\uE000-\uF8FF\uFE30-\uFE6F\uFF00-\uFFEF\uFFFC\uFFFD]|[\uDB80-\uDBFF][\uDC00-\uDFFF]/gim.test(String.fromCodePoint(a))));var a}let xn=Si(["Adlm","Arab","Armi","Avst","Chrs","Cprt","Egyp","Elym","Gara","Hatr","Hebr","Hung","Khar","Lydi","Mand","Mani","Mend","Merc","Mero","Narb","Nbat","Nkoo","Orkh","Palm","Phli","Phlp","Phnx","Prti","Rohg","Samr","Sarb","Sogo","Syrc","Thaa","Todr","Yezi"]);function zo(d){return xn.test(String.fromCodePoint(d))}function qi(d,a){return!(!a&&zo(d)||/[\u0900-\u0DFF\u0F00-\u109F\u1780-\u17FF]/gim.test(String.fromCodePoint(d)))}function Sn(d){for(let a of d)if(zo(a.codePointAt(0)))return!0;return!1}let $n=new class{constructor(){this.TIMEOUT=5e3,this.applyArabicShaping=null,this.processBidirectionalText=null,this.processStyledBidirectionalText=null,this.pluginStatus="unavailable",this.pluginURL=null,this.loadScriptResolve=()=>{}}setState(d){this.pluginStatus=d.pluginStatus,this.pluginURL=d.pluginURL}getState(){return{pluginStatus:this.pluginStatus,pluginURL:this.pluginURL}}setMethods(d){if($n.isParsed())throw new Error("RTL text plugin already registered.");this.applyArabicShaping=d.applyArabicShaping,this.processBidirectionalText=d.processBidirectionalText,this.processStyledBidirectionalText=d.processStyledBidirectionalText,this.loadScriptResolve()}isParsed(){return this.applyArabicShaping!=null&&this.processBidirectionalText!=null&&this.processStyledBidirectionalText!=null}getRTLTextPluginStatus(){return this.pluginStatus}syncState(d,a){return o(this,void 0,void 0,function*(){if(this.isParsed())return this.getState();if(d.pluginStatus!=="loading")return this.setState(d),d;let h=d.pluginURL,A=new Promise(D=>{this.loadScriptResolve=D});a(h);let C=new Promise(D=>setTimeout(()=>D(),this.TIMEOUT));if(yield Promise.race([A,C]),this.isParsed()){let D={pluginStatus:"loaded",pluginURL:h};return this.setState(D),D}throw this.setState({pluginStatus:"error",pluginURL:""}),new Error(`RTL Text Plugin failed to import scripts from ${h}`)})}};class Gi{constructor(a,h){this.isSupportedScript=Hn,this.zoom=a,h?(this.now=h.now||0,this.fadeDuration=h.fadeDuration||0,this.zoomHistory=h.zoomHistory||new dr,this.transition=h.transition||{}):(this.now=0,this.fadeDuration=0,this.zoomHistory=new dr,this.transition={})}crossFadingFactor(){return this.fadeDuration===0?1:Math.min((this.now-this.zoomHistory.lastIntegerZoomTime)/this.fadeDuration,1)}getCrossfadeParameters(){let a=this.zoom,h=a-Math.floor(a),A=this.crossFadingFactor();return a>this.zoomHistory.lastIntegerZoom?{fromScale:2,toScale:1,t:h+(1-h)*A}:{fromScale:.5,toScale:1,t:1-(1-A)*h}}}function Hn(d){return function(a,h){for(let A of a)if(!qi(A.codePointAt(0),h))return!1;return!0}(d,$n.getRTLTextPluginStatus()==="loaded")}let eo="-transition";class Dn{constructor(a,h,A){this.property=a,this.value=h,this.expression=function(C,D,O){if(vd(C))return new So(C,D);if(yh(C)){let H=gu(C,D,O);if(H.result==="error")throw new Error(H.value.map(Z=>`${Z.key}: ${Z.message}`).join(", "));return H.value}{let H=C;return D.type==="color"&&typeof C=="string"?H=Io.parse(C):D.type!=="padding"||typeof C!="number"&&!Array.isArray(C)?D.type!=="numberArray"||typeof C!="number"&&!Array.isArray(C)?D.type!=="colorArray"||typeof C!="string"&&!Array.isArray(C)?D.type==="variableAnchorOffsetCollection"&&Array.isArray(C)?H=sl.parse(C):D.type==="projectionDefinition"&&typeof C=="string"&&(H=vl.parse(C)):H=Zn.parse(C):H=_a.parse(C):H=Jl.parse(C),{globalStateRefs:new Set,_globalState:null,kind:"constant",evaluate:()=>H}}}(h===void 0?a.specification.default:h,a.specification,A)}isDataDriven(){return this.expression.kind==="source"||this.expression.kind==="composite"}getGlobalStateRefs(){return this.expression.globalStateRefs||new Set}possiblyEvaluate(a,h,A){return this.property.possiblyEvaluate(this,a,h,A)}}class Rn{constructor(a,h){this.property=a,this.value=new Dn(a,void 0,h)}transitioned(a,h){return new Ga(this.property,this.value,h,Ve({},a.transition,this.transition),a.now)}untransitioned(){return new Ga(this.property,this.value,null,{},0)}}class Il{constructor(a,h){this._properties=a,this._values=Object.create(a.defaultTransitionablePropertyValues),this._globalState=h}getValue(a){return Xr(this._values[a].value.value)}setValue(a,h){Object.prototype.hasOwnProperty.call(this._values,a)||(this._values[a]=new Rn(this._values[a].property,this._globalState)),this._values[a].value=new Dn(this._values[a].property,h===null?void 0:Xr(h),this._globalState)}getTransition(a){return Xr(this._values[a].transition)}setTransition(a,h){Object.prototype.hasOwnProperty.call(this._values,a)||(this._values[a]=new Rn(this._values[a].property,this._globalState)),this._values[a].transition=Xr(h)||void 0}serialize(){let a={};for(let h of Object.keys(this._values)){let A=this.getValue(h);A!==void 0&&(a[h]=A);let C=this.getTransition(h);C!==void 0&&(a[`${h}${eo}`]=C)}return a}transitioned(a,h){let A=new yc(this._properties);for(let C of Object.keys(this._values))A._values[C]=this._values[C].transitioned(a,h._values[C]);return A}untransitioned(){let a=new yc(this._properties);for(let h of Object.keys(this._values))a._values[h]=this._values[h].untransitioned();return a}}class Ga{constructor(a,h,A,C,D){this.property=a,this.value=h,this.begin=D+C.delay||0,this.end=this.begin+C.duration||0,a.specification.transition&&(C.delay||C.duration)&&(this.prior=A)}possiblyEvaluate(a,h,A){let C=a.now||0,D=this.value.possiblyEvaluate(a,h,A),O=this.prior;if(O){if(C>this.end)return this.prior=null,D;if(this.value.isDataDriven())return this.prior=null,D;if(CC.zoomHistory.lastIntegerZoom?{from:a,to:h}:{from:A,to:h}}interpolate(a){return a}}class jc{constructor(a){this.specification=a}possiblyEvaluate(a,h,A,C){if(a.value!==void 0){if(a.expression.kind==="constant"){let D=a.expression.evaluate(h,null,{},A,C);return this._calculate(D,D,D,h)}return this._calculate(a.expression.evaluate(new Gi(Math.floor(h.zoom-1),h)),a.expression.evaluate(new Gi(Math.floor(h.zoom),h)),a.expression.evaluate(new Gi(Math.floor(h.zoom+1),h)),h)}}_calculate(a,h,A,C){return C.zoom>C.zoomHistory.lastIntegerZoom?{from:a,to:h}:{from:A,to:h}}interpolate(a){return a}}class Hc{constructor(a){this.specification=a}possiblyEvaluate(a,h,A,C){return!!a.expression.evaluate(h,null,{},A,C)}interpolate(){return!1}}class Fa{constructor(a){this.properties=a,this.defaultPropertyValues={},this.defaultTransitionablePropertyValues={},this.defaultTransitioningPropertyValues={},this.defaultPossiblyEvaluatedValues={},this.overridableProperties=[];for(let h in a){let A=a[h];A.specification.overridable&&this.overridableProperties.push(h);let C=this.defaultPropertyValues[h]=new Dn(A,void 0,void 0),D=this.defaultTransitionablePropertyValues[h]=new Rn(A,void 0);this.defaultTransitioningPropertyValues[h]=D.untransitioned(),this.defaultPossiblyEvaluatedValues[h]=C.possiblyEvaluate({})}}}ut("DataDrivenProperty",_n),ut("DataConstantProperty",tn),ut("CrossFadedDataDrivenProperty",Ju),ut("CrossFadedProperty",jc),ut("ColorRampProperty",Hc);class Gc extends go{constructor(a,h,A){if(super(),this.id=a.id,this.type=a.type,this._globalState=A,this._featureFilter={filter:()=>!0,needGeometry:!1,getGlobalStateRefs:()=>new Set},a.type!=="custom"&&(this.metadata=a.metadata,this.minzoom=a.minzoom,this.maxzoom=a.maxzoom,a.type!=="background"&&(this.source=a.source,this.sourceLayer=a["source-layer"],this.filter=a.filter,this._featureFilter=Pc(a.filter,A)),h.layout&&(this._unevaluatedLayout=new cl(h.layout,A)),h.paint)){this._transitionablePaint=new Il(h.paint,A);for(let C in a.paint)this.setPaintProperty(C,a.paint[C],{validate:!1});for(let C in a.layout)this.setLayoutProperty(C,a.layout[C],{validate:!1});this._transitioningPaint=this._transitionablePaint.untransitioned(),this.paint=new Ta(h.paint)}}setFilter(a){this.filter=a,this._featureFilter=Pc(a,this._globalState)}getCrossfadeParameters(){return this._crossfadeParameters}getLayoutProperty(a){return a==="visibility"?this.visibility:this._unevaluatedLayout.getValue(a)}getLayoutAffectingGlobalStateRefs(){let a=new Set;if(this._unevaluatedLayout)for(let h in this._unevaluatedLayout._values){let A=this._unevaluatedLayout._values[h];for(let C of A.getGlobalStateRefs())a.add(C)}for(let h of this._featureFilter.getGlobalStateRefs())a.add(h);return a}getPaintAffectingGlobalStateRefs(){var a;let h=new globalThis.Map;if(this._transitionablePaint)for(let A in this._transitionablePaint._values){let C=this._transitionablePaint._values[A].value;for(let D of C.getGlobalStateRefs()){let O=(a=h.get(D))!==null&&a!==void 0?a:[];O.push({name:A,value:C.value}),h.set(D,O)}}return h}setLayoutProperty(a,h,A={}){h!=null&&this._validate(Ue,`layers.${this.id}.layout.${a}`,a,h,A)||(a!=="visibility"?this._unevaluatedLayout.setValue(a,h):this.visibility=h)}getPaintProperty(a){return a.endsWith(eo)?this._transitionablePaint.getTransition(a.slice(0,-11)):this._transitionablePaint.getValue(a)}setPaintProperty(a,h,A={}){if(h!=null&&this._validate(Pe,`layers.${this.id}.paint.${a}`,a,h,A))return!1;if(a.endsWith(eo))return this._transitionablePaint.setTransition(a.slice(0,-11),h||void 0),!1;{let C=this._transitionablePaint._values[a],D=C.property.specification["property-type"]==="cross-faded-data-driven",O=C.value.isDataDriven(),H=C.value;this._transitionablePaint.setValue(a,h),this._handleSpecialPaintPropertyUpdate(a);let Z=this._transitionablePaint._values[a].value;return Z.isDataDriven()||O||D||this._handleOverridablePaintPropertyUpdate(a,H,Z)}}_handleSpecialPaintPropertyUpdate(a){}_handleOverridablePaintPropertyUpdate(a,h,A){return!1}isHidden(a,h=!1){return!!(this.minzoom&&a<(h?Math.floor(this.minzoom):this.minzoom))||!!(this.maxzoom&&a>=this.maxzoom)||this.visibility==="none"}updateTransitions(a){this._transitioningPaint=this._transitionablePaint.transitioned(a,this._transitioningPaint)}hasTransition(){return this._transitioningPaint.hasTransition()}recalculate(a,h){a.getCrossfadeParameters&&(this._crossfadeParameters=a.getCrossfadeParameters()),this._unevaluatedLayout&&(this.layout=this._unevaluatedLayout.possiblyEvaluate(a,void 0,h)),this.paint=this._transitioningPaint.possiblyEvaluate(a,void 0,h)}serialize(){let a={id:this.id,type:this.type,source:this.source,"source-layer":this.sourceLayer,metadata:this.metadata,minzoom:this.minzoom,maxzoom:this.maxzoom,filter:this.filter,layout:this._unevaluatedLayout&&this._unevaluatedLayout.serialize(),paint:this._transitionablePaint&&this._transitionablePaint.serialize()};return this.visibility&&(a.layout=a.layout||{},a.layout.visibility=this.visibility),mr(a,(h,A)=>!(h===void 0||A==="layout"&&!Object.keys(h).length||A==="paint"&&!Object.keys(h).length))}_validate(a,h,A,C,D={}){return(!D||D.validate!==!1)&&ct(this,a.call(ie,{key:h,layerType:this.type,objectKey:A,value:C,styleSpec:wr,style:{glyphs:!0,sprite:!0}}))}is3D(){return!1}isTileClipped(){return!1}hasOffscreenPass(){return!1}resize(){}isStateDependent(){for(let a in this.paint._values){let h=this.paint.get(a);if(h instanceof Vs&&kl(h.property.specification)&&(h.value.kind==="source"||h.value.kind==="composite")&&h.value.isStateDependent)return!0}return!1}}let bd;var wd={get paint(){return bd=bd||new Fa({"raster-opacity":new tn(wr.paint_raster["raster-opacity"]),"raster-hue-rotate":new tn(wr.paint_raster["raster-hue-rotate"]),"raster-brightness-min":new tn(wr.paint_raster["raster-brightness-min"]),"raster-brightness-max":new tn(wr.paint_raster["raster-brightness-max"]),"raster-saturation":new tn(wr.paint_raster["raster-saturation"]),"raster-contrast":new tn(wr.paint_raster["raster-contrast"]),"raster-resampling":new tn(wr.paint_raster["raster-resampling"]),"raster-fade-duration":new tn(wr.paint_raster["raster-fade-duration"])})}};class Td extends Gc{constructor(a,h){super(a,wd,h)}}let Ou={Int8:Int8Array,Uint8:Uint8Array,Int16:Int16Array,Uint16:Uint16Array,Int32:Int32Array,Uint32:Uint32Array,Float32:Float32Array};class iu{constructor(a,h){this._structArray=a,this._pos1=h*this.size,this._pos2=this._pos1/2,this._pos4=this._pos1/4,this._pos8=this._pos1/8}}class Sa{constructor(){this.isTransferred=!1,this.capacity=-1,this.resize(0)}static serialize(a,h){return a._trim(),h&&(a.isTransferred=!0,h.push(a.arrayBuffer)),{length:a.length,arrayBuffer:a.arrayBuffer}}static deserialize(a){let h=Object.create(this.prototype);return h.arrayBuffer=a.arrayBuffer,h.length=a.length,h.capacity=a.arrayBuffer.byteLength/h.bytesPerElement,h._refreshViews(),h}_trim(){this.length!==this.capacity&&(this.capacity=this.length,this.arrayBuffer=this.arrayBuffer.slice(0,this.length*this.bytesPerElement),this._refreshViews())}clear(){this.length=0}resize(a){this.reserve(a),this.length=a}reserve(a){if(a>this.capacity){this.capacity=Math.max(a,Math.floor(5*this.capacity),128),this.arrayBuffer=new ArrayBuffer(this.capacity*this.bytesPerElement);let h=this.uint8;this._refreshViews(),h&&this.uint8.set(h)}}_refreshViews(){throw new Error("_refreshViews() must be implemented by each concrete StructArray layout")}}function na(d,a=1){let h=0,A=0;return{members:d.map(C=>{let D=Ou[C.type].BYTES_PER_ELEMENT,O=h=zl(h,Math.max(a,D)),H=C.components||1;return A=Math.max(A,D),h+=D*H,{name:C.name,type:C.type,components:H,offset:O}}),size:zl(h,Math.max(A,a)),alignment:a}}function zl(d,a){return Math.ceil(d/a)*a}class eh extends Sa{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer)}emplaceBack(a,h){let A=this.length;return this.resize(A+1),this.emplace(A,a,h)}emplace(a,h,A){let C=2*a;return this.int16[C+0]=h,this.int16[C+1]=A,a}}eh.prototype.bytesPerElement=4,ut("StructArrayLayout2i4",eh);class Jh extends Sa{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer)}emplaceBack(a,h,A){let C=this.length;return this.resize(C+1),this.emplace(C,a,h,A)}emplace(a,h,A,C){let D=3*a;return this.int16[D+0]=h,this.int16[D+1]=A,this.int16[D+2]=C,a}}Jh.prototype.bytesPerElement=6,ut("StructArrayLayout3i6",Jh);class Ul extends Sa{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer)}emplaceBack(a,h,A,C){let D=this.length;return this.resize(D+1),this.emplace(D,a,h,A,C)}emplace(a,h,A,C,D){let O=4*a;return this.int16[O+0]=h,this.int16[O+1]=A,this.int16[O+2]=C,this.int16[O+3]=D,a}}Ul.prototype.bytesPerElement=8,ut("StructArrayLayout4i8",Ul);class _s extends Sa{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer)}emplaceBack(a,h,A,C,D,O){let H=this.length;return this.resize(H+1),this.emplace(H,a,h,A,C,D,O)}emplace(a,h,A,C,D,O,H){let Z=6*a;return this.int16[Z+0]=h,this.int16[Z+1]=A,this.int16[Z+2]=C,this.int16[Z+3]=D,this.int16[Z+4]=O,this.int16[Z+5]=H,a}}_s.prototype.bytesPerElement=12,ut("StructArrayLayout2i4i12",_s);class yu extends Sa{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer)}emplaceBack(a,h,A,C,D,O){let H=this.length;return this.resize(H+1),this.emplace(H,a,h,A,C,D,O)}emplace(a,h,A,C,D,O,H){let Z=4*a,re=8*a;return this.int16[Z+0]=h,this.int16[Z+1]=A,this.uint8[re+4]=C,this.uint8[re+5]=D,this.uint8[re+6]=O,this.uint8[re+7]=H,a}}yu.prototype.bytesPerElement=8,ut("StructArrayLayout2i4ub8",yu);class Ml extends Sa{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.float32=new Float32Array(this.arrayBuffer)}emplaceBack(a,h){let A=this.length;return this.resize(A+1),this.emplace(A,a,h)}emplace(a,h,A){let C=2*a;return this.float32[C+0]=h,this.float32[C+1]=A,a}}Ml.prototype.bytesPerElement=8,ut("StructArrayLayout2f8",Ml);class ef extends Sa{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer)}emplaceBack(a,h,A,C,D,O,H,Z,re,ce){let de=this.length;return this.resize(de+1),this.emplace(de,a,h,A,C,D,O,H,Z,re,ce)}emplace(a,h,A,C,D,O,H,Z,re,ce,de){let we=10*a;return this.uint16[we+0]=h,this.uint16[we+1]=A,this.uint16[we+2]=C,this.uint16[we+3]=D,this.uint16[we+4]=O,this.uint16[we+5]=H,this.uint16[we+6]=Z,this.uint16[we+7]=re,this.uint16[we+8]=ce,this.uint16[we+9]=de,a}}ef.prototype.bytesPerElement=20,ut("StructArrayLayout10ui20",ef);class t0 extends Sa{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer)}emplaceBack(a,h,A,C,D,O,H,Z){let re=this.length;return this.resize(re+1),this.emplace(re,a,h,A,C,D,O,H,Z)}emplace(a,h,A,C,D,O,H,Z,re){let ce=8*a;return this.uint16[ce+0]=h,this.uint16[ce+1]=A,this.uint16[ce+2]=C,this.uint16[ce+3]=D,this.uint16[ce+4]=O,this.uint16[ce+5]=H,this.uint16[ce+6]=Z,this.uint16[ce+7]=re,a}}t0.prototype.bytesPerElement=16,ut("StructArrayLayout8ui16",t0);class Lp extends Sa{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer)}emplaceBack(a,h,A,C,D,O,H,Z,re,ce,de,we){let Ee=this.length;return this.resize(Ee+1),this.emplace(Ee,a,h,A,C,D,O,H,Z,re,ce,de,we)}emplace(a,h,A,C,D,O,H,Z,re,ce,de,we,Ee){let De=12*a;return this.int16[De+0]=h,this.int16[De+1]=A,this.int16[De+2]=C,this.int16[De+3]=D,this.uint16[De+4]=O,this.uint16[De+5]=H,this.uint16[De+6]=Z,this.uint16[De+7]=re,this.int16[De+8]=ce,this.int16[De+9]=de,this.int16[De+10]=we,this.int16[De+11]=Ee,a}}Lp.prototype.bytesPerElement=24,ut("StructArrayLayout4i4ui4i24",Lp);class th extends Sa{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.float32=new Float32Array(this.arrayBuffer)}emplaceBack(a,h,A){let C=this.length;return this.resize(C+1),this.emplace(C,a,h,A)}emplace(a,h,A,C){let D=3*a;return this.float32[D+0]=h,this.float32[D+1]=A,this.float32[D+2]=C,a}}th.prototype.bytesPerElement=12,ut("StructArrayLayout3f12",th);class Kf extends Sa{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.uint32=new Uint32Array(this.arrayBuffer)}emplaceBack(a){let h=this.length;return this.resize(h+1),this.emplace(h,a)}emplace(a,h){return this.uint32[1*a+0]=h,a}}Kf.prototype.bytesPerElement=4,ut("StructArrayLayout1ul4",Kf);class wf extends Sa{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer),this.uint32=new Uint32Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer)}emplaceBack(a,h,A,C,D,O,H,Z,re){let ce=this.length;return this.resize(ce+1),this.emplace(ce,a,h,A,C,D,O,H,Z,re)}emplace(a,h,A,C,D,O,H,Z,re,ce){let de=10*a,we=5*a;return this.int16[de+0]=h,this.int16[de+1]=A,this.int16[de+2]=C,this.int16[de+3]=D,this.int16[de+4]=O,this.int16[de+5]=H,this.uint32[we+3]=Z,this.uint16[de+8]=re,this.uint16[de+9]=ce,a}}wf.prototype.bytesPerElement=20,ut("StructArrayLayout6i1ul2ui20",wf);class tf extends Sa{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer)}emplaceBack(a,h,A,C,D,O){let H=this.length;return this.resize(H+1),this.emplace(H,a,h,A,C,D,O)}emplace(a,h,A,C,D,O,H){let Z=6*a;return this.int16[Z+0]=h,this.int16[Z+1]=A,this.int16[Z+2]=C,this.int16[Z+3]=D,this.int16[Z+4]=O,this.int16[Z+5]=H,a}}tf.prototype.bytesPerElement=12,ut("StructArrayLayout2i2i2i12",tf);class Tf extends Sa{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.float32=new Float32Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer)}emplaceBack(a,h,A,C,D){let O=this.length;return this.resize(O+1),this.emplace(O,a,h,A,C,D)}emplace(a,h,A,C,D,O){let H=4*a,Z=8*a;return this.float32[H+0]=h,this.float32[H+1]=A,this.float32[H+2]=C,this.int16[Z+6]=D,this.int16[Z+7]=O,a}}Tf.prototype.bytesPerElement=16,ut("StructArrayLayout2f1f2i16",Tf);class og extends Sa{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.float32=new Float32Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer)}emplaceBack(a,h,A,C,D,O){let H=this.length;return this.resize(H+1),this.emplace(H,a,h,A,C,D,O)}emplace(a,h,A,C,D,O,H){let Z=16*a,re=4*a,ce=8*a;return this.uint8[Z+0]=h,this.uint8[Z+1]=A,this.float32[re+1]=C,this.float32[re+2]=D,this.int16[ce+6]=O,this.int16[ce+7]=H,a}}og.prototype.bytesPerElement=16,ut("StructArrayLayout2ub2f2i16",og);class Fu extends Sa{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer)}emplaceBack(a,h,A){let C=this.length;return this.resize(C+1),this.emplace(C,a,h,A)}emplace(a,h,A,C){let D=3*a;return this.uint16[D+0]=h,this.uint16[D+1]=A,this.uint16[D+2]=C,a}}Fu.prototype.bytesPerElement=6,ut("StructArrayLayout3ui6",Fu);class Vl extends Sa{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer),this.uint32=new Uint32Array(this.arrayBuffer),this.float32=new Float32Array(this.arrayBuffer)}emplaceBack(a,h,A,C,D,O,H,Z,re,ce,de,we,Ee,De,ke,qe,st){let kt=this.length;return this.resize(kt+1),this.emplace(kt,a,h,A,C,D,O,H,Z,re,ce,de,we,Ee,De,ke,qe,st)}emplace(a,h,A,C,D,O,H,Z,re,ce,de,we,Ee,De,ke,qe,st,kt){let pt=24*a,_t=12*a,Ht=48*a;return this.int16[pt+0]=h,this.int16[pt+1]=A,this.uint16[pt+2]=C,this.uint16[pt+3]=D,this.uint32[_t+2]=O,this.uint32[_t+3]=H,this.uint32[_t+4]=Z,this.uint16[pt+10]=re,this.uint16[pt+11]=ce,this.uint16[pt+12]=de,this.float32[_t+7]=we,this.float32[_t+8]=Ee,this.uint8[Ht+36]=De,this.uint8[Ht+37]=ke,this.uint8[Ht+38]=qe,this.uint32[_t+10]=st,this.int16[pt+22]=kt,a}}Vl.prototype.bytesPerElement=48,ut("StructArrayLayout2i2ui3ul3ui2f3ub1ul1i48",Vl);class M_ extends Sa{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer),this.uint32=new Uint32Array(this.arrayBuffer),this.float32=new Float32Array(this.arrayBuffer)}emplaceBack(a,h,A,C,D,O,H,Z,re,ce,de,we,Ee,De,ke,qe,st,kt,pt,_t,Ht,Qt,Ir,oi,Kr,gi,ji,vi){let Qr=this.length;return this.resize(Qr+1),this.emplace(Qr,a,h,A,C,D,O,H,Z,re,ce,de,we,Ee,De,ke,qe,st,kt,pt,_t,Ht,Qt,Ir,oi,Kr,gi,ji,vi)}emplace(a,h,A,C,D,O,H,Z,re,ce,de,we,Ee,De,ke,qe,st,kt,pt,_t,Ht,Qt,Ir,oi,Kr,gi,ji,vi,Qr){let jr=32*a,dn=16*a;return this.int16[jr+0]=h,this.int16[jr+1]=A,this.int16[jr+2]=C,this.int16[jr+3]=D,this.int16[jr+4]=O,this.int16[jr+5]=H,this.int16[jr+6]=Z,this.int16[jr+7]=re,this.uint16[jr+8]=ce,this.uint16[jr+9]=de,this.uint16[jr+10]=we,this.uint16[jr+11]=Ee,this.uint16[jr+12]=De,this.uint16[jr+13]=ke,this.uint16[jr+14]=qe,this.uint16[jr+15]=st,this.uint16[jr+16]=kt,this.uint16[jr+17]=pt,this.uint16[jr+18]=_t,this.uint16[jr+19]=Ht,this.uint16[jr+20]=Qt,this.uint16[jr+21]=Ir,this.uint16[jr+22]=oi,this.uint32[dn+12]=Kr,this.float32[dn+13]=gi,this.float32[dn+14]=ji,this.uint16[jr+30]=vi,this.uint16[jr+31]=Qr,a}}M_.prototype.bytesPerElement=64,ut("StructArrayLayout8i15ui1ul2f2ui64",M_);class sg extends Sa{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.float32=new Float32Array(this.arrayBuffer)}emplaceBack(a){let h=this.length;return this.resize(h+1),this.emplace(h,a)}emplace(a,h){return this.float32[1*a+0]=h,a}}sg.prototype.bytesPerElement=4,ut("StructArrayLayout1f4",sg);class gm extends Sa{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer),this.float32=new Float32Array(this.arrayBuffer)}emplaceBack(a,h,A){let C=this.length;return this.resize(C+1),this.emplace(C,a,h,A)}emplace(a,h,A,C){let D=3*a;return this.uint16[6*a+0]=h,this.float32[D+1]=A,this.float32[D+2]=C,a}}gm.prototype.bytesPerElement=12,ut("StructArrayLayout1ui2f12",gm);class P_ extends Sa{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.uint32=new Uint32Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer)}emplaceBack(a,h,A){let C=this.length;return this.resize(C+1),this.emplace(C,a,h,A)}emplace(a,h,A,C){let D=4*a;return this.uint32[2*a+0]=h,this.uint16[D+2]=A,this.uint16[D+3]=C,a}}P_.prototype.bytesPerElement=8,ut("StructArrayLayout1ul2ui8",P_);class R_ extends Sa{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer)}emplaceBack(a,h){let A=this.length;return this.resize(A+1),this.emplace(A,a,h)}emplace(a,h,A){let C=2*a;return this.uint16[C+0]=h,this.uint16[C+1]=A,a}}R_.prototype.bytesPerElement=4,ut("StructArrayLayout2ui4",R_);class tA extends Sa{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer)}emplaceBack(a){let h=this.length;return this.resize(h+1),this.emplace(h,a)}emplace(a,h){return this.uint16[1*a+0]=h,a}}tA.prototype.bytesPerElement=2,ut("StructArrayLayout1ui2",tA);class r0 extends Sa{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.float32=new Float32Array(this.arrayBuffer)}emplaceBack(a,h,A,C){let D=this.length;return this.resize(D+1),this.emplace(D,a,h,A,C)}emplace(a,h,A,C,D){let O=4*a;return this.float32[O+0]=h,this.float32[O+1]=A,this.float32[O+2]=C,this.float32[O+3]=D,a}}r0.prototype.bytesPerElement=16,ut("StructArrayLayout4f16",r0);class z extends iu{get anchorPointX(){return this._structArray.int16[this._pos2+0]}get anchorPointY(){return this._structArray.int16[this._pos2+1]}get x1(){return this._structArray.int16[this._pos2+2]}get y1(){return this._structArray.int16[this._pos2+3]}get x2(){return this._structArray.int16[this._pos2+4]}get y2(){return this._structArray.int16[this._pos2+5]}get featureIndex(){return this._structArray.uint32[this._pos4+3]}get sourceLayerIndex(){return this._structArray.uint16[this._pos2+8]}get bucketIndex(){return this._structArray.uint16[this._pos2+9]}get anchorPoint(){return new s(this.anchorPointX,this.anchorPointY)}}z.prototype.size=20;class l extends wf{get(a){return new z(this,a)}}ut("CollisionBoxArray",l);class m extends iu{get anchorX(){return this._structArray.int16[this._pos2+0]}get anchorY(){return this._structArray.int16[this._pos2+1]}get glyphStartIndex(){return this._structArray.uint16[this._pos2+2]}get numGlyphs(){return this._structArray.uint16[this._pos2+3]}get vertexStartIndex(){return this._structArray.uint32[this._pos4+2]}get lineStartIndex(){return this._structArray.uint32[this._pos4+3]}get lineLength(){return this._structArray.uint32[this._pos4+4]}get segment(){return this._structArray.uint16[this._pos2+10]}get lowerSize(){return this._structArray.uint16[this._pos2+11]}get upperSize(){return this._structArray.uint16[this._pos2+12]}get lineOffsetX(){return this._structArray.float32[this._pos4+7]}get lineOffsetY(){return this._structArray.float32[this._pos4+8]}get writingMode(){return this._structArray.uint8[this._pos1+36]}get placedOrientation(){return this._structArray.uint8[this._pos1+37]}set placedOrientation(a){this._structArray.uint8[this._pos1+37]=a}get hidden(){return this._structArray.uint8[this._pos1+38]}set hidden(a){this._structArray.uint8[this._pos1+38]=a}get crossTileID(){return this._structArray.uint32[this._pos4+10]}set crossTileID(a){this._structArray.uint32[this._pos4+10]=a}get associatedIconIndex(){return this._structArray.int16[this._pos2+22]}}m.prototype.size=48;class T extends Vl{get(a){return new m(this,a)}}ut("PlacedSymbolArray",T);class P extends iu{get anchorX(){return this._structArray.int16[this._pos2+0]}get anchorY(){return this._structArray.int16[this._pos2+1]}get rightJustifiedTextSymbolIndex(){return this._structArray.int16[this._pos2+2]}get centerJustifiedTextSymbolIndex(){return this._structArray.int16[this._pos2+3]}get leftJustifiedTextSymbolIndex(){return this._structArray.int16[this._pos2+4]}get verticalPlacedTextSymbolIndex(){return this._structArray.int16[this._pos2+5]}get placedIconSymbolIndex(){return this._structArray.int16[this._pos2+6]}get verticalPlacedIconSymbolIndex(){return this._structArray.int16[this._pos2+7]}get key(){return this._structArray.uint16[this._pos2+8]}get textBoxStartIndex(){return this._structArray.uint16[this._pos2+9]}get textBoxEndIndex(){return this._structArray.uint16[this._pos2+10]}get verticalTextBoxStartIndex(){return this._structArray.uint16[this._pos2+11]}get verticalTextBoxEndIndex(){return this._structArray.uint16[this._pos2+12]}get iconBoxStartIndex(){return this._structArray.uint16[this._pos2+13]}get iconBoxEndIndex(){return this._structArray.uint16[this._pos2+14]}get verticalIconBoxStartIndex(){return this._structArray.uint16[this._pos2+15]}get verticalIconBoxEndIndex(){return this._structArray.uint16[this._pos2+16]}get featureIndex(){return this._structArray.uint16[this._pos2+17]}get numHorizontalGlyphVertices(){return this._structArray.uint16[this._pos2+18]}get numVerticalGlyphVertices(){return this._structArray.uint16[this._pos2+19]}get numIconVertices(){return this._structArray.uint16[this._pos2+20]}get numVerticalIconVertices(){return this._structArray.uint16[this._pos2+21]}get useRuntimeCollisionCircles(){return this._structArray.uint16[this._pos2+22]}get crossTileID(){return this._structArray.uint32[this._pos4+12]}set crossTileID(a){this._structArray.uint32[this._pos4+12]=a}get textBoxScale(){return this._structArray.float32[this._pos4+13]}get collisionCircleDiameter(){return this._structArray.float32[this._pos4+14]}get textAnchorOffsetStartIndex(){return this._structArray.uint16[this._pos2+30]}get textAnchorOffsetEndIndex(){return this._structArray.uint16[this._pos2+31]}}P.prototype.size=64;class V extends M_{get(a){return new P(this,a)}}ut("SymbolInstanceArray",V);class W extends sg{getoffsetX(a){return this.float32[1*a+0]}}ut("GlyphOffsetArray",W);class te extends Jh{getx(a){return this.int16[3*a+0]}gety(a){return this.int16[3*a+1]}gettileUnitDistanceFromAnchor(a){return this.int16[3*a+2]}}ut("SymbolLineVertexArray",te);class se extends iu{get textAnchor(){return this._structArray.uint16[this._pos2+0]}get textOffset0(){return this._structArray.float32[this._pos4+1]}get textOffset1(){return this._structArray.float32[this._pos4+2]}}se.prototype.size=12;class fe extends gm{get(a){return new se(this,a)}}ut("TextAnchorOffsetArray",fe);class ye extends iu{get featureIndex(){return this._structArray.uint32[this._pos4+0]}get sourceLayerIndex(){return this._structArray.uint16[this._pos2+2]}get bucketIndex(){return this._structArray.uint16[this._pos2+3]}}ye.prototype.size=8;class Re extends P_{get(a){return new ye(this,a)}}ut("FeatureIndexArray",Re);class Me extends eh{}class je extends eh{}class tt extends eh{}class yt extends _s{}class At extends yu{}class vt extends Ml{}class Lt extends ef{}class Kt extends t0{}class It extends Lp{}class Xt extends th{}class Rt extends Kf{}class zt extends tf{}class jt extends og{}class br extends Fu{}class Cr extends R_{}let Rr=na([{name:"a_pos",components:2,type:"Int16"}],4),{members:Pr}=Rr;class Ai{constructor(a=[]){this._forceNewSegmentOnNextPrepare=!1,this.segments=a}prepareSegment(a,h,A,C){let D=this.segments[this.segments.length-1];return a>Ai.MAX_VERTEX_ARRAY_LENGTH&&ln(`Max vertices per segment is ${Ai.MAX_VERTEX_ARRAY_LENGTH}: bucket requested ${a}. Consider using the \`fillLargeMeshArrays\` function if you require meshes with more than ${Ai.MAX_VERTEX_ARRAY_LENGTH} vertices.`),this._forceNewSegmentOnNextPrepare||!D||D.vertexLength+a>Ai.MAX_VERTEX_ARRAY_LENGTH||D.sortKey!==C?this.createNewSegment(h,A,C):D}createNewSegment(a,h,A){let C={vertexOffset:a.length,primitiveOffset:h.length,vertexLength:0,primitiveLength:0,vaos:{}};return A!==void 0&&(C.sortKey=A),this._forceNewSegmentOnNextPrepare=!1,this.segments.push(C),C}getOrCreateLatestSegment(a,h,A){return this.prepareSegment(0,a,h,A)}forceNewSegmentOnNextPrepare(){this._forceNewSegmentOnNextPrepare=!0}get(){return this.segments}destroy(){for(let a of this.segments)for(let h in a.vaos)a.vaos[h].destroy()}static simpleSegment(a,h,A,C){return new Ai([{vertexOffset:a,primitiveOffset:h,vertexLength:A,primitiveLength:C,vaos:{},sortKey:0}])}}function _i(d,a){return 256*(d=ii(Math.floor(d),0,255))+ii(Math.floor(a),0,255)}Ai.MAX_VERTEX_ARRAY_LENGTH=Math.pow(2,16)-1,ut("SegmentVector",Ai);let hi=na([{name:"a_pattern_from",components:4,type:"Uint16"},{name:"a_pattern_to",components:4,type:"Uint16"},{name:"a_pixel_ratio_from",components:1,type:"Uint16"},{name:"a_pixel_ratio_to",components:1,type:"Uint16"}]),hn=na([{name:"a_dasharray_from",components:4,type:"Uint16"},{name:"a_dasharray_to",components:4,type:"Uint16"}]);var fo,$r,di,oa={exports:{}},Ja={exports:{}},ya={exports:{}},jl=function(){if(di)return oa.exports;di=1;var d=(fo||(fo=1,Ja.exports=function(h,A){var C,D,O,H,Z,re,ce,de;for(D=h.length-(C=3&h.length),O=A,Z=3432918353,re=461845907,de=0;de>>16)*Z&65535)<<16)&4294967295)<<15|ce>>>17))*re+(((ce>>>16)*re&65535)<<16)&4294967295)<<13|O>>>19))+((5*(O>>>16)&65535)<<16)&4294967295))+((58964+(H>>>16)&65535)<<16);switch(ce=0,C){case 3:ce^=(255&h.charCodeAt(de+2))<<16;case 2:ce^=(255&h.charCodeAt(de+1))<<8;case 1:O^=ce=(65535&(ce=(ce=(65535&(ce^=255&h.charCodeAt(de)))*Z+(((ce>>>16)*Z&65535)<<16)&4294967295)<<15|ce>>>17))*re+(((ce>>>16)*re&65535)<<16)&4294967295}return O^=h.length,O=2246822507*(65535&(O^=O>>>16))+((2246822507*(O>>>16)&65535)<<16)&4294967295,O=3266489909*(65535&(O^=O>>>13))+((3266489909*(O>>>16)&65535)<<16)&4294967295,(O^=O>>>16)>>>0}),Ja.exports),a=($r||($r=1,ya.exports=function(h,A){for(var C,D=h.length,O=A^D,H=0;D>=4;)C=1540483477*(65535&(C=255&h.charCodeAt(H)|(255&h.charCodeAt(++H))<<8|(255&h.charCodeAt(++H))<<16|(255&h.charCodeAt(++H))<<24))+((1540483477*(C>>>16)&65535)<<16),O=1540483477*(65535&O)+((1540483477*(O>>>16)&65535)<<16)^(C=1540483477*(65535&(C^=C>>>24))+((1540483477*(C>>>16)&65535)<<16)),D-=4,++H;switch(D){case 3:O^=(255&h.charCodeAt(H+2))<<16;case 2:O^=(255&h.charCodeAt(H+1))<<8;case 1:O=1540483477*(65535&(O^=255&h.charCodeAt(H)))+((1540483477*(O>>>16)&65535)<<16)}return O=1540483477*(65535&(O^=O>>>13))+((1540483477*(O>>>16)&65535)<<16),(O^=O>>>15)>>>0}),ya.exports);return oa.exports=d,oa.exports.murmur3=d,oa.exports.murmur2=a,oa.exports}(),qs=c(jl);class Wa{constructor(){this.ids=[],this.positions=[],this.indexed=!1}add(a,h,A,C){this.ids.push(Hl(a)),this.positions.push(h,A,C)}getPositions(a){if(!this.indexed)throw new Error("Trying to get index, but feature positions are not indexed");let h=Hl(a),A=0,C=this.ids.length-1;for(;A>1;this.ids[O]>=h?C=O:A=O+1}let D=[];for(;this.ids[A]===h;)D.push({index:this.positions[3*A],start:this.positions[3*A+1],end:this.positions[3*A+2]}),A++;return D}static serialize(a,h){let A=new Float64Array(a.ids),C=new Uint32Array(a.positions);return Ea(A,C,0,A.length-1),h&&h.push(A.buffer,C.buffer),{ids:A,positions:C}}static deserialize(a){let h=new Wa;return h.ids=a.ids,h.positions=a.positions,h.indexed=!0,h}}function Hl(d){let a=+d;return!isNaN(a)&&a<=Number.MAX_SAFE_INTEGER?a:qs(String(d))}function Ea(d,a,h,A){for(;h>1],D=h-1,O=A+1;for(;;){do D++;while(d[D]C);if(D>=O)break;v(d,D,O),v(a,3*D,3*O),v(a,3*D+1,3*O+1),v(a,3*D+2,3*O+2)}O-h`u_${C}`),this.type=A}setUniform(a,h,A){a.set(A.constantOr(this.value))}getBinding(a,h,A){return this.type==="color"?new N(a,h):new E(a,h)}}class ue{constructor(a,h){this.uniformNames=h.map(A=>`u_${A}`),this.patternFrom=null,this.patternTo=null,this.pixelRatioFrom=1,this.pixelRatioTo=1}setConstantPatternPositions(a,h){this.pixelRatioFrom=h.pixelRatio,this.pixelRatioTo=a.pixelRatio,this.patternFrom=h.tlbr,this.patternTo=a.tlbr}setConstantDashPositions(a,h){this.dashTo=[0,a.y,a.height,a.width],this.dashFrom=[0,h.y,h.height,h.width]}setUniform(a,h,A,C){let D=null;C==="u_pattern_to"?D=this.patternTo:C==="u_pattern_from"?D=this.patternFrom:C==="u_dasharray_to"?D=this.dashTo:C==="u_dasharray_from"?D=this.dashFrom:C==="u_pixel_ratio_to"?D=this.pixelRatioTo:C==="u_pixel_ratio_from"&&(D=this.pixelRatioFrom),D!==null&&a.set(D)}getBinding(a,h,A){return A.substr(0,9)==="u_pattern"||A.substr(0,12)==="u_dasharray_"?new B(a,h):new E(a,h)}}class Ae{constructor(a,h,A,C){this.expression=a,this.type=A,this.maxValue=0,this.paintVertexAttributes=h.map(D=>({name:`a_${D}`,type:"Float32",components:A==="color"?2:1,offset:0})),this.paintVertexArray=new C}populatePaintArray(a,h,A){let C=this.paintVertexArray.length,D=this.expression.evaluate(new Gi(0,A),h,{},A.canonical,[],A.formattedSection);this.paintVertexArray.resize(a),this._setPaintValue(C,a,D)}updatePaintArray(a,h,A,C,D){let O=this.expression.evaluate(new Gi(0,D),A,C);this._setPaintValue(a,h,O)}_setPaintValue(a,h,A){if(this.type==="color"){let C=X(A);for(let D=a;D`u_${H}_t`),this.type=A,this.useIntegerZoom=C,this.zoom=D,this.maxValue=0,this.paintVertexAttributes=h.map(H=>({name:`a_${H}`,type:"Float32",components:A==="color"?4:2,offset:0})),this.paintVertexArray=new O}populatePaintArray(a,h,A){let C=this.expression.evaluate(new Gi(this.zoom,A),h,{},A.canonical,[],A.formattedSection),D=this.expression.evaluate(new Gi(this.zoom+1,A),h,{},A.canonical,[],A.formattedSection),O=this.paintVertexArray.length;this.paintVertexArray.resize(a),this._setPaintValue(O,a,C,D)}updatePaintArray(a,h,A,C,D){let O=this.expression.evaluate(new Gi(this.zoom,D),A,C),H=this.expression.evaluate(new Gi(this.zoom+1,D),A,C);this._setPaintValue(a,h,O,H)}_setPaintValue(a,h,A,C){if(this.type==="color"){let D=X(A),O=X(C);for(let H=a;H`#define HAS_UNIFORM_${C}`))}return a}getBinderAttributes(){let a=[];for(let h in this.binders){let A=this.binders[h];if(A instanceof Ae||A instanceof Te)for(let C=0;C!0){this.programConfigurations={};for(let C of a)this.programConfigurations[C.id]=new Tt(C,h,A);this.needsUpload=!1,this._featureMap=new Wa,this._bufferOffset=0}populatePaintArrays(a,h,A,C){for(let D in this.programConfigurations)this.programConfigurations[D].populatePaintArrays(a,h,C);h.id!==void 0&&this._featureMap.add(h.id,A,this._bufferOffset,a),this._bufferOffset=a,this.needsUpload=!0}updatePaintArrays(a,h,A,C){for(let D of A)this.needsUpload=this.programConfigurations[D.id].updatePaintArrays(a,this._featureMap,h,D,C)||this.needsUpload}get(a){return this.programConfigurations[a]}upload(a){if(this.needsUpload){for(let h in this.programConfigurations)this.programConfigurations[h].upload(a);this.needsUpload=!1}}destroy(){for(let a in this.programConfigurations)this.programConfigurations[a].destroy()}}function Ar(d,a){return{"text-opacity":["opacity"],"icon-opacity":["opacity"],"text-color":["fill_color"],"icon-color":["fill_color"],"text-halo-color":["halo_color"],"icon-halo-color":["halo_color"],"text-halo-blur":["halo_blur"],"icon-halo-blur":["halo_blur"],"text-halo-width":["halo_width"],"icon-halo-width":["halo_width"],"line-gap-width":["gapwidth"],"line-dasharray":["dasharray_to","dasharray_from"],"line-pattern":["pattern_to","pattern_from","pixel_ratio_to","pixel_ratio_from"],"fill-pattern":["pattern_to","pattern_from","pixel_ratio_to","pixel_ratio_from"],"fill-extrusion-pattern":["pattern_to","pattern_from","pixel_ratio_to","pixel_ratio_from"]}[d]||[d.replace(`${a}-`,"").replace(/-/g,"_")]}function qr(d,a,h){let A={color:{source:Ml,composite:r0},number:{source:sg,composite:Ml}},C=function(D){return{"line-pattern":{source:Lt,composite:Lt},"fill-pattern":{source:Lt,composite:Lt},"fill-extrusion-pattern":{source:Lt,composite:Lt},"line-dasharray":{source:Kt,composite:Kt}}[D]}(d);return C&&C[h]||A[a][h]}ut("ConstantBinder",Q),ut("CrossFadedConstantBinder",ue),ut("SourceExpressionBinder",Ae),ut("CrossFadedPatternBinder",bt),ut("CrossFadedDasharrayBinder",wt),ut("CompositeExpressionBinder",Te),ut("ProgramConfiguration",Tt,{omit:["_buffers"]}),ut("ProgramConfigurationSet",er);let _r=Math.pow(2,14)-1,Sr=-_r-1;function or(d){let a=hr/d.extent,h=d.loadGeometry();for(let A=0;AO.x+1||ZO.y+1)&&ln("Geometry exceeds allowed extent, reduce your vector tile buffer size")}}return h}function Pi(d,a){return{type:d.type,id:d.id,properties:d.properties,geometry:a?or(d):[]}}let En=-32768;function wn(d,a,h,A,C){d.emplaceBack(En+8*a+A,En+8*h+C)}class vo{constructor(a){this.zoom=a.zoom,this.overscaling=a.overscaling,this.layers=a.layers,this.layerIds=this.layers.map(h=>h.id),this.index=a.index,this.hasDependencies=!1,this.layoutVertexArray=new je,this.indexArray=new br,this.segments=new Ai,this.programConfigurations=new er(a.layers,a.zoom),this.stateDependentLayerIds=this.layers.filter(h=>h.isStateDependent()).map(h=>h.id)}populate(a,h,A){let C=this.layers[0],D=[],O=null,H=!1,Z=C.type==="heatmap";if(C.type==="circle"){let ce=C;O=ce.layout.get("circle-sort-key"),H=!O.isConstant(),Z=Z||ce.paint.get("circle-pitch-alignment")==="map"}let re=Z?h.subdivisionGranularity.circle:1;for(let{feature:ce,id:de,index:we,sourceLayerIndex:Ee}of a){let De=this.layers[0]._featureFilter.needGeometry,ke=Pi(ce,De);if(!this.layers[0]._featureFilter.filter(new Gi(this.zoom),ke,A))continue;let qe=H?O.evaluate(ke,{},A):void 0,st={id:de,properties:ce.properties,type:ce.type,sourceLayerIndex:Ee,index:we,geometry:De?ke.geometry:or(ce),patterns:{},sortKey:qe};D.push(st)}H&&D.sort((ce,de)=>ce.sortKey-de.sortKey);for(let ce of D){let{geometry:de,index:we,sourceLayerIndex:Ee}=ce,De=a[we].feature;this.addFeature(ce,de,we,A,re),h.featureIndex.insert(De,de,we,Ee,this.index)}}update(a,h,A){this.stateDependentLayers.length&&this.programConfigurations.updatePaintArrays(a,h,this.stateDependentLayers,{imagePositions:A})}isEmpty(){return this.layoutVertexArray.length===0}uploadPending(){return!this.uploaded||this.programConfigurations.needsUpload}upload(a){this.uploaded||(this.layoutVertexBuffer=a.createVertexBuffer(this.layoutVertexArray,Pr),this.indexBuffer=a.createIndexBuffer(this.indexArray)),this.programConfigurations.upload(a),this.uploaded=!0}destroy(){this.layoutVertexBuffer&&(this.layoutVertexBuffer.destroy(),this.indexBuffer.destroy(),this.programConfigurations.destroy(),this.segments.destroy())}addFeature(a,h,A,C,D=1){let O;switch(D){case 1:O=[0,7];break;case 3:O=[0,2,5,7];break;case 5:O=[0,1,3,4,6,7];break;case 7:O=[0,1,2,3,4,5,6,7];break;default:throw new Error(`Invalid circle bucket granularity: ${D}; valid values are 1, 3, 5, 7.`)}let H=O.length;for(let Z of h)for(let re of Z){let ce=re.x,de=re.y;if(ce<0||ce>=hr||de<0||de>=hr)continue;let we=this.segments.prepareSegment(H*H,this.layoutVertexArray,this.indexArray,a.sortKey),Ee=we.vertexLength;for(let De=0;De1){if(Oi(d,a))return!0;for(let A=0;A1?h:h.sub(a)._mult(C)._add(a))}function va(d,a){let h,A,C,D=!1;for(let O=0;Oa.y!=C.y>a.y&&a.x<(C.x-A.x)*(a.y-A.y)/(C.y-A.y)+A.x&&(D=!D)}return D}function Bo(d,a){let h=!1;for(let A=0,C=d.length-1;Aa.y!=O.y>a.y&&a.x<(O.x-D.x)*(a.y-D.y)/(O.y-D.y)+D.x&&(h=!h)}return h}function ib(d,a,h){let A=h[0],C=h[2];if(d.xC.x&&a.x>C.x||d.yC.y&&a.y>C.y)return!1;let D=Nn(d,a,h[0]);return D!==Nn(d,a,h[1])||D!==Nn(d,a,h[2])||D!==Nn(d,a,h[3])}function Sd(d,a,h){let A=a.paint.get(d).value;return A.kind==="constant"?A.value:h.programConfigurations.get(a.id).getMaxValue(d)}function i0(d){return Math.sqrt(d[0]*d[0]+d[1]*d[1])}function nb(d,a,h,A,C){if(!a[0]&&!a[1])return d;let D=s.convert(a)._mult(C);h==="viewport"&&D._rotate(-A);let O=[];for(let H=0;HHC(pt,qe,st,kt))}(re,D,H,Z),De=ce),NL({queryGeometry:Ee,size:De,transform:D,unwrappedTileID:H,getElevation:Z,pitchAlignment:we,pitchScale:de},C)}}class GC extends vo{}let VL;ut("HeatmapBucket",GC,{omit:["layers"]});var h8={get paint(){return VL=VL||new Fa({"heatmap-radius":new _n(wr.paint_heatmap["heatmap-radius"]),"heatmap-weight":new _n(wr.paint_heatmap["heatmap-weight"]),"heatmap-intensity":new tn(wr.paint_heatmap["heatmap-intensity"]),"heatmap-color":new Hc(wr.paint_heatmap["heatmap-color"]),"heatmap-opacity":new tn(wr.paint_heatmap["heatmap-opacity"])})}};function WC(d,{width:a,height:h},A,C){if(C){if(C instanceof Uint8ClampedArray)C=new Uint8Array(C.buffer);else if(C.length!==a*h*A)throw new RangeError(`mismatched image size. expected: ${C.length} but got: ${a*h*A}`)}else C=new Uint8Array(a*h*A);return d.width=a,d.height=h,d.data=C,d}function qC(d,{width:a,height:h},A){if(a===d.width&&h===d.height)return;let C=WC({},{width:a,height:h},A);uv(d,C,{x:0,y:0},{x:0,y:0},{width:Math.min(d.width,a),height:Math.min(d.height,h)},A),d.width=a,d.height=h,d.data=C.data}function uv(d,a,h,A,C,D){if(C.width===0||C.height===0)return a;if(C.width>d.width||C.height>d.height||h.x>d.width-C.width||h.y>d.height-C.height)throw new RangeError("out of range source coordinates for image copy");if(C.width>a.width||C.height>a.height||A.x>a.width-C.width||A.y>a.height-C.height)throw new RangeError("out of range destination coordinates for image copy");let O=d.data,H=a.data;if(O===H)throw new Error("srcData equals dstData, so image is already copied");for(let Z=0;Z{a[d.evaluationKey]=Z;let re=d.expression.evaluate(a);C.setPixel(O/4/h,H/4,re)};if(d.clips)for(let O=0,H=0;Othis.max&&(this.max=de),de=this.dim+1||h<-1||h>=this.dim+1)throw new RangeError("out of range source coordinates for DEM data");return(h+1)*this.stride+(a+1)}unpack(a,h,A){return a*this.redFactor+h*this.greenFactor+A*this.blueFactor-this.baseShift}pack(a){return A2(a,this.getUnpackVector())}getPixels(){return new rh({width:this.stride,height:this.stride},new Uint8Array(this.data.buffer))}backfillBorder(a,h,A){if(this.dim!==a.dim)throw new Error("dem dimension mismatch");let C=h*this.dim,D=h*this.dim+this.dim,O=A*this.dim,H=A*this.dim+this.dim;switch(h){case-1:C=D-1;break;case 1:D=C+1}switch(A){case-1:O=H-1;break;case 1:H=O+1}let Z=-h*this.dim,re=-A*this.dim;for(let ce=O;ce0)for(let O=a;O=a;O-=A)D=JC(O/A|0,d[O],d[O+1],D);return D&&Am(D,D.next)&&(B_(D),D=D.next),D}function iA(d,a){if(!d)return d;a||(a=d);let h,A=d;do if(h=!1,A.steiner||!Am(A,A.next)&&rc(A.prev,A,A.next)!==0)A=A.next;else{if(B_(A),A=a=A.prev,A===A.next)break;h=!0}while(h||A!==a);return a}function ab(d,a,h,A,C,D,O){if(!d)return;!O&&D&&function(Z,re,ce,de){let we=Z;do we.z===0&&(we.z=_2(we.x,we.y,re,ce,de)),we.prevZ=we.prev,we.nextZ=we.next,we=we.next;while(we!==Z);we.prevZ.nextZ=null,we.prevZ=null,function(Ee){let De,ke=1;do{let qe,st=Ee;Ee=null;let kt=null;for(De=0;st;){De++;let pt=st,_t=0;for(let Qt=0;Qt0||Ht>0&&pt;)_t!==0&&(Ht===0||!pt||st.z<=pt.z)?(qe=st,st=st.nextZ,_t--):(qe=pt,pt=pt.nextZ,Ht--),kt?kt.nextZ=qe:Ee=qe,qe.prevZ=kt,kt=qe;st=pt}kt.nextZ=null,ke*=2}while(De>1)}(we)}(d,A,C,D);let H=d;for(;d.prev!==d.next;){let Z=d.prev,re=d.next;if(D?qL(d,A,C,D):WL(d))a.push(Z.i,d.i,re.i),B_(d),d=re.next,H=re.next;else if((d=re)===H){O?O===1?ab(d=$L(iA(d),a),a,h,A,C,D,2):O===2&&XL(d,a,h,A,C,D):ab(iA(d),a,h,A,C,D,1);break}}}function WL(d){let a=d.prev,h=d,A=d.next;if(rc(a,h,A)>=0)return!1;let C=a.x,D=h.x,O=A.x,H=a.y,Z=h.y,re=A.y,ce=Math.min(C,D,O),de=Math.min(H,Z,re),we=Math.max(C,D,O),Ee=Math.max(H,Z,re),De=A.next;for(;De!==a;){if(De.x>=ce&&De.x<=we&&De.y>=de&&De.y<=Ee&&nA(C,H,D,Z,O,re,De.x,De.y)&&rc(De.prev,De,De.next)>=0)return!1;De=De.next}return!0}function qL(d,a,h,A){let C=d.prev,D=d,O=d.next;if(rc(C,D,O)>=0)return!1;let H=C.x,Z=D.x,re=O.x,ce=C.y,de=D.y,we=O.y,Ee=Math.min(H,Z,re),De=Math.min(ce,de,we),ke=Math.max(H,Z,re),qe=Math.max(ce,de,we),st=_2(Ee,De,a,h,A),kt=_2(ke,qe,a,h,A),pt=d.prevZ,_t=d.nextZ;for(;pt&&pt.z>=st&&_t&&_t.z<=kt;){if(pt.x>=Ee&&pt.x<=ke&&pt.y>=De&&pt.y<=qe&&pt!==C&&pt!==O&&nA(H,ce,Z,de,re,we,pt.x,pt.y)&&rc(pt.prev,pt,pt.next)>=0||(pt=pt.prevZ,_t.x>=Ee&&_t.x<=ke&&_t.y>=De&&_t.y<=qe&&_t!==C&&_t!==O&&nA(H,ce,Z,de,re,we,_t.x,_t.y)&&rc(_t.prev,_t,_t.next)>=0))return!1;_t=_t.nextZ}for(;pt&&pt.z>=st;){if(pt.x>=Ee&&pt.x<=ke&&pt.y>=De&&pt.y<=qe&&pt!==C&&pt!==O&&nA(H,ce,Z,de,re,we,pt.x,pt.y)&&rc(pt.prev,pt,pt.next)>=0)return!1;pt=pt.prevZ}for(;_t&&_t.z<=kt;){if(_t.x>=Ee&&_t.x<=ke&&_t.y>=De&&_t.y<=qe&&_t!==C&&_t!==O&&nA(H,ce,Z,de,re,we,_t.x,_t.y)&&rc(_t.prev,_t,_t.next)>=0)return!1;_t=_t.nextZ}return!0}function $L(d,a){let h=d;do{let A=h.prev,C=h.next.next;!Am(A,C)&&YL(A,h,h.next,C)&&ag(A,C)&&ag(C,A)&&(a.push(A.i,h.i,C.i),B_(h),B_(h.next),h=d=C),h=h.next}while(h!==d);return iA(h)}function XL(d,a,h,A,C,D){let O=d;do{let H=O.next.next;for(;H!==O.prev;){if(O.i!==H.i&&v2(O,H)){let Z=w2(O,H);return O=iA(O,O.next),Z=iA(Z,Z.next),ab(O,a,h,A,C,D,0),void ab(Z,a,h,A,C,D,0)}H=H.next}O=O.next}while(O!==d)}function d8(d,a){let h=d.x-a.x;return h===0&&(h=d.y-a.y,h===0)&&(h=(d.next.y-d.y)/(d.next.x-d.x)-(a.next.y-a.y)/(a.next.x-a.x)),h}function p8(d,a){let h=function(C,D){let O=D,H=C.x,Z=C.y,re,ce=-1/0;if(Am(C,O))return O;do{if(Am(C,O.next))return O.next;if(Z<=O.y&&Z>=O.next.y&&O.next.y!==O.y){let ke=O.x+(Z-O.y)*(O.next.x-O.x)/(O.next.y-O.y);if(ke<=H&&ke>ce&&(ce=ke,re=O.x=O.x&&O.x>=we&&H!==O.x&&QC(Zre.x||O.x===re.x&&ZL(re,O)))&&(re=O,De=ke)}O=O.next}while(O!==de);return re}(d,a);if(!h)return a;let A=w2(h,d);return iA(A,A.next),iA(h,h.next)}function ZL(d,a){return rc(d.prev,d,a.prev)<0&&rc(a.next,d,d.next)<0}function _2(d,a,h,A,C){return(d=1431655765&((d=858993459&((d=252645135&((d=16711935&((d=(d-h)*C|0)|d<<8))|d<<4))|d<<2))|d<<1))|(a=1431655765&((a=858993459&((a=252645135&((a=16711935&((a=(a-A)*C|0)|a<<8))|a<<4))|a<<2))|a<<1))<<1}function y2(d){let a=d,h=d;do(a.x=(d-O)*(D-H)&&(d-O)*(A-H)>=(h-O)*(a-H)&&(h-O)*(D-H)>=(C-O)*(A-H)}function nA(d,a,h,A,C,D,O,H){return!(d===O&&a===H)&&QC(d,a,h,A,C,D,O,H)}function v2(d,a){return d.next.i!==a.i&&d.prev.i!==a.i&&!function(h,A){let C=h;do{if(C.i!==h.i&&C.next.i!==h.i&&C.i!==A.i&&C.next.i!==A.i&&YL(C,C.next,h,A))return!0;C=C.next}while(C!==h);return!1}(d,a)&&(ag(d,a)&&ag(a,d)&&function(h,A){let C=h,D=!1,O=(h.x+A.x)/2,H=(h.y+A.y)/2;do C.y>H!=C.next.y>H&&C.next.y!==C.y&&O<(C.next.x-C.x)*(H-C.y)/(C.next.y-C.y)+C.x&&(D=!D),C=C.next;while(C!==h);return D}(d,a)&&(rc(d.prev,d,a.prev)||rc(d,a.prev,a))||Am(d,a)&&rc(d.prev,d,d.next)>0&&rc(a.prev,a,a.next)>0)}function rc(d,a,h){return(a.y-d.y)*(h.x-a.x)-(a.x-d.x)*(h.y-a.y)}function Am(d,a){return d.x===a.x&&d.y===a.y}function YL(d,a,h,A){let C=b2(rc(d,a,h)),D=b2(rc(d,a,A)),O=b2(rc(h,A,d)),H=b2(rc(h,A,a));return C!==D&&O!==H||!(C!==0||!x2(d,h,a))||!(D!==0||!x2(d,A,a))||!(O!==0||!x2(h,d,A))||!(H!==0||!x2(h,a,A))}function x2(d,a,h){return a.x<=Math.max(d.x,h.x)&&a.x>=Math.min(d.x,h.x)&&a.y<=Math.max(d.y,h.y)&&a.y>=Math.min(d.y,h.y)}function b2(d){return d>0?1:d<0?-1:0}function ag(d,a){return rc(d.prev,d,d.next)<0?rc(d,a,d.next)>=0&&rc(d,d.prev,a)>=0:rc(d,a,d.prev)<0||rc(d,d.next,a)<0}function w2(d,a){let h=T2(d.i,d.x,d.y),A=T2(a.i,a.x,a.y),C=d.next,D=a.prev;return d.next=a,a.prev=d,h.next=C,C.prev=h,A.next=h,h.prev=A,D.next=A,A.prev=D,A}function JC(d,a,h,A){let C=T2(d,a,h);return A?(C.next=A.next,C.prev=A,A.next.prev=C,A.next=C):(C.prev=C,C.next=C),C}function B_(d){d.next.prev=d.prev,d.prev.next=d.next,d.prevZ&&(d.prevZ.nextZ=d.nextZ),d.nextZ&&(d.nextZ.prevZ=d.prevZ)}function T2(d,a,h){return{i:d,x:a,y:h,prev:null,next:null,z:0,prevZ:null,nextZ:null,steiner:!1}}class L_{constructor(a,h){if(h>a)throw new Error("Min granularity must not be greater than base granularity.");this._baseZoomGranularity=a,this._minGranularity=h}getGranularityForZoomLevel(a){return Math.max(Math.floor(this._baseZoomGranularity/(1<32767||h>32767)throw new Error("Vertex coordinates are out of signed 16 bit integer range.");let A=0|Math.round(a),C=0|Math.round(h),D=this._getKey(A,C);if(this._vertexDictionary.has(D))return this._vertexDictionary.get(D);let O=this._vertexBuffer.length/2;return this._vertexDictionary.set(D,O),this._vertexBuffer.push(A,C),O}_subdivideTrianglesScanline(a){if(this._granularity<2)return function(C,D){let O=[];for(let H=0;H0?(O.push(Z),O.push(ce),O.push(re)):(O.push(Z),O.push(re),O.push(ce))}return O}(this._vertexBuffer,a);let h=[],A=a.length;for(let C=0;C=1||Ht<=0)||st&&(reD)){de>=C&&de<=D&&O.push(A[(H+1)%3]);continue}!st&&_t>0&&O.push(this._vertexToIndex(Z+De*_t,re+ke*_t));let Qt=Z+De*Math.max(_t,0),Ir=Z+De*Math.min(Ht,1);qe||this._generateIntraEdgeVertices(O,Z,re,ce,de,Qt,Ir),!st&&Ht<1&&O.push(this._vertexToIndex(Z+De*Ht,re+ke*Ht)),(st||de>=C&&de<=D)&&O.push(A[(H+1)%3]),!st&&(de<=C||de>=D)&&this._generateInterEdgeVertices(O,Z,re,ce,de,we,Ee,Ir,C,D)}return O}_generateIntraEdgeVertices(a,h,A,C,D,O,H){let Z=C-h,re=D-A,ce=re===0,de=ce?Math.min(h,C):Math.min(O,H),we=ce?Math.max(h,C):Math.max(O,H),Ee=Math.floor(de/this._granularityCellSize)+1,De=Math.ceil(we/this._granularityCellSize)-1;if(ce?h=Ee;ke--){let qe=ke*this._granularityCellSize;a.push(this._vertexToIndex(qe,A+re*(qe-h)/Z))}}_generateInterEdgeVertices(a,h,A,C,D,O,H,Z,re,ce){let de=D-A,we=O-C,Ee=H-D,De=(re-D)/Ee,ke=(ce-D)/Ee,qe=Math.min(De,ke),st=Math.max(De,ke),kt=C+we*qe,pt=Math.floor(Math.min(kt,Z)/this._granularityCellSize)+1,_t=Math.ceil(Math.max(kt,Z)/this._granularityCellSize)-1,Ht=Z=1||st<=0){let oi=A-H,Kr=O+(h-O)*Math.min((re-H)/oi,(ce-H)/oi);pt=Math.floor(Math.min(Kr,Z)/this._granularityCellSize)+1,_t=Math.ceil(Math.max(Kr,Z)/this._granularityCellSize)-1,Ht=Z0?ce:re;if(Ht)for(let oi=pt;oi<=_t;oi++)a.push(this._vertexToIndex(oi*this._granularityCellSize,Ir));else for(let oi=_t;oi>=pt;oi--)a.push(this._vertexToIndex(oi*this._granularityCellSize,Ir))}_generateOutline(a){let h=[];for(let A of a){let C=D_(A,this._granularity,!0),D=this._pointArrayToIndices(C),O=[];for(let H=1;HD!=(O===hv)?(a.push(h),a.push(A),a.push(this._vertexToIndex(C,O)),a.push(A),a.push(this._vertexToIndex(D,O)),a.push(this._vertexToIndex(C,O))):(a.push(A),a.push(h),a.push(this._vertexToIndex(C,O)),a.push(this._vertexToIndex(D,O)),a.push(A),a.push(this._vertexToIndex(C,O)))}_fillPoles(a,h,A){let C=this._vertexBuffer,D=hr,O=a.length;for(let H=2;H80*de){qe=re[0],st=re[1];let pt=qe,_t=st;for(let Ht=de;Htpt&&(pt=Qt),Ir>_t&&(_t=Ir)}kt=Math.max(pt-qe,_t-st),kt=kt!==0?32767/kt:0}return ab(De,ke,de,qe,st,kt,0),ke}(A,C),Z=this._convertIndices(A,H);D=this._subdivideTrianglesScanline(Z)}catch(H){console.error(H)}let O=[];return h&&(O=this._generateOutline(a)),this._ensureNoPoleVertices(),this._handlePoles(D),{verticesFlattened:this._vertexBuffer,indicesTriangles:D,indicesLineList:O}}_convertIndices(a,h){let A=[];for(let C=0;C0?(Math.floor(Ir/O)+1)*O:(Math.ceil(Ir/O)-1)*O,ji=_t>0?(Math.floor(oi/O)+1)*O:(Math.ceil(oi/O)-1)*O,vi=Math.abs(Ir-gi),Qr=Math.abs(oi-ji),jr=Math.abs(Ir-ke),dn=Math.abs(oi-qe),cn=st?vi/Ht:Number.POSITIVE_INFINITY,vn=kt?Qr/Qt:Number.POSITIVE_INFINITY;if((jr<=vi||!st)&&(dn<=Qr||!kt))break;if(cn=0?O-1:D-1,re=(H+1)%D,ce=d[2*a[Z]],de=d[2*a[re]],we=d[2*a[O]],Ee=d[2*a[O]+1],De=d[2*a[H]+1],ke=!1;if(cede)ke=!1;else{let qe=De-Ee,st=-(d[2*a[H]]-we),kt=Ee((de-we)*qe+(d[2*a[re]+1]-Ee)*st)*kt&&(ke=!0)}if(ke){let qe=a[Z],st=a[O],kt=a[H];qe!==st&&qe!==kt&&st!==kt&&h.push(kt,st,qe),O--,O<0&&(O=D-1)}else{let qe=a[re],st=a[O],kt=a[H];qe!==st&&qe!==kt&&st!==kt&&h.push(kt,st,qe),H++,H>=D&&(H=0)}if(Z===re)break}}function dv(d,a,h,A,C,D,O,H,Z){let re=C.length/2,ce=O&&H&&Z;if(reAi.MAX_VERTEX_ARRAY_LENGTH&&(_t=de.createNewSegment(we,Ee),pt=kt.count,gi=!0,ji=!0,vi=!0,Ht=0);let Qr=Js(st,De,qe,kt,Ir,gi,_t),jr=Js(st,De,qe,kt,oi,ji,_t),dn=Js(st,De,qe,kt,Kr,vi,_t);Ee.emplaceBack(Ht+Qr-pt,Ht+jr-pt,Ht+dn-pt),_t.primitiveLength++}})(a,h,A,C,D,d),ce&&function(de,we,Ee,De,ke,qe){let st=[];for(let Qt=0;QtAi.MAX_VERTEX_ARRAY_LENGTH&&(_t=de.createNewSegment(we,Ee),pt=kt.count,ji=!0,vi=!0,Ht=0);let Qr=Js(st,De,qe,kt,Kr,ji,_t),jr=Js(st,De,qe,kt,gi,vi,_t);Ee.emplaceBack(Ht+Qr-pt,Ht+jr-pt),_t.primitiveLength++}}}(O,h,H,C,Z,d),a.forceNewSegmentOnNextPrepare(),O?.forceNewSegmentOnNextPrepare()}function Js(d,a,h,A,C,D,O){if(D){let H=A.count;return h(a[2*C],a[2*C+1]),d[C]=A.count,A.count++,O.vertexLength++,H}return d[C]}class eI{constructor(a){this.zoom=a.zoom,this.overscaling=a.overscaling,this.layers=a.layers,this.layerIds=this.layers.map(h=>h.id),this.index=a.index,this.hasDependencies=!1,this.patternFeatures=[],this.layoutVertexArray=new tt,this.indexArray=new br,this.indexArray2=new Cr,this.programConfigurations=new er(a.layers,a.zoom),this.segments=new Ai,this.segments2=new Ai,this.stateDependentLayerIds=this.layers.filter(h=>h.isStateDependent()).map(h=>h.id)}populate(a,h,A){this.hasDependencies=o0("fill",this.layers,h);let C=this.layers[0].layout.get("fill-sort-key"),D=!C.isConstant(),O=[];for(let{feature:H,id:Z,index:re,sourceLayerIndex:ce}of a){let de=this.layers[0]._featureFilter.needGeometry,we=Pi(H,de);if(!this.layers[0]._featureFilter.filter(new Gi(this.zoom),we,A))continue;let Ee=D?C.evaluate(we,{},A,h.availableImages):void 0,De={id:Z,properties:H.properties,type:H.type,sourceLayerIndex:ce,index:re,geometry:de?we.geometry:or(H),patterns:{},sortKey:Ee};O.push(De)}D&&O.sort((H,Z)=>H.sortKey-Z.sortKey);for(let H of O){let{geometry:Z,index:re,sourceLayerIndex:ce}=H;if(this.hasDependencies){let de=sb("fill",this.layers,H,{zoom:this.zoom},h);this.patternFeatures.push(de)}else this.addFeature(H,Z,re,A,{},h.subdivisionGranularity);h.featureIndex.insert(a[re].feature,Z,re,ce,this.index)}}update(a,h,A){this.stateDependentLayers.length&&this.programConfigurations.updatePaintArrays(a,h,this.stateDependentLayers,{imagePositions:A})}addFeatures(a,h,A){for(let C of this.patternFeatures)this.addFeature(C,C.geometry,C.index,h,A,a.subdivisionGranularity)}isEmpty(){return this.layoutVertexArray.length===0}uploadPending(){return!this.uploaded||this.programConfigurations.needsUpload}upload(a){this.uploaded||(this.layoutVertexBuffer=a.createVertexBuffer(this.layoutVertexArray,HL),this.indexBuffer=a.createIndexBuffer(this.indexArray),this.indexBuffer2=a.createIndexBuffer(this.indexArray2)),this.programConfigurations.upload(a),this.uploaded=!0}destroy(){this.layoutVertexBuffer&&(this.layoutVertexBuffer.destroy(),this.indexBuffer.destroy(),this.indexBuffer2.destroy(),this.programConfigurations.destroy(),this.segments.destroy(),this.segments2.destroy())}addFeature(a,h,A,C,D,O){for(let H of dt(h,500)){let Z=C2(H,C,O.fill.getGranularityForZoomLevel(C.z)),re=this.layoutVertexArray;dv((ce,de)=>{re.emplaceBack(ce,de)},this.segments,this.layoutVertexArray,this.indexArray,Z.verticesFlattened,Z.indicesTriangles,this.segments2,this.indexArray2,Z.indicesLineList)}this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length,a,A,{imagePositions:D,canonical:C})}}let I2,O_;ut("FillBucket",eI,{omit:["layers","patternFeatures"]});var m8={get paint(){return O_=O_||new Fa({"fill-antialias":new tn(wr.paint_fill["fill-antialias"]),"fill-opacity":new _n(wr.paint_fill["fill-opacity"]),"fill-color":new _n(wr.paint_fill["fill-color"]),"fill-outline-color":new _n(wr.paint_fill["fill-outline-color"]),"fill-translate":new tn(wr.paint_fill["fill-translate"]),"fill-translate-anchor":new tn(wr.paint_fill["fill-translate-anchor"]),"fill-pattern":new Ju(wr.paint_fill["fill-pattern"])})},get layout(){return I2=I2||new Fa({"fill-sort-key":new _n(wr.layout_fill["fill-sort-key"])})}};class g8 extends Gc{constructor(a,h){super(a,m8,h)}recalculate(a,h){super.recalculate(a,h);let A=this.paint._values["fill-outline-color"];A.value.kind==="constant"&&A.value.value===void 0&&(this.paint._values["fill-outline-color"]=this.paint._values["fill-color"])}createBucket(a){return new eI(a)}queryRadius(){return i0(this.paint.get("fill-translate"))}queryIntersectsFeature({queryGeometry:a,geometry:h,transform:A,pixelsToTileUnits:C}){return ro(nb(a,this.paint.get("fill-translate"),this.paint.get("fill-translate-anchor"),-A.bearingInRadians,C),h)}isTileClipped(){return!0}}let A8=na([{name:"a_pos",components:2,type:"Int16"},{name:"a_normal_ed",components:4,type:"Int16"}],4),_8=na([{name:"a_centroid",components:2,type:"Int16"}],4),{members:y8}=A8;class cb{constructor(a,h,A,C,D){this.properties={},this.extent=A,this.type=0,this.id=void 0,this._pbf=a,this._geometry=-1,this._keys=C,this._values=D,a.readFields(v8,this,h)}loadGeometry(){let a=this._pbf;a.pos=this._geometry;let h=a.readVarint()+a.pos,A=[],C,D=1,O=0,H=0,Z=0;for(;a.pos>3}if(O--,D===1||D===2)H+=a.readSVarint(),Z+=a.readSVarint(),D===1&&(C&&A.push(C),C=[]),C&&C.push(new s(H,Z));else{if(D!==7)throw new Error(`unknown command ${D}`);C&&C.push(C[0].clone())}}return C&&A.push(C),A}bbox(){let a=this._pbf;a.pos=this._geometry;let h=a.readVarint()+a.pos,A=1,C=0,D=0,O=0,H=1/0,Z=-1/0,re=1/0,ce=-1/0;for(;a.pos>3}if(C--,A===1||A===2)D+=a.readSVarint(),O+=a.readSVarint(),DZ&&(Z=D),Oce&&(ce=O);else if(A!==7)throw new Error(`unknown command ${A}`)}return[H,re,Z,ce]}toGeoJSON(a,h,A){let C=this.extent*Math.pow(2,A),D=this.extent*a,O=this.extent*h,H=this.loadGeometry();function Z(we){return[360*(we.x+D)/C-180,360/Math.PI*Math.atan(Math.exp((1-2*(we.y+O)/C)*Math.PI))-90]}function re(we){return we.map(Z)}let ce;if(this.type===1){let we=[];for(let De of H)we.push(De[0]);let Ee=re(we);ce=we.length===1?{type:"Point",coordinates:Ee[0]}:{type:"MultiPoint",coordinates:Ee}}else if(this.type===2){let we=H.map(re);ce=we.length===1?{type:"LineString",coordinates:we[0]}:{type:"MultiLineString",coordinates:we}}else{if(this.type!==3)throw new Error("unknown feature type");{let we=tI(H),Ee=[];for(let De of we)Ee.push(De.map(re));ce=Ee.length===1?{type:"Polygon",coordinates:Ee[0]}:{type:"MultiPolygon",coordinates:Ee}}}let de={type:"Feature",geometry:ce,properties:this.properties};return this.id!=null&&(de.id=this.id),de}}function v8(d,a,h){d===1?a.id=h.readVarint():d===2?function(A,C){let D=A.readVarint()+A.pos;for(;A.pos=this._features.length)throw new Error("feature index out of bounds");this._pbf.pos=this._features[a];let h=this._pbf.readVarint()+this._pbf.pos;return new cb(this._pbf,h,this.extent,this._keys,this._values)}}function JL(d,a,h){d===15?a.version=h.readVarint():d===1?a.name=h.readString():d===5?a.extent=h.readVarint():d===2?a._features.push(h.pos):d===3?a._keys.push(h.readString()):d===4&&a._values.push(function(A){let C=null,D=A.readVarint()+A.pos;for(;A.pos>3;C=O===1?A.readString():O===2?A.readFloat():O===3?A.readDouble():O===4?A.readVarint64():O===5?A.readVarint():O===6?A.readSVarint():O===7?A.readBoolean():null}if(C==null)throw new Error("unknown feature value");return C}(h))}class ub{constructor(a,h){this.layers=a.readFields(F_,{},h)}}function F_(d,a,h){if(d===3){let A=new QL(h,h.readVarint()+h.pos);A.length&&(a[A.name]=A)}}let hb=Math.pow(2,13);function lg(d,a,h,A,C,D,O,H){d.emplaceBack(a,h,2*Math.floor(A*hb)+O,C*hb*2,D*hb*2,Math.round(H))}class M2{constructor(a){this.zoom=a.zoom,this.overscaling=a.overscaling,this.layers=a.layers,this.layerIds=this.layers.map(h=>h.id),this.index=a.index,this.hasDependencies=!1,this.layoutVertexArray=new yt,this.centroidVertexArray=new Me,this.indexArray=new br,this.programConfigurations=new er(a.layers,a.zoom),this.segments=new Ai,this.stateDependentLayerIds=this.layers.filter(h=>h.isStateDependent()).map(h=>h.id)}populate(a,h,A){this.features=[],this.hasDependencies=o0("fill-extrusion",this.layers,h);for(let{feature:C,id:D,index:O,sourceLayerIndex:H}of a){let Z=this.layers[0]._featureFilter.needGeometry,re=Pi(C,Z);if(!this.layers[0]._featureFilter.filter(new Gi(this.zoom),re,A))continue;let ce={id:D,sourceLayerIndex:H,index:O,geometry:Z?re.geometry:or(C),properties:C.properties,type:C.type,patterns:{}};this.hasDependencies?this.features.push(sb("fill-extrusion",this.layers,ce,{zoom:this.zoom},h)):this.addFeature(ce,ce.geometry,O,A,{},h.subdivisionGranularity),h.featureIndex.insert(C,ce.geometry,O,H,this.index,!0)}}addFeatures(a,h,A){for(let C of this.features){let{geometry:D}=C;this.addFeature(C,D,C.index,h,A,a.subdivisionGranularity)}}update(a,h,A){this.stateDependentLayers.length&&this.programConfigurations.updatePaintArrays(a,h,this.stateDependentLayers,{imagePositions:A})}isEmpty(){return this.layoutVertexArray.length===0&&this.centroidVertexArray.length===0}uploadPending(){return!this.uploaded||this.programConfigurations.needsUpload}upload(a){this.uploaded||(this.layoutVertexBuffer=a.createVertexBuffer(this.layoutVertexArray,y8),this.centroidVertexBuffer=a.createVertexBuffer(this.centroidVertexArray,_8.members,!0),this.indexBuffer=a.createIndexBuffer(this.indexArray)),this.programConfigurations.upload(a),this.uploaded=!0}destroy(){this.layoutVertexBuffer&&(this.layoutVertexBuffer.destroy(),this.indexBuffer.destroy(),this.programConfigurations.destroy(),this.segments.destroy(),this.centroidVertexBuffer.destroy())}addFeature(a,h,A,C,D,O){for(let H of dt(h,500)){let Z={x:0,y:0,sampleCount:0},re=this.layoutVertexArray.length;this.processPolygon(Z,C,a,H,O);let ce=this.layoutVertexArray.length-re,de=Math.floor(Z.x/Z.sampleCount),we=Math.floor(Z.y/Z.sampleCount);for(let Ee=0;Ee{lg(ce,de,we,0,0,1,1,0)},this.segments,this.layoutVertexArray,this.indexArray,re.verticesFlattened,re.indicesTriangles)}_generateSideFaces(a,h){let A=0;for(let C=1;CAi.MAX_VERTEX_ARRAY_LENGTH&&(h.segment=this.segments.prepareSegment(4,this.layoutVertexArray,this.indexArray));let H=D.sub(O)._perp()._unit(),Z=O.dist(D);A+Z>32768&&(A=0),lg(this.layoutVertexArray,D.x,D.y,H.x,H.y,0,0,A),lg(this.layoutVertexArray,D.x,D.y,H.x,H.y,0,1,A),A+=Z,lg(this.layoutVertexArray,O.x,O.y,H.x,H.y,0,0,A),lg(this.layoutVertexArray,O.x,O.y,H.x,H.y,0,1,A);let re=h.segment.vertexLength;this.indexArray.emplaceBack(re,re+2,re+1),this.indexArray.emplaceBack(re+1,re+2,re+3),h.segment.vertexLength+=4,h.segment.primitiveLength+=2}}}function Wc(d,a){for(let h=0;hhr)||d.y===a.y&&(d.y<0||d.y>hr)}function rI(d){return d.every(a=>a.x<0)||d.every(a=>a.x>hr)||d.every(a=>a.y<0)||d.every(a=>a.y>hr)}let iI;ut("FillExtrusionBucket",M2,{omit:["layers","features"]});var eD={get paint(){return iI=iI||new Fa({"fill-extrusion-opacity":new tn(wr["paint_fill-extrusion"]["fill-extrusion-opacity"]),"fill-extrusion-color":new _n(wr["paint_fill-extrusion"]["fill-extrusion-color"]),"fill-extrusion-translate":new tn(wr["paint_fill-extrusion"]["fill-extrusion-translate"]),"fill-extrusion-translate-anchor":new tn(wr["paint_fill-extrusion"]["fill-extrusion-translate-anchor"]),"fill-extrusion-pattern":new Ju(wr["paint_fill-extrusion"]["fill-extrusion-pattern"]),"fill-extrusion-height":new _n(wr["paint_fill-extrusion"]["fill-extrusion-height"]),"fill-extrusion-base":new _n(wr["paint_fill-extrusion"]["fill-extrusion-base"]),"fill-extrusion-vertical-gradient":new tn(wr["paint_fill-extrusion"]["fill-extrusion-vertical-gradient"])})}};class tD extends Gc{constructor(a,h){super(a,eD,h)}createBucket(a){return new M2(a)}queryRadius(){return i0(this.paint.get("fill-extrusion-translate"))}is3D(){return!0}queryIntersectsFeature({queryGeometry:a,feature:h,featureState:A,geometry:C,transform:D,pixelsToTileUnits:O,pixelPosMatrix:H}){let Z=nb(a,this.paint.get("fill-extrusion-translate"),this.paint.get("fill-extrusion-translate-anchor"),-D.bearingInRadians,O),re=this.paint.get("fill-extrusion-height").evaluate(h,A),ce=this.paint.get("fill-extrusion-base").evaluate(h,A),de=function(Ee,De){let ke=[];for(let qe of Ee){let st=[qe.x,qe.y,0,1];Et(st,st,De),ke.push(new s(st[0]/st[3],st[1]/st[3]))}return ke}(Z,H),we=function(Ee,De,ke,qe){let st=[],kt=[],pt=qe[8]*De,_t=qe[9]*De,Ht=qe[10]*De,Qt=qe[11]*De,Ir=qe[8]*ke,oi=qe[9]*ke,Kr=qe[10]*ke,gi=qe[11]*ke;for(let ji of Ee){let vi=[],Qr=[];for(let jr of ji){let dn=jr.x,cn=jr.y,vn=qe[0]*dn+qe[4]*cn+qe[12],rn=qe[1]*dn+qe[5]*cn+qe[13],Vn=qe[2]*dn+qe[6]*cn+qe[14],pa=qe[3]*dn+qe[7]*cn+qe[15],Hs=Vn+Ht,vc=pa+Qt,Ef=vn+Ir,Vu=rn+oi,xc=Vn+Kr,sc=pa+gi,za=new s((vn+pt)/vc,(rn+_t)/vc);za.z=Hs/vc,vi.push(za);let $c=new s(Ef/sc,Vu/sc);$c.z=xc/sc,Qr.push($c)}st.push(vi),kt.push(Qr)}return[st,kt]}(C,ce,re,H);return function(Ee,De,ke){let qe=1/0;ro(ke,De)&&(qe=P2(ke,De[0]));for(let st=0;sth.id),this.index=a.index,this.hasDependencies=!1,this.patternFeatures=[],this.lineClipsArray=[],this.gradients={},this.layers.forEach(h=>{this.gradients[h.id]={}}),this.layoutVertexArray=new At,this.layoutVertexArray2=new vt,this.indexArray=new br,this.programConfigurations=new er(a.layers,a.zoom),this.segments=new Ai,this.maxLineLength=0,this.stateDependentLayerIds=this.layers.filter(h=>h.isStateDependent()).map(h=>h.id)}populate(a,h,A){this.hasDependencies=o0("line",this.layers,h)||this.hasLineDasharray(this.layers);let C=this.layers[0].layout.get("line-sort-key"),D=!C.isConstant(),O=[];for(let{feature:H,id:Z,index:re,sourceLayerIndex:ce}of a){let de=this.layers[0]._featureFilter.needGeometry,we=Pi(H,de);if(!this.layers[0]._featureFilter.filter(new Gi(this.zoom),we,A))continue;let Ee=D?C.evaluate(we,{},A):void 0,De={id:Z,properties:H.properties,type:H.type,sourceLayerIndex:ce,index:re,geometry:de?we.geometry:or(H),patterns:{},dashes:{},sortKey:Ee};O.push(De)}D&&O.sort((H,Z)=>H.sortKey-Z.sortKey);for(let H of O){let{geometry:Z,index:re,sourceLayerIndex:ce}=H;this.hasDependencies?(o0("line",this.layers,h)?sb("line",this.layers,H,{zoom:this.zoom},h):this.hasLineDasharray(this.layers)&&this.addLineDashDependencies(this.layers,H,this.zoom,h),this.patternFeatures.push(H)):this.addFeature(H,Z,re,A,{},{},h.subdivisionGranularity),h.featureIndex.insert(a[re].feature,Z,re,ce,this.index)}}update(a,h,A,C){this.stateDependentLayers.length&&this.programConfigurations.updatePaintArrays(a,h,this.stateDependentLayers,{imagePositions:A,dashPositions:C})}addFeatures(a,h,A,C){for(let D of this.patternFeatures)this.addFeature(D,D.geometry,D.index,h,A,C,a.subdivisionGranularity)}isEmpty(){return this.layoutVertexArray.length===0}uploadPending(){return!this.uploaded||this.programConfigurations.needsUpload}upload(a){this.uploaded||(this.layoutVertexArray2.length!==0&&(this.layoutVertexBuffer2=a.createVertexBuffer(this.layoutVertexArray2,qc)),this.layoutVertexBuffer=a.createVertexBuffer(this.layoutVertexArray,N_),this.indexBuffer=a.createIndexBuffer(this.indexArray)),this.programConfigurations.upload(a),this.uploaded=!0}destroy(){this.layoutVertexBuffer&&(this.layoutVertexBuffer.destroy(),this.indexBuffer.destroy(),this.programConfigurations.destroy(),this.segments.destroy())}lineFeatureClips(a){if(a.properties&&Object.prototype.hasOwnProperty.call(a.properties,"mapbox_clip_start")&&Object.prototype.hasOwnProperty.call(a.properties,"mapbox_clip_end"))return{start:+a.properties.mapbox_clip_start,end:+a.properties.mapbox_clip_end}}addFeature(a,h,A,C,D,O,H){let Z=this.layers[0].layout,re=Z.get("line-join").evaluate(a,{}),ce=Z.get("line-cap"),de=Z.get("line-miter-limit"),we=Z.get("line-round-limit");this.lineClips=this.lineFeatureClips(a);for(let Ee of h)this.addLine(Ee,a,re,ce,de,we,C,H);this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length,a,A,{imagePositions:D,dashPositions:O,canonical:C})}addLine(a,h,A,C,D,O,H,Z){if(this.distance=0,this.scaledDistance=0,this.totalDistance=0,a=D_(a,H?Z.line.getGranularityForZoomLevel(H.z):1),this.lineClips){this.lineClipsArray.push(this.lineClips);for(let pt=0;pt=2&&a[ce-1].equals(a[ce-2]);)ce--;let de=0;for(;de0;if(Kr&&pt>de){let Qr=De.dist(ke);if(Qr>2*we){let jr=De.sub(De.sub(ke)._mult(we/Qr)._round());this.updateDistance(ke,jr),this.addCurrentVertex(jr,st,0,0,Ee),ke=jr}}let ji=ke&&qe,vi=ji?A:re?"butt":C;if(ji&&vi==="round"&&(IrD&&(vi="bevel"),vi==="bevel"&&(Ir>2&&(vi="flipbevel"),Ir100)_t=kt.mult(-1);else{let Qr=Ir*st.add(kt).mag()/st.sub(kt).mag();_t._perp()._mult(Qr*(gi?-1:1))}this.addCurrentVertex(De,_t,0,0,Ee),this.addCurrentVertex(De,_t.mult(-1),0,0,Ee)}else if(vi==="bevel"||vi==="fakeround"){let Qr=-Math.sqrt(Ir*Ir-1),jr=gi?Qr:0,dn=gi?0:Qr;if(ke&&this.addCurrentVertex(De,st,jr,dn,Ee),vi==="fakeround"){let cn=Math.round(180*oi/Math.PI/20);for(let vn=1;vn2*we){let jr=De.add(qe.sub(De)._mult(we/Qr)._round());this.updateDistance(De,jr),this.addCurrentVertex(jr,kt,0,0,Ee),De=jr}}}}addCurrentVertex(a,h,A,C,D,O=!1){let H=h.y*C-h.x,Z=-h.y-h.x*C;this.addHalfVertex(a,h.x+h.y*A,h.y-h.x*A,O,!1,A,D),this.addHalfVertex(a,H,Z,O,!0,-C,D),this.distance>cg/2&&this.totalDistance===0&&(this.distance=0,this.updateScaledDistance(),this.addCurrentVertex(a,h,A,C,D,O))}addHalfVertex({x:a,y:h},A,C,D,O,H,Z){let re=.5*(this.lineClips?this.scaledDistance*(cg-1):this.scaledDistance);this.layoutVertexArray.emplaceBack((a<<1)+(D?1:0),(h<<1)+(O?1:0),Math.round(63*A)+128,Math.round(63*C)+128,1+(H===0?0:H<0?-1:1)|(63&re)<<2,re>>6),this.lineClips&&this.layoutVertexArray2.emplaceBack((this.scaledDistance-this.lineClips.start)/(this.lineClips.end-this.lineClips.start),this.lineClipsArray.length);let ce=Z.vertexLength++;this.e1>=0&&this.e2>=0&&(this.indexArray.emplaceBack(this.e1,ce,this.e2),Z.primitiveLength++),O?this.e2=ce:this.e1=ce}updateScaledDistance(){this.scaledDistance=this.lineClips?this.lineClips.start+(this.lineClips.end-this.lineClips.start)*this.distance/this.totalDistance:this.distance}updateDistance(a,h){this.distance+=a.dist(h),this.updateScaledDistance()}hasLineDasharray(a){for(let h of a){let A=h.paint.get("line-dasharray");if(A&&!A.isConstant())return!0}return!1}addLineDashDependencies(a,h,A,C){for(let D of a){let O=D.paint.get("line-dasharray");if(!O||O.value.kind==="constant")continue;let H=D.layout.get("line-cap")==="round",Z={dasharray:O.value.evaluate({zoom:A-1},h,{}),round:H},re={dasharray:O.value.evaluate({zoom:A},h,{}),round:H},ce={dasharray:O.value.evaluate({zoom:A+1},h,{}),round:H},de=`${Z.dasharray.join(",")},${Z.round}`,we=`${re.dasharray.join(",")},${re.round}`,Ee=`${ce.dasharray.join(",")},${ce.round}`;C.dashDependencies[de]=Z,C.dashDependencies[we]=re,C.dashDependencies[Ee]=ce,h.dashes[D.id]={min:de,mid:we,max:Ee}}}}let db,R2;ut("LineBucket",mv,{omit:["layers","patternFeatures"]});var z_={get paint(){return R2=R2||new Fa({"line-opacity":new _n(wr.paint_line["line-opacity"]),"line-color":new _n(wr.paint_line["line-color"]),"line-translate":new tn(wr.paint_line["line-translate"]),"line-translate-anchor":new tn(wr.paint_line["line-translate-anchor"]),"line-width":new _n(wr.paint_line["line-width"]),"line-gap-width":new _n(wr.paint_line["line-gap-width"]),"line-offset":new _n(wr.paint_line["line-offset"]),"line-blur":new _n(wr.paint_line["line-blur"]),"line-dasharray":new Ju(wr.paint_line["line-dasharray"]),"line-pattern":new Ju(wr.paint_line["line-pattern"]),"line-gradient":new Hc(wr.paint_line["line-gradient"])})},get layout(){return db=db||new Fa({"line-cap":new tn(wr.layout_line["line-cap"]),"line-join":new _n(wr.layout_line["line-join"]),"line-miter-limit":new tn(wr.layout_line["line-miter-limit"]),"line-round-limit":new tn(wr.layout_line["line-round-limit"]),"line-sort-key":new _n(wr.layout_line["line-sort-key"])})}};class s0 extends _n{possiblyEvaluate(a,h){return h=new Gi(Math.floor(h.zoom),{now:h.now,fadeDuration:h.fadeDuration,zoomHistory:h.zoomHistory,transition:h.transition}),super.possiblyEvaluate(a,h)}evaluate(a,h,A,C){return h=Ve({},h,{zoom:Math.floor(h.zoom)}),super.evaluate(a,h,A,C)}}let pb;class iD extends Gc{constructor(a,h){super(a,z_,h),this.gradientVersion=0,pb||(pb=new s0(z_.paint.properties["line-width"].specification),pb.useIntegerZoom=!0)}_handleSpecialPaintPropertyUpdate(a){if(a==="line-gradient"){let h=this.gradientExpression();this.stepInterpolant=!!function(A){return A._styleExpression!==void 0}(h)&&h._styleExpression.expression instanceof pe,this.gradientVersion=(this.gradientVersion+1)%Number.MAX_SAFE_INTEGER}}gradientExpression(){return this._transitionablePaint._values["line-gradient"].value.expression}recalculate(a,h){super.recalculate(a,h),this.paint._values["line-floorwidth"]=pb.possiblyEvaluate(this._transitioningPaint._values["line-width"].value,a)}createBucket(a){return new mv(a)}queryRadius(a){let h=a,A=nD(Sd("line-width",this,h),Sd("line-gap-width",this,h)),C=Sd("line-offset",this,h);return A/2+Math.abs(C)+i0(this.paint.get("line-translate"))}queryIntersectsFeature({queryGeometry:a,feature:h,featureState:A,geometry:C,transform:D,pixelsToTileUnits:O}){let H=nb(a,this.paint.get("line-translate"),this.paint.get("line-translate-anchor"),-D.bearingInRadians,O),Z=O/2*nD(this.paint.get("line-width").evaluate(h,A),this.paint.get("line-gap-width").evaluate(h,A)),re=this.paint.get("line-offset").evaluate(h,A);return re&&(C=function(ce,de){let we=[];for(let Ee=0;Ee=3){for(let ke=0;ke0?a+2*d:d}let vu=na([{name:"a_pos_offset",components:4,type:"Int16"},{name:"a_data",components:4,type:"Uint16"},{name:"a_pixeloffset",components:4,type:"Int16"}],4),oA=na([{name:"a_projected_pos",components:3,type:"Float32"}],4);na([{name:"a_fade_opacity",components:1,type:"Uint32"}],4);let oD=na([{name:"a_placed",components:2,type:"Uint8"},{name:"a_shift",components:2,type:"Float32"},{name:"a_box_real",components:2,type:"Int16"}]);na([{type:"Int16",name:"anchorPointX"},{type:"Int16",name:"anchorPointY"},{type:"Int16",name:"x1"},{type:"Int16",name:"y1"},{type:"Int16",name:"x2"},{type:"Int16",name:"y2"},{type:"Uint32",name:"featureIndex"},{type:"Uint16",name:"sourceLayerIndex"},{type:"Uint16",name:"bucketIndex"}]);let u=na([{name:"a_pos",components:2,type:"Int16"},{name:"a_anchor_pos",components:2,type:"Int16"},{name:"a_extrude",components:2,type:"Int16"}],4),p=na([{name:"a_pos",components:2,type:"Float32"},{name:"a_radius",components:1,type:"Float32"},{name:"a_flags",components:2,type:"Int16"}],4);function _(d,a,h){return d.sections.forEach(A=>{A.text=function(C,D,O){let H=D.layout.get("text-transform").evaluate(O,{});return H==="uppercase"?C=C.toLocaleUpperCase():H==="lowercase"&&(C=C.toLocaleLowerCase()),$n.applyArabicShaping&&(C=$n.applyArabicShaping(C)),C}(A.text,a,h)}),d}na([{name:"triangle",components:3,type:"Uint16"}]),na([{type:"Int16",name:"anchorX"},{type:"Int16",name:"anchorY"},{type:"Uint16",name:"glyphStartIndex"},{type:"Uint16",name:"numGlyphs"},{type:"Uint32",name:"vertexStartIndex"},{type:"Uint32",name:"lineStartIndex"},{type:"Uint32",name:"lineLength"},{type:"Uint16",name:"segment"},{type:"Uint16",name:"lowerSize"},{type:"Uint16",name:"upperSize"},{type:"Float32",name:"lineOffsetX"},{type:"Float32",name:"lineOffsetY"},{type:"Uint8",name:"writingMode"},{type:"Uint8",name:"placedOrientation"},{type:"Uint8",name:"hidden"},{type:"Uint32",name:"crossTileID"},{type:"Int16",name:"associatedIconIndex"}]),na([{type:"Int16",name:"anchorX"},{type:"Int16",name:"anchorY"},{type:"Int16",name:"rightJustifiedTextSymbolIndex"},{type:"Int16",name:"centerJustifiedTextSymbolIndex"},{type:"Int16",name:"leftJustifiedTextSymbolIndex"},{type:"Int16",name:"verticalPlacedTextSymbolIndex"},{type:"Int16",name:"placedIconSymbolIndex"},{type:"Int16",name:"verticalPlacedIconSymbolIndex"},{type:"Uint16",name:"key"},{type:"Uint16",name:"textBoxStartIndex"},{type:"Uint16",name:"textBoxEndIndex"},{type:"Uint16",name:"verticalTextBoxStartIndex"},{type:"Uint16",name:"verticalTextBoxEndIndex"},{type:"Uint16",name:"iconBoxStartIndex"},{type:"Uint16",name:"iconBoxEndIndex"},{type:"Uint16",name:"verticalIconBoxStartIndex"},{type:"Uint16",name:"verticalIconBoxEndIndex"},{type:"Uint16",name:"featureIndex"},{type:"Uint16",name:"numHorizontalGlyphVertices"},{type:"Uint16",name:"numVerticalGlyphVertices"},{type:"Uint16",name:"numIconVertices"},{type:"Uint16",name:"numVerticalIconVertices"},{type:"Uint16",name:"useRuntimeCollisionCircles"},{type:"Uint32",name:"crossTileID"},{type:"Float32",name:"textBoxScale"},{type:"Float32",name:"collisionCircleDiameter"},{type:"Uint16",name:"textAnchorOffsetStartIndex"},{type:"Uint16",name:"textAnchorOffsetEndIndex"}]),na([{type:"Float32",name:"offsetX"}]),na([{type:"Int16",name:"x"},{type:"Int16",name:"y"},{type:"Int16",name:"tileUnitDistanceFromAnchor"}]),na([{type:"Uint16",name:"textAnchor"},{type:"Float32",components:2,name:"textOffset"}]);var R=24;let j={"!":"\uFE15","#":"\uFF03",$:"\uFF04","%":"\uFF05","&":"\uFF06","(":"\uFE35",")":"\uFE36","*":"\uFF0A","+":"\uFF0B",",":"\uFE10","-":"\uFE32",".":"\u30FB","/":"\uFF0F",":":"\uFE13",";":"\uFE14","<":"\uFE3F","=":"\uFF1D",">":"\uFE40","?":"\uFE16","@":"\uFF20","[":"\uFE47","\\":"\uFF3C","]":"\uFE48","^":"\uFF3E",_:"\uFE33","`":"\uFF40","{":"\uFE37","|":"\u2015","}":"\uFE38","~":"\uFF5E","\xA2":"\uFFE0","\xA3":"\uFFE1","\xA5":"\uFFE5","\xA6":"\uFFE4","\xAC":"\uFFE2","\xAF":"\uFFE3","\u2013":"\uFE32","\u2014":"\uFE31","\u2018":"\uFE43","\u2019":"\uFE44","\u201C":"\uFE41","\u201D":"\uFE42","\u2026":"\uFE19","\u22EF":"\uFE19","\u2027":"\u30FB","\u20A9":"\uFFE6","\u3001":"\uFE11","\u3002":"\uFE12","\u3008":"\uFE3F","\u3009":"\uFE40","\u300A":"\uFE3D","\u300B":"\uFE3E","\u300C":"\uFE41","\u300D":"\uFE42","\u300E":"\uFE43","\u300F":"\uFE44","\u3010":"\uFE3B","\u3011":"\uFE3C","\u3014":"\uFE39","\u3015":"\uFE3A","\u3016":"\uFE17","\u3017":"\uFE18","\uFF01":"\uFE15","\uFF08":"\uFE35","\uFF09":"\uFE36","\uFF0C":"\uFE10","\uFF0D":"\uFE32","\uFF0E":"\u30FB","\uFF1A":"\uFE13","\uFF1B":"\uFE14","\uFF1C":"\uFE3F","\uFF1E":"\uFE40","\uFF1F":"\uFE16","\uFF3B":"\uFE47","\uFF3D":"\uFE48","\uFF3F":"\uFE33","\uFF5B":"\uFE37","\uFF5C":"\u2015","\uFF5D":"\uFE38","\uFF5F":"\uFE35","\uFF60":"\uFE36","\uFF61":"\uFE12","\uFF62":"\uFE41","\uFF63":"\uFE42"},$={10:!0,32:!0,38:!0,41:!0,43:!0,45:!0,47:!0,173:!0,183:!0,8203:!0,8208:!0,8211:!0,8231:!0},J={40:!0};function le(d,a,h,A,C,D){if("fontStack"in a){let O=h[a.fontStack],H=O&&O[d];return H?H.metrics.advance*a.scale+C:0}{let O=A[a.imageName];return O?O.displaySize[0]*a.scale*R/D+C:0}}function ve(d,a,h,A){let C=Math.pow(d-a,2);return A?dMath.max(a,this.sections[h].scale),0)}getMaxImageSize(a){let h=0,A=0;for(let C=0;CA))}addImageSection(a){let h=a.image?a.image.name:"";if(h.length===0)return void ln("Can't add FormattedSection with an empty image.");let A=this.getNextImageSectionCharCode();A?(this.text+=String.fromCharCode(A),this.sections.push({scale:1,verticalAlign:a.verticalAlign||"bottom",imageName:h}),this.sectionIndex.push(this.sections.length-1)):ln("Reached maximum number of images 6401")}getNextImageSectionCharCode(){return this.imageSectionID?this.imageSectionID>=63743?null:++this.imageSectionID:(this.imageSectionID=57344,this.imageSectionID)}determineLineBreaks(a,h,A,C,D){let O=[],H=this.determineAverageLineWidth(a,h,A,C,D),Z=this.hasZeroWidthSpaces(),re=0,ce=0,de=this.text[Symbol.iterator](),we=de.next(),Ee=this.text[Symbol.iterator]();Ee.next();let De=Ee.next(),ke=this.text[Symbol.iterator]();ke.next(),ke.next();let qe=ke.next();for(;!we.done;){let st=this.getSection(ce),kt=we.value.codePointAt(0);if(Wr(kt)||(re+=le(kt,st,A,C,a,D)),!De.done){let pt=kr(kt),_t=De.value.codePointAt(0);($[kt]||pt||"imageName"in st||!qe.done&&J[_t])&&O.push(Le(ce+1,re,H,O,Ie(kt,_t,pt&&Z),!1))}ce++,we=de.next(),De=Ee.next(),qe=ke.next()}return ze(Le(this.length(),re,H,O,0,!0))}determineAverageLineWidth(a,h,A,C,D){let O=0,H=0;for(let Z of this.text){let re=this.getSection(H);O+=le(Z.codePointAt(0),re,A,C,a,D),H++}return O/Math.max(1,Math.ceil(O/h))}}let lt=4294967296,Mt=1/lt,Dt=typeof TextDecoder>"u"?null:new TextDecoder("utf-8");class tr{constructor(a=new Uint8Array(16)){this.buf=ArrayBuffer.isView(a)?a:new Uint8Array(a),this.dataView=new DataView(this.buf.buffer),this.pos=0,this.type=0,this.length=this.buf.length}readFields(a,h,A=this.length){for(;this.pos>3,O=this.pos;this.type=7&C,a(D,h,this),this.pos===O&&this.skip(C)}return h}readMessage(a,h){return this.readFields(a,h,this.readVarint()+this.pos)}readFixed32(){let a=this.dataView.getUint32(this.pos,!0);return this.pos+=4,a}readSFixed32(){let a=this.dataView.getInt32(this.pos,!0);return this.pos+=4,a}readFixed64(){let a=this.dataView.getUint32(this.pos,!0)+this.dataView.getUint32(this.pos+4,!0)*lt;return this.pos+=8,a}readSFixed64(){let a=this.dataView.getUint32(this.pos,!0)+this.dataView.getInt32(this.pos+4,!0)*lt;return this.pos+=8,a}readFloat(){let a=this.dataView.getFloat32(this.pos,!0);return this.pos+=4,a}readDouble(){let a=this.dataView.getFloat64(this.pos,!0);return this.pos+=8,a}readVarint(a){let h=this.buf,A,C;return C=h[this.pos++],A=127&C,C<128?A:(C=h[this.pos++],A|=(127&C)<<7,C<128?A:(C=h[this.pos++],A|=(127&C)<<14,C<128?A:(C=h[this.pos++],A|=(127&C)<<21,C<128?A:(C=h[this.pos],A|=(15&C)<<28,function(D,O,H){let Z=H.buf,re,ce;if(ce=Z[H.pos++],re=(112&ce)>>4,ce<128||(ce=Z[H.pos++],re|=(127&ce)<<3,ce<128)||(ce=Z[H.pos++],re|=(127&ce)<<10,ce<128)||(ce=Z[H.pos++],re|=(127&ce)<<17,ce<128)||(ce=Z[H.pos++],re|=(127&ce)<<24,ce<128)||(ce=Z[H.pos++],re|=(1&ce)<<31,ce<128))return qt(D,re,O);throw new Error("Expected varint not more than 10 bytes")}(A,a,this)))))}readVarint64(){return this.readVarint(!0)}readSVarint(){let a=this.readVarint();return a%2==1?(a+1)/-2:a/2}readBoolean(){return Boolean(this.readVarint())}readString(){let a=this.readVarint()+this.pos,h=this.pos;return this.pos=a,a-h>=12&&Dt?Dt.decode(this.buf.subarray(h,a)):function(A,C,D){let O="",H=C;for(;H239?4:Z>223?3:Z>191?2:1;if(H+Ee>D)break;Ee===1?Z<128&&(we=Z):Ee===2?(re=A[H+1],(192&re)==128&&(we=(31&Z)<<6|63&re,we<=127&&(we=null))):Ee===3?(re=A[H+1],ce=A[H+2],(192&re)==128&&(192&ce)==128&&(we=(15&Z)<<12|(63&re)<<6|63&ce,(we<=2047||we>=55296&&we<=57343)&&(we=null))):Ee===4&&(re=A[H+1],ce=A[H+2],de=A[H+3],(192&re)==128&&(192&ce)==128&&(192&de)==128&&(we=(15&Z)<<18|(63&re)<<12|(63&ce)<<6|63&de,(we<=65535||we>=1114112)&&(we=null))),we===null?(we=65533,Ee=1):we>65535&&(we-=65536,O+=String.fromCharCode(we>>>10&1023|55296),we=56320|1023&we),O+=String.fromCharCode(we),H+=Ee}return O}(this.buf,h,a)}readBytes(){let a=this.readVarint()+this.pos,h=this.buf.subarray(this.pos,a);return this.pos=a,h}readPackedVarint(a=[],h){let A=this.readPackedEnd();for(;this.pos127;);else if(h===2)this.pos=this.readVarint()+this.pos;else if(h===5)this.pos+=4;else{if(h!==1)throw new Error(`Unimplemented type: ${h}`);this.pos+=8}}writeTag(a,h){this.writeVarint(a<<3|h)}realloc(a){let h=this.length||16;for(;h268435455||a<0?function(h,A){let C,D;if(h>=0?(C=h%4294967296|0,D=h/4294967296|0):(C=~(-h%4294967296),D=~(-h/4294967296),4294967295^C?C=C+1|0:(C=0,D=D+1|0)),h>=18446744073709552e3||h<-18446744073709552e3)throw new Error("Given varint doesn't fit into 10 bytes");A.realloc(10),function(O,H,Z){Z.buf[Z.pos++]=127&O|128,O>>>=7,Z.buf[Z.pos++]=127&O|128,O>>>=7,Z.buf[Z.pos++]=127&O|128,O>>>=7,Z.buf[Z.pos++]=127&O|128,Z.buf[Z.pos]=127&(O>>>=7)}(C,0,A),function(O,H){let Z=(7&O)<<4;H.buf[H.pos++]|=Z|((O>>>=3)?128:0),O&&(H.buf[H.pos++]=127&O|((O>>>=7)?128:0),O&&(H.buf[H.pos++]=127&O|((O>>>=7)?128:0),O&&(H.buf[H.pos++]=127&O|((O>>>=7)?128:0),O&&(H.buf[H.pos++]=127&O|((O>>>=7)?128:0),O&&(H.buf[H.pos++]=127&O)))))}(D,A)}(a,this):(this.realloc(4),this.buf[this.pos++]=127&a|(a>127?128:0),a<=127||(this.buf[this.pos++]=127&(a>>>=7)|(a>127?128:0),a<=127||(this.buf[this.pos++]=127&(a>>>=7)|(a>127?128:0),a<=127||(this.buf[this.pos++]=a>>>7&127))))}writeSVarint(a){this.writeVarint(a<0?2*-a-1:2*a)}writeBoolean(a){this.writeVarint(+a)}writeString(a){a=String(a),this.realloc(4*a.length),this.pos++;let h=this.pos;this.pos=function(C,D,O){for(let H,Z,re=0;re55295&&H<57344){if(!Z){H>56319||re+1===D.length?(C[O++]=239,C[O++]=191,C[O++]=189):Z=H;continue}if(H<56320){C[O++]=239,C[O++]=191,C[O++]=189,Z=H;continue}H=Z-55296<<10|H-56320|65536,Z=null}else Z&&(C[O++]=239,C[O++]=191,C[O++]=189,Z=null);H<128?C[O++]=H:(H<2048?C[O++]=H>>6|192:(H<65536?C[O++]=H>>12|224:(C[O++]=H>>18|240,C[O++]=H>>12&63|128),C[O++]=H>>6&63|128),C[O++]=63&H|128)}return O}(this.buf,a,this.pos);let A=this.pos-h;A>=128&&ur(h,A,this),this.pos=h-1,this.writeVarint(A),this.pos+=A}writeFloat(a){this.realloc(4),this.dataView.setFloat32(this.pos,a,!0),this.pos+=4}writeDouble(a){this.realloc(8),this.dataView.setFloat64(this.pos,a,!0),this.pos+=8}writeBytes(a){let h=a.length;this.writeVarint(h),this.realloc(h);for(let A=0;A=128&&ur(A,C,this),this.pos=A-1,this.writeVarint(C),this.pos+=C}writeMessage(a,h,A){this.writeTag(a,2),this.writeRawMessage(h,A)}writePackedVarint(a,h){h.length&&this.writeMessage(a,Tr,h)}writePackedSVarint(a,h){h.length&&this.writeMessage(a,Nr,h)}writePackedBoolean(a,h){h.length&&this.writeMessage(a,Ei,h)}writePackedFloat(a,h){h.length&&this.writeMessage(a,Vr,h)}writePackedDouble(a,h){h.length&&this.writeMessage(a,ri,h)}writePackedFixed32(a,h){h.length&&this.writeMessage(a,Ui,h)}writePackedSFixed32(a,h){h.length&&this.writeMessage(a,Cn,h)}writePackedFixed64(a,h){h.length&&this.writeMessage(a,Ki,h)}writePackedSFixed64(a,h){h.length&&this.writeMessage(a,Bn,h)}writeBytesField(a,h){this.writeTag(a,2),this.writeBytes(h)}writeFixed32Field(a,h){this.writeTag(a,5),this.writeFixed32(h)}writeSFixed32Field(a,h){this.writeTag(a,5),this.writeSFixed32(h)}writeFixed64Field(a,h){this.writeTag(a,1),this.writeFixed64(h)}writeSFixed64Field(a,h){this.writeTag(a,1),this.writeSFixed64(h)}writeVarintField(a,h){this.writeTag(a,0),this.writeVarint(h)}writeSVarintField(a,h){this.writeTag(a,0),this.writeSVarint(h)}writeStringField(a,h){this.writeTag(a,2),this.writeString(h)}writeFloatField(a,h){this.writeTag(a,5),this.writeFloat(h)}writeDoubleField(a,h){this.writeTag(a,1),this.writeDouble(h)}writeBooleanField(a,h){this.writeVarintField(a,+h)}}function qt(d,a,h){return h?4294967296*a+(d>>>0):4294967296*(a>>>0)+(d>>>0)}function ur(d,a,h){let A=a<=16383?1:a<=2097151?2:a<=268435455?3:Math.floor(Math.log(a)/(7*Math.LN2));h.realloc(A);for(let C=h.pos-1;C>=d;C--)h.buf[C+A]=h.buf[C]}function Tr(d,a){for(let h=0;hH.h-O.h);let A=[{x:0,y:0,w:Math.max(Math.ceil(Math.sqrt(a/.95)),h),h:1/0}],C=0,D=0;for(let O of d)for(let H=A.length-1;H>=0;H--){let Z=A[H];if(!(O.w>Z.w||O.h>Z.h)){if(O.x=Z.x,O.y=Z.y,D=Math.max(D,O.y+O.h),C=Math.max(C,O.x+O.w),O.w===Z.w&&O.h===Z.h){let re=A.pop();re&&Hke.toCodeUnitIndex(Ir));let Qt=kt(ke.toString(),st);for(let Ir of Qt){let oi=[...Ir].map(()=>0);qe.push(new Ke(Ir,ke.sections,oi))}}else if(pt){qe=[],st=st.map(Kr=>ke.toCodeUnitIndex(Kr));let Qt=0,Ir=[];for(let Kr of ke.text)Ir.push(...Array(Kr.length).fill(ke.sectionIndex[Qt])),Qt++;let oi=pt(ke.text,Ir,st);for(let Kr of oi){let gi=[],ji="";for(let vi of Kr[0])gi.push(Kr[1][ji.length]),ji+=vi;qe.push(new Ke(Kr[0],ke.sections,gi))}}else qe=function(Qt,Ir){let oi=[],Kr=0;for(let gi of Ir)oi.push(Qt.substring(Kr,gi)),Kr=gi;return Krre){let ce=Math.ceil(D/re);C*=ce/O,O=ce}return{x1:A,y1:C,x2:A+D,y2:C+O}}function su(d,a,h,A,C,D){let O=d.image,H;if(O.content){let qe=O.content,st=O.pixelRatio||1;H=[qe[0]/st,qe[1]/st,O.displaySize[0]-qe[2]/st,O.displaySize[1]-qe[3]/st]}let Z=a.left*D,re=a.right*D,ce,de,we,Ee;h==="width"||h==="both"?(Ee=C[0]+Z-A[3],de=C[0]+re+A[1]):(Ee=C[0]+(Z+re-O.displaySize[0])/2,de=Ee+O.displaySize[0]);let De=a.top*D,ke=a.bottom*D;return h==="height"||h==="both"?(ce=C[1]+De-A[0],we=C[1]+ke+A[2]):(ce=C[1]+(De+ke-O.displaySize[1])/2,we=ce+O.displaySize[1]),{image:O,top:ce,right:de,bottom:we,left:Ee,collisionPadding:H}}ut("ImagePosition",Jo),ut("ImageAtlas",xo),n.aA=void 0,(es=n.aA||(n.aA={}))[es.none=0]="none",es[es.horizontal=1]="horizontal",es[es.vertical=2]="vertical",es[es.horizontalOnly=3]="horizontalOnly";let nc=128,ka=32640;function au(d,a){let{expression:h}=a;if(h.kind==="constant")return{kind:"constant",layoutSize:h.evaluate(new Gi(d+1))};if(h.kind==="source")return{kind:"source"};{let{zoomStops:A,interpolationType:C}=h,D=0;for(;DO.id),this.index=a.index,this.pixelRatio=a.pixelRatio,this.sourceLayerIndex=a.sourceLayerIndex,this.hasDependencies=!1,this.hasRTLText=!1,this.sortKeyRanges=[],this.collisionCircleArray=[];let h=this.layers[0]._unevaluatedLayout._values;this.textSizeData=au(this.zoom,h["text-size"]),this.iconSizeData=au(this.zoom,h["icon-size"]);let A=this.layers[0].layout,C=A.get("symbol-sort-key"),D=A.get("symbol-z-order");this.canOverlap=hs(A,"text-overlap","text-allow-overlap")!=="never"||hs(A,"icon-overlap","icon-allow-overlap")!=="never"||A.get("text-ignore-placement")||A.get("icon-ignore-placement"),this.sortFeaturesByKey=D!=="viewport-y"&&!C.isConstant(),this.sortFeaturesByY=(D==="viewport-y"||D==="auto"&&!this.sortFeaturesByKey)&&this.canOverlap,A.get("symbol-placement")==="point"&&(this.writingModes=A.get("text-writing-mode").map(O=>n.aA[O])),this.stateDependentLayerIds=this.layers.filter(O=>O.isStateDependent()).map(O=>O.id),this.sourceID=a.sourceID}createArrays(){this.text=new xu(new er(this.layers,this.zoom,a=>/^text/.test(a))),this.icon=new xu(new er(this.layers,this.zoom,a=>/^icon/.test(a))),this.glyphOffsetArray=new W,this.lineVertexArray=new te,this.symbolInstances=new V,this.textAnchorOffsets=new fe}calculateGlyphDependencies(a,h,A,C,D){for(let O of a)if(h[O.codePointAt(0)]=!0,(A||C)&&D){let H=j[O];H&&(h[H.codePointAt(0)]=!0)}}populate(a,h,A){let C=this.layers[0],D=C.layout,O=D.get("text-font"),H=D.get("text-field"),Z=D.get("icon-image"),re=(H.value.kind!=="constant"||H.value.value instanceof Ql&&!H.value.value.isEmpty()||H.value.value.toString().length>0)&&(O.value.kind!=="constant"||O.value.value.length>0),ce=Z.value.kind!=="constant"||!!Z.value.value||Object.keys(Z.parameters).length>0,de=D.get("symbol-sort-key");if(this.features=[],!re&&!ce)return;let we=h.iconDependencies,Ee=h.glyphDependencies,De=h.availableImages,ke=new Gi(this.zoom);for(let{feature:qe,id:st,index:kt,sourceLayerIndex:pt}of a){let _t=C._featureFilter.needGeometry,Ht=Pi(qe,_t);if(!C._featureFilter.filter(ke,Ht,A))continue;let Qt,Ir;if(_t||(Ht.geometry=or(qe)),re){let Kr=C.getValueAndResolveTokens("text-field",Ht,A,De),gi=Ql.factory(Kr),ji=this.hasRTLText=this.hasRTLText||rf(gi);(!ji||$n.getRTLTextPluginStatus()==="unavailable"||ji&&$n.isParsed())&&(Qt=_(gi,C,Ht))}if(ce){let Kr=C.getValueAndResolveTokens("icon-image",Ht,A,De);Ir=Kr instanceof Ol?Kr:Ol.fromString(Kr)}if(!Qt&&!Ir)continue;let oi=this.sortFeaturesByKey?de.evaluate(Ht,{},A):void 0;if(this.features.push({id:st,text:Qt,icon:Ir,index:kt,sourceLayerIndex:pt,geometry:Ht.geometry,properties:qe.properties,type:cb.types[qe.type],sortKey:oi}),Ir&&(we[Ir.name]=!0),Qt){let Kr=O.evaluate(Ht,{},A).join(","),gi=D.get("text-rotation-alignment")!=="viewport"&&D.get("symbol-placement")!=="point";this.allowVerticalPlacement=this.writingModes&&this.writingModes.indexOf(n.aA.vertical)>=0;for(let ji of Qt.sections)if(ji.image)we[ji.image.name]=!0;else{let vi=ai(Qt.toString()),Qr=ji.fontStack||Kr,jr=Ee[Qr]=Ee[Qr]||{};this.calculateGlyphDependencies(ji.text,jr,gi,this.allowVerticalPlacement,vi)}}}D.get("symbol-placement")==="line"&&(this.features=function(qe){let st={},kt={},pt=[],_t=0;function Ht(Kr){pt.push(qe[Kr]),_t++}function Qt(Kr,gi,ji){let vi=kt[Kr];return delete kt[Kr],kt[gi]=vi,pt[vi].geometry[0].pop(),pt[vi].geometry[0]=pt[vi].geometry[0].concat(ji[0]),vi}function Ir(Kr,gi,ji){let vi=st[gi];return delete st[gi],st[Kr]=vi,pt[vi].geometry[0].shift(),pt[vi].geometry[0]=ji[0].concat(pt[vi].geometry[0]),vi}function oi(Kr,gi,ji){let vi=ji?gi[0][gi[0].length-1]:gi[0][0];return`${Kr}:${vi.x}:${vi.y}`}for(let Kr=0;KrKr.geometry)}(this.features)),this.sortFeaturesByKey&&this.features.sort((qe,st)=>qe.sortKey-st.sortKey)}update(a,h,A){this.stateDependentLayers.length&&(this.text.programConfigurations.updatePaintArrays(a,h,this.layers,{imagePositions:A}),this.icon.programConfigurations.updatePaintArrays(a,h,this.layers,{imagePositions:A}))}isEmpty(){return this.symbolInstances.length===0&&!this.hasRTLText}uploadPending(){return!this.uploaded||this.text.programConfigurations.needsUpload||this.icon.programConfigurations.needsUpload}upload(a){!this.uploaded&&this.hasDebugData()&&(this.textCollisionBox.upload(a),this.iconCollisionBox.upload(a)),this.text.upload(a,this.sortFeaturesByY,!this.uploaded,this.text.programConfigurations.needsUpload),this.icon.upload(a,this.sortFeaturesByY,!this.uploaded,this.icon.programConfigurations.needsUpload),this.uploaded=!0}destroyDebugData(){this.textCollisionBox.destroy(),this.iconCollisionBox.destroy()}destroy(){this.text.destroy(),this.icon.destroy(),this.hasDebugData()&&this.destroyDebugData()}addToLineVertexArray(a,h){let A=this.lineVertexArray.length;if(a.segment!==void 0){let C=a.dist(h[a.segment+1]),D=a.dist(h[a.segment]),O={};for(let H=a.segment+1;H=0;H--)O[H]={x:h[H].x,y:h[H].y,tileUnitDistanceFromAnchor:D},H>0&&(D+=h[H-1].dist(h[H]));for(let H=0;H0}hasIconData(){return this.icon.segments.get().length>0}hasDebugData(){return this.textCollisionBox&&this.iconCollisionBox}hasTextCollisionBoxData(){return this.hasDebugData()&&this.textCollisionBox.segments.get().length>0}hasIconCollisionBoxData(){return this.hasDebugData()&&this.iconCollisionBox.segments.get().length>0}addIndicesForPlacedSymbol(a,h){let A=a.placedSymbolArray.get(h),C=A.vertexStartIndex+4*A.numGlyphs;for(let D=A.vertexStartIndex;DC[H]-C[Z]||D[Z]-D[H]),O}addToSortKeyRanges(a,h){let A=this.sortKeyRanges[this.sortKeyRanges.length-1];A&&A.sortKey===h?A.symbolInstanceEnd=a+1:this.sortKeyRanges.push({sortKey:h,symbolInstanceStart:a,symbolInstanceEnd:a+1})}sortFeatures(a){if(this.sortFeaturesByY&&this.sortedAngle!==a&&!(this.text.segments.get().length>1||this.icon.segments.get().length>1)){this.symbolInstanceIndexes=this.getSortedSymbolIndexes(a),this.sortedAngle=a,this.text.indexArray.clear(),this.icon.indexArray.clear(),this.featureSortOrder=[];for(let h of this.symbolInstanceIndexes){let A=this.symbolInstances.get(h);this.featureSortOrder.push(A.featureIndex),[A.rightJustifiedTextSymbolIndex,A.centerJustifiedTextSymbolIndex,A.leftJustifiedTextSymbolIndex].forEach((C,D,O)=>{C>=0&&O.indexOf(C)===D&&this.addIndicesForPlacedSymbol(this.text,C)}),A.verticalPlacedTextSymbolIndex>=0&&this.addIndicesForPlacedSymbol(this.text,A.verticalPlacedTextSymbolIndex),A.placedIconSymbolIndex>=0&&this.addIndicesForPlacedSymbol(this.icon,A.placedIconSymbolIndex),A.verticalPlacedIconSymbolIndex>=0&&this.addIndicesForPlacedSymbol(this.icon,A.verticalPlacedIconSymbolIndex)}this.text.indexBuffer&&this.text.indexBuffer.updateData(this.text.indexArray),this.icon.indexBuffer&&this.icon.indexBuffer.updateData(this.icon.indexArray)}}}let ku,$s;ut("SymbolBucket",dl,{omit:["layers","collisionBoxArray","features","compareText"]}),dl.MAX_GLYPHS=65535,dl.addDynamicAttributes=Bs;var Dp={get paint(){return $s=$s||new Fa({"icon-opacity":new _n(wr.paint_symbol["icon-opacity"]),"icon-color":new _n(wr.paint_symbol["icon-color"]),"icon-halo-color":new _n(wr.paint_symbol["icon-halo-color"]),"icon-halo-width":new _n(wr.paint_symbol["icon-halo-width"]),"icon-halo-blur":new _n(wr.paint_symbol["icon-halo-blur"]),"icon-translate":new tn(wr.paint_symbol["icon-translate"]),"icon-translate-anchor":new tn(wr.paint_symbol["icon-translate-anchor"]),"text-opacity":new _n(wr.paint_symbol["text-opacity"]),"text-color":new _n(wr.paint_symbol["text-color"],{runtimeType:Di,getOverride:d=>d.textColor,hasOverride:d=>!!d.textColor}),"text-halo-color":new _n(wr.paint_symbol["text-halo-color"]),"text-halo-width":new _n(wr.paint_symbol["text-halo-width"]),"text-halo-blur":new _n(wr.paint_symbol["text-halo-blur"]),"text-translate":new tn(wr.paint_symbol["text-translate"]),"text-translate-anchor":new tn(wr.paint_symbol["text-translate-anchor"])})},get layout(){return ku=ku||new Fa({"symbol-placement":new tn(wr.layout_symbol["symbol-placement"]),"symbol-spacing":new tn(wr.layout_symbol["symbol-spacing"]),"symbol-avoid-edges":new tn(wr.layout_symbol["symbol-avoid-edges"]),"symbol-sort-key":new _n(wr.layout_symbol["symbol-sort-key"]),"symbol-z-order":new tn(wr.layout_symbol["symbol-z-order"]),"icon-allow-overlap":new tn(wr.layout_symbol["icon-allow-overlap"]),"icon-overlap":new tn(wr.layout_symbol["icon-overlap"]),"icon-ignore-placement":new tn(wr.layout_symbol["icon-ignore-placement"]),"icon-optional":new tn(wr.layout_symbol["icon-optional"]),"icon-rotation-alignment":new tn(wr.layout_symbol["icon-rotation-alignment"]),"icon-size":new _n(wr.layout_symbol["icon-size"]),"icon-text-fit":new tn(wr.layout_symbol["icon-text-fit"]),"icon-text-fit-padding":new tn(wr.layout_symbol["icon-text-fit-padding"]),"icon-image":new _n(wr.layout_symbol["icon-image"]),"icon-rotate":new _n(wr.layout_symbol["icon-rotate"]),"icon-padding":new _n(wr.layout_symbol["icon-padding"]),"icon-keep-upright":new tn(wr.layout_symbol["icon-keep-upright"]),"icon-offset":new _n(wr.layout_symbol["icon-offset"]),"icon-anchor":new _n(wr.layout_symbol["icon-anchor"]),"icon-pitch-alignment":new tn(wr.layout_symbol["icon-pitch-alignment"]),"text-pitch-alignment":new tn(wr.layout_symbol["text-pitch-alignment"]),"text-rotation-alignment":new tn(wr.layout_symbol["text-rotation-alignment"]),"text-field":new _n(wr.layout_symbol["text-field"]),"text-font":new _n(wr.layout_symbol["text-font"]),"text-size":new _n(wr.layout_symbol["text-size"]),"text-max-width":new _n(wr.layout_symbol["text-max-width"]),"text-line-height":new tn(wr.layout_symbol["text-line-height"]),"text-letter-spacing":new _n(wr.layout_symbol["text-letter-spacing"]),"text-justify":new _n(wr.layout_symbol["text-justify"]),"text-radial-offset":new _n(wr.layout_symbol["text-radial-offset"]),"text-variable-anchor":new tn(wr.layout_symbol["text-variable-anchor"]),"text-variable-anchor-offset":new _n(wr.layout_symbol["text-variable-anchor-offset"]),"text-anchor":new _n(wr.layout_symbol["text-anchor"]),"text-max-angle":new tn(wr.layout_symbol["text-max-angle"]),"text-writing-mode":new tn(wr.layout_symbol["text-writing-mode"]),"text-rotate":new _n(wr.layout_symbol["text-rotate"]),"text-padding":new tn(wr.layout_symbol["text-padding"]),"text-keep-upright":new tn(wr.layout_symbol["text-keep-upright"]),"text-transform":new _n(wr.layout_symbol["text-transform"]),"text-offset":new _n(wr.layout_symbol["text-offset"]),"text-allow-overlap":new tn(wr.layout_symbol["text-allow-overlap"]),"text-overlap":new tn(wr.layout_symbol["text-overlap"]),"text-ignore-placement":new tn(wr.layout_symbol["text-ignore-placement"]),"text-optional":new tn(wr.layout_symbol["text-optional"])})}};class ed{constructor(a){if(a.property.overrides===void 0)throw new Error("overrides must be provided to instantiate FormatSectionOverride class");this.type=a.property.overrides?a.property.overrides.runtimeType:si,this.defaultValue=a}evaluate(a){if(a.formattedSection){let h=this.defaultValue.property.overrides;if(h&&h.hasOverride(a.formattedSection))return h.getOverride(a.formattedSection)}return a.feature&&a.featureState?this.defaultValue.evaluate(a.feature,a.featureState):this.defaultValue.property.specification.default}eachChild(a){this.defaultValue.isConstant()||a(this.defaultValue.value._styleExpression.expression)}outputDefined(){return!1}serialize(){return null}}ut("FormatSectionOverride",ed,{omit:["defaultValue"]});class Qd extends Gc{constructor(a,h){super(a,Dp,h)}recalculate(a,h){if(super.recalculate(a,h),this.layout.get("icon-rotation-alignment")==="auto"&&(this.layout._values["icon-rotation-alignment"]=this.layout.get("symbol-placement")!=="point"?"map":"viewport"),this.layout.get("text-rotation-alignment")==="auto"&&(this.layout._values["text-rotation-alignment"]=this.layout.get("symbol-placement")!=="point"?"map":"viewport"),this.layout.get("text-pitch-alignment")==="auto"&&(this.layout._values["text-pitch-alignment"]=this.layout.get("text-rotation-alignment")==="map"?"map":"viewport"),this.layout.get("icon-pitch-alignment")==="auto"&&(this.layout._values["icon-pitch-alignment"]=this.layout.get("icon-rotation-alignment")),this.layout.get("symbol-placement")==="point"){let A=this.layout.get("text-writing-mode");if(A){let C=[];for(let D of A)C.indexOf(D)<0&&C.push(D);this.layout._values["text-writing-mode"]=C}else this.layout._values["text-writing-mode"]=["horizontal"]}this._setPaintOverrides()}getValueAndResolveTokens(a,h,A,C){let D=this.layout.get(a).evaluate(h,{},A,C),O=this._unevaluatedLayout._values[a];return O.isDataDriven()||yh(O.value)||!D?D:function(H,Z){return Z.replace(/{([^{}]+)}/g,(re,ce)=>H&&ce in H?String(H[ce]):"")}(h.properties,D)}createBucket(a){return new dl(a)}queryRadius(){return 0}queryIntersectsFeature(){throw new Error("Should take a different path in FeatureIndex")}_setPaintOverrides(){for(let a of Dp.paint.overridableProperties){if(!Qd.hasPaintOverride(this.layout,a))continue;let h=this.paint.get(a),A=new ed(h),C=new Mc(A,h.property.specification),D=null;D=h.value.kind==="constant"||h.value.kind==="source"?new $f("source",C):new Yu("composite",C,h.value.zoomStops),this.paint._values[a]=new Vs(h.property,D,h.parameters)}}_handleOverridablePaintPropertyUpdate(a,h,A){return!(!this.layout||h.isDataDriven()||A.isDataDriven())&&Qd.hasPaintOverride(this.layout,a)}static hasPaintOverride(a,h){let A=a.get("text-field"),C=Dp.paint.properties[h],D=!1,O=H=>{for(let Z of H)if(C.overrides&&C.overrides.hasOverride(Z))return void(D=!0)};if(A.value.kind==="constant"&&A.value.value instanceof Ql)O(A.value.value.sections);else if(A.value.kind==="source"||A.value.kind==="composite"){let H=re=>{D||(re instanceof Ws&&La(re.value)===po?O(re.value.sections):re instanceof Gr?O(re.sections):re.eachChild(H))},Z=A.value;Z._styleExpression&&H(Z._styleExpression.expression)}return D}}let oc;var ug={get paint(){return oc=oc||new Fa({"background-color":new tn(wr.paint_background["background-color"]),"background-pattern":new jc(wr.paint_background["background-pattern"]),"background-opacity":new tn(wr.paint_background["background-opacity"])})}};class Op extends Gc{constructor(a,h){super(a,ug,h)}}class gv extends Gc{constructor(a,h){super(a,{},h),this.onAdd=A=>{this.implementation.onAdd&&this.implementation.onAdd(A,A.painter.context.gl)},this.onRemove=A=>{this.implementation.onRemove&&this.implementation.onRemove(A,A.painter.context.gl)},this.implementation=a}is3D(){return this.implementation.renderingMode==="3d"}hasOffscreenPass(){return this.implementation.prerender!==void 0}recalculate(){}updateTransitions(){}hasTransition(){return!1}serialize(){throw new Error("Custom layers cannot be serialized")}}class U_{constructor(a){this._methodToThrottle=a,this._triggered=!1,typeof MessageChannel<"u"&&(this._channel=new MessageChannel,this._channel.port2.onmessage=()=>{this._triggered=!1,this._methodToThrottle()})}trigger(){this._triggered||(this._triggered=!0,this._channel?this._channel.port1.postMessage(!0):setTimeout(()=>{this._triggered=!1,this._methodToThrottle()},0))}remove(){delete this._channel,this._methodToThrottle=()=>{}}}let Av={once:!0},_m=63710088e-1;class Jd{constructor(a,h){if(isNaN(a)||isNaN(h))throw new Error(`Invalid LngLat object: (${a}, ${h})`);if(this.lng=+a,this.lat=+h,this.lat>90||this.lat<-90)throw new Error("Invalid LngLat latitude value: must be between -90 and 90")}wrap(){return new Jd(Gn(this.lng,-180,180),this.lat)}toArray(){return[this.lng,this.lat]}toString(){return`LngLat(${this.lng}, ${this.lat})`}distanceTo(a){let h=Math.PI/180,A=this.lat*h,C=a.lat*h,D=Math.sin(A)*Math.sin(C)+Math.cos(A)*Math.cos(C)*Math.cos((a.lng-this.lng)*h);return _m*Math.acos(Math.min(D,1))}static convert(a){if(a instanceof Jd)return a;if(Array.isArray(a)&&(a.length===2||a.length===3))return new Jd(Number(a[0]),Number(a[1]));if(!Array.isArray(a)&&typeof a=="object"&&a!==null)return new Jd(Number("lng"in a?a.lng:a.lon),Number(a.lat));throw new Error("`LngLatLike` argument must be specified as a LngLat instance, an object {lng: , lat: }, an object {lon: , lat: }, or an array of [, ]")}}let mb=2*Math.PI*_m;function V_(d){return mb*Math.cos(d*Math.PI/180)}function _v(d){return(180+d)/360}function gb(d){return(180-180/Math.PI*Math.log(Math.tan(Math.PI/4+d*Math.PI/360)))/360}function Ab(d,a){return d/V_(a)}function hg(d){return 360*d-180}function sA(d){return 360/Math.PI*Math.atan(Math.exp((180-360*d)*Math.PI/180))-90}function j_(d,a){return d*V_(sA(a))}class Fp{constructor(a,h,A=0){this.x=+a,this.y=+h,this.z=+A}static fromLngLat(a,h=0){let A=Jd.convert(a);return new Fp(_v(A.lng),gb(A.lat),Ab(h,A.lat))}toLngLat(){return new Jd(hg(this.x),sA(this.y))}toAltitude(){return j_(this.z,this.y)}meterInMercatorCoordinateUnits(){return 1/mb*(a=sA(this.y),1/Math.cos(a*Math.PI/180));var a}}function H_(d,a,h){var A=2*Math.PI*6378137/256/Math.pow(2,h);return[d*A-2*Math.PI*6378137/2,a*A-2*Math.PI*6378137/2]}class yv{constructor(a,h,A){if(!function(C,D,O){return!(C<0||C>25||O<0||O>=Math.pow(2,C)||D<0||D>=Math.pow(2,C))}(a,h,A))throw new Error(`x=${h}, y=${A}, z=${a} outside of bounds. 0<=x<${Math.pow(2,a)}, 0<=y<${Math.pow(2,a)} 0<=z<=25 `);this.z=a,this.x=h,this.y=A,this.key=fg(0,a,a,h,A)}equals(a){return this.z===a.z&&this.x===a.x&&this.y===a.y}url(a,h,A){let C=function(O,H,Z){var re=H_(256*O,256*(H=Math.pow(2,Z)-H-1),Z),ce=H_(256*(O+1),256*(H+1),Z);return re[0]+","+re[1]+","+ce[0]+","+ce[1]}(this.x,this.y,this.z),D=function(O,H,Z){let re,ce="";for(let de=O;de>0;de--)re=1<1?"@2x":"").replace(/{quadkey}/g,D).replace(/{bbox-epsg-3857}/g,C)}isChildOf(a){let h=this.z-a.z;return h>0&&a.x===this.x>>h&&a.y===this.y>>h}getTilePoint(a){let h=Math.pow(2,this.z);return new s((a.x*h-this.x)*hr,(a.y*h-this.y)*hr)}toString(){return`${this.z}/${this.x}/${this.y}`}}class _b{constructor(a,h){this.wrap=a,this.canonical=h,this.key=fg(a,h.z,h.z,h.x,h.y)}}class nf{constructor(a,h,A,C,D){if(this.terrainRttPosMatrix32f=null,a= z; overscaledZ = ${a}; z = ${A}`);this.overscaledZ=a,this.wrap=h,this.canonical=new yv(A,+C,+D),this.key=fg(h,a,A,C,D)}clone(){return new nf(this.overscaledZ,this.wrap,this.canonical.z,this.canonical.x,this.canonical.y)}equals(a){return this.overscaledZ===a.overscaledZ&&this.wrap===a.wrap&&this.canonical.equals(a.canonical)}scaledTo(a){if(a>this.overscaledZ)throw new Error(`targetZ > this.overscaledZ; targetZ = ${a}; overscaledZ = ${this.overscaledZ}`);let h=this.canonical.z-a;return a>this.canonical.z?new nf(a,this.wrap,this.canonical.z,this.canonical.x,this.canonical.y):new nf(a,this.wrap,a,this.canonical.x>>h,this.canonical.y>>h)}isOverscaled(){return this.overscaledZ>this.canonical.z}calculateScaledKey(a,h){if(a>this.overscaledZ)throw new Error(`targetZ > this.overscaledZ; targetZ = ${a}; overscaledZ = ${this.overscaledZ}`);let A=this.canonical.z-a;return a>this.canonical.z?fg(this.wrap*+h,a,this.canonical.z,this.canonical.x,this.canonical.y):fg(this.wrap*+h,a,a,this.canonical.x>>A,this.canonical.y>>A)}isChildOf(a){if(a.wrap!==this.wrap||this.overscaledZ-a.overscaledZ<=0)return!1;if(a.overscaledZ===0)return this.overscaledZ>0;let h=this.canonical.z-a.canonical.z;return!(h<0)&&a.canonical.x===this.canonical.x>>h&&a.canonical.y===this.canonical.y>>h}children(a){if(this.overscaledZ>=a)return[new nf(this.overscaledZ+1,this.wrap,this.canonical.z,this.canonical.x,this.canonical.y)];let h=this.canonical.z+1,A=2*this.canonical.x,C=2*this.canonical.y;return[new nf(h,this.wrap,h,A,C),new nf(h,this.wrap,h,A+1,C),new nf(h,this.wrap,h,A,C+1),new nf(h,this.wrap,h,A+1,C+1)]}isLessThan(a){return this.wrapa.wrap)&&(this.overscaledZa.overscaledZ)&&(this.canonical.xa.canonical.x)&&this.canonical.yD.key===A);C>-1&&d.addOrUpdateProperties.splice(C,1)}return(d.removeAllProperties||a.removeAllProperties)&&(h.removeAllProperties=!0),(d.removeProperties||a.removeProperties)&&(h.removeProperties=[...d.removeProperties||[],...a.removeProperties||[]]),(d.addOrUpdateProperties||a.addOrUpdateProperties)&&(h.addOrUpdateProperties=[...d.addOrUpdateProperties||[],...a.addOrUpdateProperties||[]]),(d.newGeometry||a.newGeometry)&&(h.newGeometry=a.newGeometry||d.newGeometry),h}function vv(d){var a,h;if(!d)return{};let A={};return A.removeAll=d.removeAll,A.remove=new Set(d.remove||[]),A.add=new Map((a=d.add)===null||a===void 0?void 0:a.map(C=>[C.id,C])),A.update=new Map((h=d.update)===null||h===void 0?void 0:h.map(C=>[C.id,C])),A}ut("CanonicalTileID",yv),ut("OverscaledTileID",nf,{omit:["terrainRttPosMatrix32f"]});class xv{constructor(a){this._stringToNumber={},this._numberToString=[];for(let h=0;h=this._numberToString.length)throw new Error(`Out of bounds. Index requested n=${a} can't be >= this._numberToString.length ${this._numberToString.length}`);return this._numberToString[a]}}class vb{constructor(a,h,A,C,D){this.type="Feature",this._vectorTileFeature=a,this._x=A,this._y=C,this._z=h,this.properties=a.properties,this.id=D}projectPoint(a,h,A,C){return[360*(a.x+h)/C-180,360/Math.PI*Math.atan(Math.exp((1-2*(a.y+A)/C)*Math.PI))-90]}projectLine(a,h,A,C){return a.map(D=>this.projectPoint(D,h,A,C))}get geometry(){if(this._geometry)return this._geometry;let a=this._vectorTileFeature,h=a.extent*Math.pow(2,this._z),A=a.extent*this._x,C=a.extent*this._y,D=a.loadGeometry();switch(a.type){case 1:{let O=[];for(let Z of D)O.push(Z[0]);let H=this.projectLine(O,A,C,h);this._geometry=O.length===1?{type:"Point",coordinates:H[0]}:{type:"MultiPoint",coordinates:H};break}case 2:{let O=D.map(H=>this.projectLine(H,A,C,h));this._geometry=O.length===1?{type:"LineString",coordinates:O[0]}:{type:"MultiLineString",coordinates:O};break}case 3:{let O=tI(D),H=[];for(let Z of O)H.push(Z.map(re=>this.projectLine(re,A,C,h)));this._geometry=H.length===1?{type:"Polygon",coordinates:H[0]}:{type:"MultiPolygon",coordinates:H};break}default:throw new Error(`unknown feature type: ${a.type}`)}return this._geometry}set geometry(a){this._geometry=a}toJSON(){let a={geometry:this.geometry};for(let h in this)h!=="_geometry"&&h!=="_vectorTileFeature"&&h!=="_x"&&h!=="_y"&&h!=="_z"&&(a[h]=this[h]);return a}}class ym{_name;dataBuffer;nullabilityBuffer;_size;constructor(a,h,A){this._name=a,this.dataBuffer=h,typeof A=="number"?this._size=A:(this.nullabilityBuffer=A,this._size=A.size())}getValue(a){return this.nullabilityBuffer&&!this.nullabilityBuffer.get(a)?null:this.getValueFromBuffer(a)}has(a){return this.nullabilityBuffer&&this.nullabilityBuffer.get(a)||!this.nullabilityBuffer}get name(){return this._name}get size(){return this._size}}class G_ extends ym{}class lA extends G_{getValueFromBuffer(a){return this.dataBuffer[a]}}class W_ extends G_{getValueFromBuffer(a){return this.dataBuffer[a]}}class cA extends ym{delta;constructor(a,h,A,C){super(a,h,C),this.delta=A}}class q_ extends cA{constructor(a,h,A,C){super(a,Int32Array.of(h),A,C)}getValueFromBuffer(a){return this.dataBuffer[0]+a*this.delta}}class uA extends ym{constructor(a,h,A){super(a,Int32Array.of(h),A)}getValueFromBuffer(a){return this.dataBuffer[0]}}class nI{_name;_geometryVector;_idVector;_propertyVectors;_extent;propertyVectorsMap;constructor(a,h,A,C,D=4096){this._name=a,this._geometryVector=h,this._idVector=A,this._propertyVectors=C,this._extent=D}get name(){return this._name}get idVector(){return this._idVector}get geometryVector(){return this._geometryVector}get propertyVectors(){return this._propertyVectors}getPropertyVector(a){return this.propertyVectorsMap||(this.propertyVectorsMap=new Map(this._propertyVectors.map(h=>[h.name,h]))),this.propertyVectorsMap.get(a)}*[Symbol.iterator](){let a=this.geometryVector[Symbol.iterator](),h=0;for(;h>4,Z<128||(Z=D[O.get()],O.increment(),H|=(127&Z)<<3,Z<128)||(Z=D[O.get()],O.increment(),H|=(127&Z)<<10,Z<128)||(Z=D[O.get()],O.increment(),H|=(127&Z)<<17,Z<128)||(Z=D[O.get()],O.increment(),H|=(127&Z)<<24,Z<128)||(Z=D[O.get()],O.increment(),H|=(1&Z)<<31,Z<128))return 4294967296*H+(C>>>0);throw new Error("Expected varint not more than 10 bytes")}(h,d,a)))))}function xb(d,a,h,A){throw new Error("FastPFor is not implemented yet.")}function bm(d){return d>>>1^-(1&d)}function l0(d){return d>>1n^-(1n&d)}function B2(d,a){let h=0n,A=0,C=a.get();for(;C=64)throw new Error("Varint too long")}return a.set(C),h}function L2(d,a,h){let A=new Int32Array(h),C=0;for(let D=0;D=4)for(let A=d[0];h>>1^-(1&d[0]),d[1]=d[1]>>>1^-(1&d[1]);let a=d.length/4*4,h=2;if(a>=4)for(;h>>1^-(1&A))+d[h-2],d[h+1]=(C>>>1^-(1&C))+d[h-1],d[h+2]=(D>>>1^-(1&D))+d[h],d[h+3]=(O>>>1^-(1&O))+d[h+1]}for(;h!=d.length;h+=2)d[h]=(d[h]>>>1^-(1&d[h]))+d[h-2],d[h+1]=(d[h+1]>>>1^-(1&d[h+1]))+d[h-1]}(function(d){d.NONE="NONE",d.DELTA="DELTA",d.COMPONENTWISE_DELTA="COMPONENTWISE_DELTA",d.RLE="RLE",d.MORTON="MORTON",d.PDE="PDE"})(Es||(Es={})),function(d){d.NONE="NONE",d.FAST_PFOR="FAST_PFOR",d.VARINT="VARINT",d.ALP="ALP"}(dg||(dg={})),function(d){d.PRESENT="PRESENT",d.DATA="DATA",d.OFFSET="OFFSET",d.LENGTH="LENGTH"}(Nu||(Nu={}));class O2{_dictionaryType;_offsetType;_lengthType;constructor(a,h,A){this._dictionaryType=a,this._offsetType=h,this._lengthType=A}get dictionaryType(){return this._dictionaryType}get offsetType(){return this._offsetType}get lengthType(){return this._lengthType}}function of(d,a){let h=function(A,C){let D=A[C.get()],O=Object.values(Nu)[D>>4],H=null;switch(O){case Nu.DATA:H=new O2(Object.values(vm)[15&D]);break;case Nu.OFFSET:H=new O2(null,Object.values(xm)[15&D]);break;case Nu.LENGTH:H=new O2(null,null,Object.values(ta)[15&D])}C.increment();let Z=A[C.get()],re=Object.values(Es)[Z>>5],ce=Object.values(Es)[Z>>2&7],de=Object.values(dg)[3&Z];C.increment();let we=Uu(A,C,2),Ee=we[0];return{physicalStreamType:O,logicalStreamType:H,logicalLevelTechnique1:re,logicalLevelTechnique2:ce,physicalLevelTechnique:de,numValues:Ee,byteLength:we[1],decompressedCount:Ee}}(d,a);return h.logicalLevelTechnique1===Es.MORTON?function(A,C,D){let O=Uu(C,D,2);return{physicalStreamType:A.physicalStreamType,logicalStreamType:A.logicalStreamType,logicalLevelTechnique1:A.logicalLevelTechnique1,logicalLevelTechnique2:A.logicalLevelTechnique2,physicalLevelTechnique:A.physicalLevelTechnique,numValues:A.numValues,byteLength:A.byteLength,decompressedCount:A.decompressedCount,numBits:O[0],coordinateShift:O[1]}}(h,d,a):Es.RLE!==h.logicalLevelTechnique1&&Es.RLE!==h.logicalLevelTechnique2||dg.NONE===h.physicalLevelTechnique?h:function(A,C,D){let O=Uu(C,D,2);return{physicalStreamType:A.physicalStreamType,logicalStreamType:A.logicalStreamType,logicalLevelTechnique1:A.logicalLevelTechnique1,logicalLevelTechnique2:A.logicalLevelTechnique2,physicalLevelTechnique:A.physicalLevelTechnique,numValues:A.numValues,byteLength:A.byteLength,decompressedCount:O[1],runs:O[0],numRleValues:O[1]}}(h,d,a)}(function(d){d.NONE="NONE",d.SINGLE="SINGLE",d.SHARED="SHARED",d.VERTEX="VERTEX",d.MORTON="MORTON",d.FSST="FSST"})(vm||(vm={})),function(d){d.VERTEX="VERTEX",d.INDEX="INDEX",d.STRING="STRING",d.KEY="KEY"}(xm||(xm={})),function(d){d.VAR_BINARY="VAR_BINARY",d.GEOMETRIES="GEOMETRIES",d.PARTS="PARTS",d.RINGS="RINGS",d.TRIANGLES="TRIANGLES",d.SYMBOL="SYMBOL",d.DICTIONARY="DICTIONARY"}(ta||(ta={})),function(d){d[d.FLAT=0]="FLAT",d[d.CONST=1]="CONST",d[d.SEQUENCE=2]="SEQUENCE",d[d.DICTIONARY=3]="DICTIONARY",d[d.FSST_DICTIONARY=4]="FSST_DICTIONARY"}(el||(el={}));class kp{values;_size;constructor(a,h){this.values=a,this._size=h}get(a){let h=Math.floor(a/8);return(this.values[h]>>a%8&1)==1}set(a,h){let A=Math.floor(a/8);this.values[A]=this.values[A]|(h?1:0)<>a%8&1}size(){return this._size}getBuffer(){return this.values}}function pl(d,a,h,A,C){return function(D,O,H){switch(O.logicalLevelTechnique1){case Es.DELTA:return O.logicalLevelTechnique2===Es.RLE?function(Z,re,ce){let de=new Int32Array(ce),we=0,Ee=0;for(let De=0;De>>1^-(1&Z[0]);let re=Z.length/4*4,ce=1;if(re>=4)for(;ce>>1^-(1&de))+Z[ce-1],Z[ce+1]=(we>>>1^-(1&we))+Z[ce],Z[ce+2]=(Ee>>>1^-(1&Ee))+Z[ce+1],Z[ce+3]=(De>>>1^-(1&De))+Z[ce+2]}for(;ce!=Z.length;++ce)Z[ce]=(Z[ce]>>>1^-(1&Z[ce]))+Z[ce-1]}(D),D);case Es.RLE:return function(Z,re,ce){return ce?function(de,we,Ee){let De=new Int32Array(Ee),ke=0;for(let qe=0;qe>>1^-(1&kt),De.fill(kt,ke,ke+st),ke+=st}return De}(Z,re.runs,re.numRleValues):L2(Z,re.runs,re.numRleValues)}(D,O,H);case Es.MORTON:return D2(D),D;case Es.COMPONENTWISE_DELTA:return sI(D),D;case Es.NONE:return H&&function(Z){for(let re=0;re>>1^-(1&ce)}}(D),D;default:throw new Error(`The specified Logical level technique is not supported: ${O.logicalLevelTechnique1}`)}}(bb(d,a,h),h,A)}function wm(d,a,h){return function(A,C){if(C.logicalLevelTechnique1===Es.DELTA&&C.logicalLevelTechnique2===Es.NONE)return function(O){let H=new Int32Array(O.length+1);H[0]=0,H[1]=bm(O[0]);let Z=H[1],re=2;for(;re!=H.length;++re){let ce=O[re-1];Z+=ce>>>1^-(1&ce),H[re]=H[re-1]+Z}return H}(A);if(C.logicalLevelTechnique1===Es.RLE&&C.logicalLevelTechnique2===Es.NONE)return function(O,H,Z){let re=new Int32Array(Z+1);re[0]=0;let ce=1,de=re[0];for(let we=0;we>>1^-(1&De);for(let ke=ce;ke>1n^-(1n&H[0]);let Z=H.length/4*4,re=1;if(Z>=4)for(;re>1n^-(1n&ce))+H[re-1],H[re+1]=(de>>1n^-(1n&de))+H[re],H[re+2]=(we>>1n^-(1n&we))+H[re+1],H[re+3]=(Ee>>1n^-(1n&Ee))+H[re+2]}for(;re!=H.length;++re)H[re]=(H[re]>>1n^-(1n&H[re]))+H[re-1]}(C),C);case Es.RLE:return function(H,Z,re){return re?function(ce,de,we){let Ee=new BigInt64Array(we),De=0;for(let ke=0;ke>1n^-(1n&st),Ee.fill(st,De,De+qe),De+=qe}return Ee}(H,Z.runs,Z.numRleValues):oI(H,Z.runs,Z.numRleValues)}(C,D,O);case Es.NONE:return O&&function(H){for(let Z=0;Z>1n^-(1n&re)}}(C),C;default:throw new Error(`The specified Logical level technique is not supported: ${D.logicalLevelTechnique1}`)}}($_(d,a,h.numValues),h,A)}function X_(d,a,h,A){let C=$_(d,a,h.numValues);if(C.length===1){let D=C[0];return A?l0(D):D}return A?function(D){return l0(D[1])}(C):function(D){return D[1]}(C)}function fA(d,a,h,A,C){return function(D,O,H,Z){switch(O.logicalLevelTechnique1){case Es.DELTA:return O.logicalLevelTechnique2===Es.RLE&&(D=L2(D,O.runs,O.numRleValues)),function(re,ce){let de=new Int32Array(re.size()),we=0;re.get(0)?(de[0]=re.get(0)?ce[0]>>>1^-(1&ce[0]):0,we=1):de[0]=0;let Ee=1;for(;Ee!=de.length;++Ee)de[Ee]=re.get(Ee)?de[Ee-1]+(ce[we]>>>1^-(1&ce[we++])):de[Ee-1];return de}(Z,D);case Es.RLE:return function(re,ce,de,we){let Ee=ce;return de?function(De,ke,qe){let st=new Int32Array(De.size()),kt=0;for(let pt=0;pt>>1^-(1&Ht);for(let Qt=kt;Qt>>1^-(1&De)}else de[Ee]=0;return de}(Z,D):function(re,ce){let de=new Int32Array(re.size()),we=0,Ee=0;for(;Ee!=de.length;++Ee)de[Ee]=re.get(Ee)?ce[we++]:0;return de}(Z,D),D;default:throw new Error("The specified Logical level technique is not supported")}}(h.physicalLevelTechnique===dg.FAST_PFOR?xb():Uu(d,a,h.numValues),h,A,C)}function c0(d,a,h,A){let C=d.logicalLevelTechnique1;if(C===Es.RLE)return d.runs===1?el.CONST:el.FLAT;let D=a instanceof kp?a.size():a;if(C===Es.DELTA&&d.logicalLevelTechnique2===Es.RLE){let O=d.runs,H=2;if(d.numRleValues!==D)return el.FLAT;if(O===1)return el.SEQUENCE;if(O===2){let Z=A.get(),re;if(d.physicalLevelTechnique===dg.VARINT)re=Uu(h,A,4);else{let ce=A.get();re=new Int32Array(h.buffer,h.byteOffset+ce,4)}if(A.set(Z),re[2]===H&&re[3]===H)return el.SEQUENCE}}return d.numValues===1?el.CONST:el.FLAT}class Z_ extends G_{getValueFromBuffer(a){return this.dataBuffer[a]}}class lI extends cA{constructor(a,h,A,C){super(a,BigInt64Array.of(h),A,C)}getValueFromBuffer(a){return this.dataBuffer[0]+BigInt(a)*this.delta}}class Y_{_geometryOffsets;_partOffsets;_ringOffsets;constructor(a,h,A){this._geometryOffsets=a,this._partOffsets=h,this._ringOffsets=A}get geometryOffsets(){return this._geometryOffsets}get partOffsets(){return this._partOffsets}get ringOffsets(){return this._ringOffsets}}function F2(d,a,h){return{x:cI(d,a)-h,y:cI(d>>1,a)-h}}function cI(d,a){let h=0;for(let A=0;A>A;return h}(function(d){d[d.POINT=0]="POINT",d[d.LINESTRING=1]="LINESTRING",d[d.POLYGON=2]="POLYGON",d[d.MULTIPOINT=3]="MULTIPOINT",d[d.MULTILINESTRING=4]="MULTILINESTRING",d[d.MULTIPOLYGON=5]="MULTIPOLYGON"})(zu||(zu={})),function(d){d[d.POINT=0]="POINT",d[d.LINESTRING=1]="LINESTRING",d[d.POLYGON=2]="POLYGON"}(a0||(a0={})),function(d){d[d.MORTON=0]="MORTON",d[d.VEC_2=1]="VEC_2",d[d.VEC_3=2]="VEC_3"}(td||(td={}));class uI{createPoint(a){return[[a]]}createMultiPoint(a){return a.map(h=>[h])}createLineString(a){return[a]}createMultiLineString(a){return a}createPolygon(a,h){return[a].concat(h)}createMultiPolygon(a){return a.flat()}}function k2(d){let a=new Array(d.numGeometries),h=1,A=1,C=1,D=0,O=new uI,H=0,Z=0,re=d.mortonSettings,ce=d.topologyVector,de=ce.geometryOffsets,we=ce.partOffsets,Ee=ce.ringOffsets,De=d.vertexOffsets,ke=d.containsPolygonGeometry(),qe=d.vertexBuffer;for(let st=0;st0&&ke.push(ke[0]),we.push(ke)}a[ce]=we,D&&re++}break;case zu.MULTIPOLYGON:{let de=D[re]-D[re-1];re++;let we=[];for(let Ee=0;Ee0&&st.push(st[0]),we.push(st)}}a[ce]=we}}return a}[Symbol.iterator](){return null}}function Tv(d,a,h,A,C,D){return new lD(d,a,h,A,C,D)}class lD extends dI{_numGeometries;_geometryType;constructor(a,h,A,C,D,O){super(A,C,D,O),this._numGeometries=a,this._geometryType=h}geometryType(a){return this._geometryType}get numGeometries(){return this._numGeometries}containsSingleGeometryType(){return!0}}function Eb(d,a,h,A,C){return new x8(d,a,h,A,C)}class x8 extends dI{_geometryTypes;constructor(a,h,A,C,D){super(h,A,C,D),this._geometryTypes=a}geometryType(a){return this._geometryTypes[a]}get numGeometries(){return this._geometryTypes.length}containsSingleGeometryType(){return!1}}function cD(d,a,h,A,C){let D=of(d,h),O=null,H=null,Z=null,re=null,ce=null,de=null,we=null,Ee=null;if(c0(D,A,d,h)===el.CONST){let ke=Np(d,h,D,!1);for(let qe=0;qeh?a[D++]:1);return A}function uD(d,a,h,A){let C=new Int32Array(a[a.length-1]+1),D=0;C[0]=D;let O=1,H=0;for(let Z=0;Z=12?T8.decode(d.subarray(a,h)):function(A,C,D){let O="",H=C;for(;H239?4:Z>223?3:Z>191?2:1;if(H+Ee>D)break;Ee===1?Z<128&&(we=Z):Ee===2?(re=A[H+1],(192&re)==128&&(we=(31&Z)<<6|63&re,we<=127&&(we=null))):Ee===3?(re=A[H+1],ce=A[H+2],(192&re)==128&&(192&ce)==128&&(we=(15&Z)<<12|(63&re)<<6|63&ce,(we<=2047||we>=55296&&we<=57343)&&(we=null))):Ee===4&&(re=A[H+1],ce=A[H+2],de=A[H+3],(192&re)==128&&(192&ce)==128&&(192&de)==128&&(we=(15&Z)<<18|(63&re)<<12|(63&ce)<<6|63&de,(we<=65535||we>=1114112)&&(we=null))),we===null?(we=65533,Ee=1):we>65535&&(we-=65536,O+=String.fromCharCode(we>>>10&1023|55296),we=56320|1023&we),O+=String.fromCharCode(we),H+=Ee}return O}(d,a,h)}class Sv extends ym{offsetBuffer;constructor(a,h,A,C){super(a,A,C),this.offsetBuffer=h}}class mI extends Sv{textEncoder;constructor(a,h,A,C){super(a,h,A,C??h.length-1),this.textEncoder=new TextEncoder}getValueFromBuffer(a){return Up(this.dataBuffer,this.offsetBuffer[a],this.offsetBuffer[a+1])}}class mg extends Sv{indexBuffer;textEncoder;constructor(a,h,A,C,D){super(a,A,C,D??h.length),this.indexBuffer=h,this.indexBuffer=h,this.textEncoder=new TextEncoder}getValueFromBuffer(a){let h=this.indexBuffer[a];return Up(this.dataBuffer,this.offsetBuffer[h],this.offsetBuffer[h+1])}}class gI extends Sv{indexBuffer;symbolOffsetBuffer;symbolTableBuffer;textEncoder;symbolLengthBuffer;lengthBuffer;decodedDictionary;constructor(a,h,A,C,D,O,H){super(a,A,C,H),this.indexBuffer=h,this.symbolOffsetBuffer=D,this.symbolTableBuffer=O,this.textEncoder=new TextEncoder}getValueFromBuffer(a){this.decodedDictionary==null&&(this.symbolLengthBuffer==null&&(this.symbolLengthBuffer=this.offsetToLengthBuffer(this.symbolOffsetBuffer),this.lengthBuffer=this.offsetToLengthBuffer(this.offsetBuffer)),this.decodedDictionary=function(A,C,D){let O=[],H=new Array(C.length).fill(0);for(let Z=1;Z>1n^-(1n&rn[0]):0n,pa=1):Vn[0]=0n;let Hs=1;for(;Hs!=Vn.length;++Hs)Vn[Hs]=vn.get(Hs)?Vn[Hs-1]+(rn[pa]>>1n^-(1n&rn[pa++])):Vn[Hs-1];return Vn}(cn,Qr);case Es.RLE:return function(vn,rn,Vn,pa){let Hs=rn;return Vn?function(vc,Ef,Vu){let xc=new BigInt64Array(vc.size()),sc=0;for(let za=0;za>1n^-(1n&lu);for(let ql=sc;ql>1n^-(1n&vc)}else Vn[Hs]=0n;return Vn}(cn,Qr):function(vn,rn){let Vn=new BigInt64Array(vn.size()),pa=0,Hs=0;for(;Hs!=Vn.length;++Hs)Vn[Hs]=vn.get(Hs)?rn[pa++]:0n;return Vn}(cn,Qr),Qr;default:throw new Error("The specified Logical level technique is not supported")}}($_(oi,Kr,gi.numValues),gi,ji,vi)}(ke,qe,_t,Qt,kt):hA(ke,qe,_t,Qt);return new Z_(st.name,Ir,kt)}if(Ht===el.SEQUENCE){let Ir=aI(ke,qe,_t);return new lI(st.name,Ir[0],Ir[1],_t.numRleValues)}{let Ir=X_(ke,qe,_t,Qt);return new hD(st.name,Ir,kt)}}(H,Z,de,De,ce);case 7:return function(ke,qe,st,kt){let pt=of(ke,qe),_t=AI(kt)?function(Ht,Qt,Ir,oi){let Kr=Qt.get(),gi=Kr+oi*Float32Array.BYTES_PER_ELEMENT,ji=new Uint8Array(Ht.subarray(Kr,gi)).buffer,vi=new Float32Array(ji);Qt.set(gi);let Qr=Ir.size(),jr=new Float32Array(Qr),dn=0;for(let cn=0;cn>>0,A=!!(4&h),C=!!(2&h),D=Uu(d,a,1)[0]>>>0,O={};if(1&h&&(O.nullable=!0),C){let H={};if(A?(H.type="logicalType",H.logicalType=D):(H.type="physicalType",H.physicalType=D),8&h){let Z=Uu(d,a,1)[0]>>>0;H.children=new Array(Z);for(let re=0;re>>0,A=function(C){switch(C){case 0:case 1:case 2:case 3:{let D={};D.nullable=!!(1&C),D.columnScope=0;let O={};return O.physicalType=C>1?6:4,O.type="physicalType",D.scalarType=O,D.type="scalarType",D}case 4:{let D={nullable:!1,columnScope:0},O={type:"physicalType",physicalType:0};return D.type="complexType",D.complexType=O,D}case 30:{let D={nullable:!1,columnScope:0},O={type:"physicalType",physicalType:1};return D.type="complexType",D.complexType=O,D}default:return function(D){let O=null;switch(D){case 10:case 11:O=0;break;case 12:case 13:O=1;break;case 14:case 15:O=2;break;case 16:case 17:O=3;break;case 18:case 19:O=4;break;case 20:case 21:O=5;break;case 22:case 23:O=6;break;case 24:case 25:O=7;break;case 26:case 27:O=8;break;case 28:case 29:O=9;break;default:return null}let H={};H.nullable=!!(1&D),H.columnScope=0;let Z={type:"physicalType"};return Z.physicalType=O,H.type="scalarType",H.scalarType=Z,H}(C)}}(h);if(!A)throw new Error(`Unsupported column type code: ${h}`);if(function(C){return C>=10}(h)?A.name=BK(d,a):h>=0&&h<=3?A.name="id":h===4&&(A.name="geometry"),function(C){return C===30}(h)){let C=Uu(d,a,1)[0]>>>0,D=A.complexType;D.children=new Array(C);for(let O=0;O>>0,D=Uu(d,a,1)[0]>>>0;A.columns=new Array(D);for(let O=0;O=4)for(;Ht<_t-4;Ht+=4){let Qt=pt[Ht],Ir=pt[Ht+1],oi=pt[Ht+2],Kr=pt[Ht+3];pt[Ht]=(Qt%2==1?(Qt+1)/-2:Qt/2)+pt[Ht-1],pt[Ht+1]=(Ir%2==1?(Ir+1)/-2:Ir/2)+pt[Ht],pt[Ht+2]=(oi%2==1?(oi+1)/-2:oi/2)+pt[Ht+1],pt[Ht+3]=(Kr%2==1?(Kr+1)/-2:Kr/2)+pt[Ht+2]}for(;Ht!=pt.length;++Ht)pt[Ht]=(pt[Ht]%2==1?(pt[Ht]+1)/-2:pt[Ht]/2)+pt[Ht-1]}(qe),qe;case Es.RLE:return function(pt,_t,Ht){return Ht?function(Qt,Ir,oi){let Kr=new Float64Array(oi),gi=0;for(let ji=0;ji>>0,re=O.get()+Z;if(re>A.length)throw new Error(`Block overruns tile: ${re} > ${A.length}`);if(Uu(A,O,1)[0]>>>0!=1){O.set(re);continue}let ce=J2e(A,O),de=ce[1],we=ce[0].featureTables[0],Ee=null,De=null,ke=[],qe=0;for(let kt of we.columns){let pt=kt.name;if(pt==="id"){let _t=null;if(kt.nullable){let Qt=of(A,O),Ir=O.get(),oi=Cb(A,Qt.numValues,O);O.set(Ir+Qt.byteLength),_t=new kp(oi,Qt.numValues)}let Ht=of(A,O);qe=Ht.decompressedCount,Ee=eTe(A,kt,O,pt,Ht,_t??qe,D)}else if(pt==="geometry"){let _t=Uu(A,O,1)[0];if(qe===0){let Ht=O.get();qe=of(A,O).decompressedCount,O.set(Ht)}De=cD(A,_t,O,qe)}else{let _t=Y2e(kt)?Uu(A,O,1)[0]:1;if(_t===0&&kt.type==="scalarType")continue;let Ht=Z2e(A,O,kt,_t,qe);if(Ht)if(Array.isArray(Ht))for(let Qt of Ht)ke.push(Qt);else ke.push(Ht)}}let st=new nI(we.name,De,Ee,ke,de);H.push(st),O.set(re)}return H}(new Uint8Array(a));this.layers=h.reduce((A,C)=>Object.assign(Object.assign({},A),{[C.name]:new rTe(C)}),{})}}class Ib{constructor(){this.minX=1/0,this.maxX=-1/0,this.minY=1/0,this.maxY=-1/0}extend(a){return this.minX=Math.min(this.minX,a.x),this.minY=Math.min(this.minY,a.y),this.maxX=Math.max(this.maxX,a.x),this.maxY=Math.max(this.maxY,a.y),this}expandBy(a){return this.minX-=a,this.minY-=a,this.maxX+=a,this.maxY+=a,(this.minX>this.maxX||this.minY>this.maxY)&&(this.minX=1/0,this.maxX=-1/0,this.minY=1/0,this.maxY=-1/0),this}shrinkBy(a){return this.expandBy(-a)}map(a){let h=new Ib;return h.extend(a(new s(this.minX,this.minY))),h.extend(a(new s(this.maxX,this.minY))),h.extend(a(new s(this.minX,this.maxY))),h.extend(a(new s(this.maxX,this.maxY))),h}static fromPoints(a){let h=new Ib;for(let A of a)h.extend(A);return h}contains(a){return a.x>=this.minX&&a.x<=this.maxX&&a.y>=this.minY&&a.y<=this.maxY}empty(){return this.minX>this.maxX}width(){return this.maxX-this.minX}height(){return this.maxY-this.minY}covers(a){return!this.empty()&&!a.empty()&&a.minX>=this.minX&&a.maxX<=this.maxX&&a.minY>=this.minY&&a.maxY<=this.maxY}intersects(a){return!this.empty()&&!a.empty()&&a.minX<=this.maxX&&a.maxX>=this.minX&&a.minY<=this.maxY&&a.maxY>=this.minY}}class iTe{constructor(a,h){this.feature=a,this.type=a.type,this.properties=a.tags?a.tags:{},this.extent=h,"id"in a&&(typeof a.id=="string"?this.id=parseInt(a.id,10):typeof a.id!="number"||isNaN(a.id)||(this.id=a.id))}loadGeometry(){let a=[],h=this.feature.type===1?[this.feature.geometry]:this.feature.geometry;for(let A of h){let C=[];for(let D of A)C.push(new s(D[0],D[1]));a.push(C)}return a}}let _I="_geojsonTileLayer";function nTe(d,a){a.writeVarintField(15,d.version||1),a.writeStringField(1,d.name||""),a.writeVarintField(5,d.extent||4096);let h={keys:[],values:[],keycache:{},valuecache:{}};for(let D=0;D>31}function aTe(d,a){let h=d.loadGeometry(),A=d.type,C=0,D=0;for(let O of h){let H=1;A===1&&(H=O.length),a.writeVarint(S8(1,H));let Z=A===3?O.length-1:O.length;for(let re=0;re=0&&de[3]>=0&&Z.insert(H,de[0],de[1],de[2],de[3])}}loadVTLayers(){return this.vtLayers||(this.vtLayers=this.encoding!=="mlt"?new ub(new tr(this.rawTileData)).layers:new DK(this.rawTileData).layers,this.sourceLayerCoder=new xv(this.vtLayers?Object.keys(this.vtLayers).sort():[_I])),this.vtLayers}query(a,h,A,C){this.loadVTLayers();let D=a.params,O=hr/a.tileSize/a.scale,H=Pc(D.filter,D.globalState),Z=a.queryGeometry,re=a.queryPadding*O,ce=Ib.fromPoints(Z),de=this.grid.query(ce.minX-re,ce.minY-re,ce.maxX+re,ce.maxY+re),we=Ib.fromPoints(a.cameraQueryGeometry).expandBy(re),Ee=this.grid3D.query(we.minX,we.minY,we.maxX,we.maxY,(qe,st,kt,pt)=>function(_t,Ht,Qt,Ir,oi){for(let gi of _t)if(Ht<=gi.x&&Qt<=gi.y&&Ir>=gi.x&&oi>=gi.y)return!0;let Kr=[new s(Ht,Qt),new s(Ht,oi),new s(Ir,oi),new s(Ir,Qt)];if(_t.length>2){for(let gi of Kr)if(Bo(_t,gi))return!0}for(let gi=0;gi<_t.length-1;gi++)if(ib(_t[gi],_t[gi+1],Kr))return!0;return!1}(a.cameraQueryGeometry,qe-re,st-re,kt+re,pt+re));for(let qe of Ee)de.push(qe);de.sort(cTe);let De={},ke;for(let qe=0;qe(pt||(pt=or(_t)),Ht.queryIntersectsFeature({queryGeometry:Z,feature:_t,featureState:Qt,geometry:pt,zoom:this.z,transform:a.transform,pixelsToTileUnits:O,pixelPosMatrix:a.pixelPosMatrix,unwrappedTileID:this.tileID.toUnwrapped(),getElevation:a.getElevation})))}return De}loadMatchingFeature(a,h,A,C,D,O,H,Z,re,ce,de){let we=this.bucketLayerIDs[h];if(O&&!we.some(qe=>O.has(qe)))return;let Ee=this.sourceLayerCoder.decode(A),De=this.vtLayers[Ee].feature(C);if(D.needGeometry){let qe=Pi(De,!0);if(!D.filter(new Gi(this.tileID.overscaledZ),qe,this.tileID.canonical))return}else if(!D.filter(new Gi(this.tileID.overscaledZ),De))return;let ke=this.getId(De,Ee);for(let qe=0;qe{let H=a instanceof Ta?a.get(O):null;return H&&H.evaluate?H.evaluate(h,A,C):H})}function cTe(d,a){return a-d}function NK(d,a,h,A,C){let D=[];for(let O=0;O=A&&de.x>=A||(ce.x>=A?ce=new s(A,ce.y+(A-ce.x)/(de.x-ce.x)*(de.y-ce.y))._round():de.x>=A&&(de=new s(A,ce.y+(A-ce.x)/(de.x-ce.x)*(de.y-ce.y))._round()),ce.y>=C&&de.y>=C||(ce.y>=C?ce=new s(ce.x+(C-ce.y)/(de.y-ce.y)*(de.x-ce.x),C)._round():de.y>=C&&(de=new s(ce.x+(C-ce.y)/(de.y-ce.y)*(de.x-ce.x),C)._round()),Z&&ce.equals(Z[Z.length-1])||(Z=[ce],D.push(Z)),Z.push(de)))))}}return D}function zK(d,a,h,A,C){switch(a){case 1:return function(D,O,H,Z){let re=[];for(let ce of D)for(let de of ce){let we=Z===0?de.x:de.y;we>=O&&we<=H&&re.push([de])}return re}(d,h,A,C);case 2:return UK(d,h,A,C,!1);case 3:return UK(d,h,A,C,!0)}return[]}function uTe(d,a,h,A,C){let D=A===0?hTe:fTe,O=[],H=[];for(let ce=0;cea&&O.push(D(de,we,a)):Ee>h?De=a&&(O.push(D(de,we,a)),ke=!0),De>h&&Ee<=h&&(O.push(D(de,we,h)),ke=!0),!C&&ke&&(H.push(O),O=[])}let Z=d.length-1,re=A===0?d[Z].x:d[Z].y;return re>=a&&re<=h&&O.push(d[Z]),C&&O.length>0&&!O[0].equals(O[O.length-1])&&O.push(new s(O[0].x,O[0].y)),O.length>0&&H.push(O),H}function UK(d,a,h,A,C){let D=[];for(let O of d){let H=uTe(O,a,h,A,C);H.length>0&&D.push(...H)}return D}function hTe(d,a,h){return new s(h,d.y+(h-d.x)/(a.x-d.x)*(a.y-d.y))}function fTe(d,a,h){return new s(d.x+(h-d.y)/(a.y-d.y)*(a.x-d.x),h)}ut("FeatureIndex",FK,{omit:["rawTileData","sourceLayerCoder"]});class Ev extends s{constructor(a,h,A,C){super(a,h),this.angle=A,C!==void 0&&(this.segment=C)}clone(){return new Ev(this.x,this.y,this.angle,this.segment)}}function VK(d,a,h,A,C){if(a.segment===void 0||h===0)return!0;let D=a,O=a.segment+1,H=0;for(;H>-h/2;){if(O--,O<0)return!1;H-=d[O].dist(D),D=d[O]}H+=d[O].dist(d[O+1]),O++;let Z=[],re=0;for(;HA;)re-=Z.shift().angleDelta;if(re>C)return!1;O++,H+=ce.dist(de)}return!0}function jK(d){let a=0;for(let h=0;hre){let De=(re-Z)/Ee,ke=Fr.number(de.x,we.x,De),qe=Fr.number(de.y,we.y,De),st=new Ev(ke,qe,we.angleTo(de),ce);return st._round(),!O||VK(d,st,H,O,a)?st:void 0}Z+=Ee}}function pTe(d,a,h,A,C,D,O,H,Z){let re=HK(A,D,O),ce=GK(A,C),de=ce*O,we=d[0].x===0||d[0].x===Z||d[0].y===0||d[0].y===Z;return a-de=0&&_t=0&&Ht=0&&we+re<=ce){let Qt=new Ev(_t,Ht,kt,De);Qt._round(),A&&!VK(d,Qt,D,A,C)||Ee.push(Qt)}}de+=st}return H||Ee.length||O||(Ee=WK(d,de/2,h,A,C,D,O,!0,Z)),Ee}function qK(d,a,h,A){let C=[],D=d.image,O=D.pixelRatio,H=D.paddedRect.w-2,Z=D.paddedRect.h-2,re={x1:d.left,y1:d.top,x2:d.right,y2:d.bottom},ce=D.stretchX||[[0,H]],de=D.stretchY||[[0,Z]],we=(jr,dn)=>jr+dn[1]-dn[0],Ee=ce.reduce(we,0),De=de.reduce(we,0),ke=H-Ee,qe=Z-De,st=0,kt=Ee,pt=0,_t=De,Ht=0,Qt=ke,Ir=0,oi=qe;if(D.content&&A){let jr=D.content,dn=jr[2]-jr[0],cn=jr[3]-jr[1];(D.textFitWidth||D.textFitHeight)&&(re=ih(d)),st=dD(ce,0,jr[0]),pt=dD(de,0,jr[1]),kt=dD(ce,jr[0],jr[2]),_t=dD(de,jr[1],jr[3]),Ht=jr[0]-st,Ir=jr[1]-pt,Qt=dn-kt,oi=cn-_t}let Kr=re.x1,gi=re.y1,ji=re.x2-Kr,vi=re.y2-gi,Qr=(jr,dn,cn,vn)=>{let rn=pD(jr.stretch-st,kt,ji,Kr),Vn=mD(jr.fixed-Ht,Qt,jr.stretch,Ee),pa=pD(dn.stretch-pt,_t,vi,gi),Hs=mD(dn.fixed-Ir,oi,dn.stretch,De),vc=pD(cn.stretch-st,kt,ji,Kr),Ef=mD(cn.fixed-Ht,Qt,cn.stretch,Ee),Vu=pD(vn.stretch-pt,_t,vi,gi),xc=mD(vn.fixed-Ir,oi,vn.stretch,De),sc=new s(rn,pa),za=new s(vc,pa),$c=new s(vc,Vu),lu=new s(rn,Vu),ql=new s(Vn/O,Hs/O),ep=new s(Ef/O,xc/O),Cf=a*Math.PI/180;if(Cf){let Th=Math.sin(Cf),Bc=Math.cos(Cf),ju=[Bc,-Th,Th,Bc];sc._matMult(ju),za._matMult(ju),lu._matMult(ju),$c._matMult(ju)}let tp=jr.stretch+jr.fixed,gg=dn.stretch+dn.fixed;return{tl:sc,tr:za,bl:lu,br:$c,tex:{x:D.paddedRect.x+1+tp,y:D.paddedRect.y+1+gg,w:cn.stretch+cn.fixed-tp,h:vn.stretch+vn.fixed-gg},writingMode:void 0,glyphOffset:[0,0],sectionIndex:0,pixelOffsetTL:ql,pixelOffsetBR:ep,minFontScaleX:Qt/O/ji,minFontScaleY:oi/O/vi,isSDF:h}};if(A&&(D.stretchX||D.stretchY)){let jr=$K(ce,ke,Ee),dn=$K(de,qe,De);for(let cn=0;cn0&&(ke=Math.max(10,ke),this.circleDiameter=ke)}else{let we=!((de=O.image)===null||de===void 0)&&de.content&&(O.image.textFitWidth||O.image.textFitHeight)?ih(O):{x1:O.left,y1:O.top,x2:O.right,y2:O.bottom};we.y1=we.y1*H-Z[0],we.y2=we.y2*H+Z[2],we.x1=we.x1*H-Z[3],we.x2=we.x2*H+Z[1];let Ee=O.collisionPadding;if(Ee&&(we.x1-=Ee[0]*H,we.y1-=Ee[1]*H,we.x2+=Ee[2]*H,we.y2+=Ee[3]*H),ce){let De=new s(we.x1,we.y1),ke=new s(we.x2,we.y1),qe=new s(we.x1,we.y2),st=new s(we.x2,we.y2),kt=ce*Math.PI/180;De._rotate(kt),ke._rotate(kt),qe._rotate(kt),st._rotate(kt),we.x1=Math.min(De.x,ke.x,qe.x,st.x),we.x2=Math.max(De.x,ke.x,qe.x,st.x),we.y1=Math.min(De.y,ke.y,qe.y,st.y),we.y2=Math.max(De.y,ke.y,qe.y,st.y)}a.emplaceBack(h.x,h.y,we.x1,we.y1,we.x2,we.y2,A,C,D)}this.boxEndIndex=a.length}}class mTe{constructor(a=[],h=(A,C)=>AC?1:0){if(this.data=a,this.length=this.data.length,this.compare=h,this.length>0)for(let A=(this.length>>1)-1;A>=0;A--)this._down(A)}push(a){this.data.push(a),this._up(this.length++)}pop(){if(this.length===0)return;let a=this.data[0],h=this.data.pop();return--this.length>0&&(this.data[0]=h,this._down(0)),a}peek(){return this.data[0]}_up(a){let{data:h,compare:A}=this,C=h[a];for(;a>0;){let D=a-1>>1,O=h[D];if(A(C,O)>=0)break;h[a]=O,a=D}h[a]=C}_down(a){let{data:h,compare:A}=this,C=this.length>>1,D=h[a];for(;a=0)break;h[a]=h[O],a=O}h[a]=D}}function gTe(d,a=1,h=!1){let A=Ib.fromPoints(d[0]),C=Math.min(A.width(),A.height()),D=C/2,O=new mTe([],ATe),{minX:H,minY:Z,maxX:re,maxY:ce}=A;if(C===0)return new s(H,Z);for(let Ee=H;Eede.d||!de.d)&&(de=Ee,h&&console.log("found best %d after %d probes",Math.round(1e4*Ee.d)/1e4,we)),Ee.max-de.d<=a||(D=Ee.h/2,O.push(new U2(Ee.p.x-D,Ee.p.y-D,D,d)),O.push(new U2(Ee.p.x+D,Ee.p.y-D,D,d)),O.push(new U2(Ee.p.x-D,Ee.p.y+D,D,d)),O.push(new U2(Ee.p.x+D,Ee.p.y+D,D,d)),we+=4)}return h&&(console.log(`num probes: ${we}`),console.log(`best distance: ${de.d}`)),de.p}function ATe(d,a){return a.max-d.max}function U2(d,a,h,A){this.p=new s(d,a),this.h=h,this.d=function(C,D){let O=!1,H=1/0;for(let Z=0;ZC.y!=De.y>C.y&&C.x<(De.x-Ee.x)*(C.y-Ee.y)/(De.y-Ee.y)+Ee.x&&(O=!O),H=Math.min(H,Qo(C,Ee,De))}}return(O?1:-1)*Math.sqrt(H)}(this.p,A),this.max=this.d+this.h*Math.SQRT2}var Sf;n.aQ=void 0,(Sf=n.aQ||(n.aQ={}))[Sf.center=1]="center",Sf[Sf.left=2]="left",Sf[Sf.right=3]="right",Sf[Sf.top=4]="top",Sf[Sf.bottom=5]="bottom",Sf[Sf["top-left"]=6]="top-left",Sf[Sf["top-right"]=7]="top-right",Sf[Sf["bottom-left"]=8]="bottom-left",Sf[Sf["bottom-right"]=9]="bottom-right";let E8=Number.POSITIVE_INFINITY;function XK(d,a){return a[1]!==E8?function(h,A,C){let D=0,O=0;switch(A=Math.abs(A),C=Math.abs(C),h){case"top-right":case"top-left":case"top":O=C-7;break;case"bottom-right":case"bottom-left":case"bottom":O=7-C}switch(h){case"top-right":case"bottom-right":case"right":D=-A;break;case"top-left":case"bottom-left":case"left":D=A}return[D,O]}(d,a[0],a[1]):function(h,A){let C=0,D=0;A<0&&(A=0);let O=A/Math.SQRT2;switch(h){case"top-right":case"top-left":D=O-7;break;case"bottom-right":case"bottom-left":D=7-O;break;case"bottom":D=7-A;break;case"top":D=A-7}switch(h){case"top-right":case"bottom-right":C=-O;break;case"top-left":case"bottom-left":C=O;break;case"left":C=A;break;case"right":C=-A}return[C,D]}(d,a[0])}function ZK(d,a,h){var A;let C=d.layout,D=(A=C.get("text-variable-anchor-offset"))===null||A===void 0?void 0:A.evaluate(a,{},h);if(D){let H=D.values,Z=[];for(let re=0;rewe*R);ce.startsWith("top")?de[1]-=7:ce.startsWith("bottom")&&(de[1]+=7),Z[re+1]=de}return new sl(Z)}let O=C.get("text-variable-anchor");if(O){let H;H=d._unevaluatedLayout.getValue("text-radial-offset")!==void 0?[C.get("text-radial-offset").evaluate(a,{},h)*R,E8]:C.get("text-offset").evaluate(a,{},h).map(re=>re*R);let Z=[];for(let re of O)Z.push(re,XK(re,H));return new sl(Z)}return null}function C8(d){switch(d){case"right":case"top-right":case"bottom-right":return"right";case"left":case"top-left":case"bottom-left":return"left"}return"center"}function _Te(d,a,h,A,C,D,O,H,Z,re,ce,de){let we=D.textMaxSize.evaluate(a,{});we===void 0&&(we=O);let Ee=d.layers[0].layout,De=Ee.get("icon-offset").evaluate(a,{},ce),ke=KK(h.horizontal),qe=O/24,st=d.tilePixelRatio*qe,kt=d.tilePixelRatio*we/24,pt=d.tilePixelRatio*H,_t=d.tilePixelRatio*Ee.get("symbol-spacing"),Ht=Ee.get("text-padding")*d.tilePixelRatio,Qt=function(cn,vn,rn,Vn=1){let pa=cn.get("icon-padding").evaluate(vn,{},rn),Hs=pa&&pa.values;return[Hs[0]*Vn,Hs[1]*Vn,Hs[2]*Vn,Hs[3]*Vn]}(Ee,a,ce,d.tilePixelRatio),Ir=Ee.get("text-max-angle")/180*Math.PI,oi=Ee.get("text-rotation-alignment")!=="viewport"&&Ee.get("symbol-placement")!=="point",Kr=Ee.get("icon-rotation-alignment")==="map"&&Ee.get("symbol-placement")!=="point",gi=Ee.get("symbol-placement"),ji=_t/2,vi=Ee.get("icon-text-fit"),Qr;A&&vi!=="none"&&(d.allowVerticalPlacement&&h.vertical&&(Qr=su(A,h.vertical,vi,Ee.get("icon-text-fit-padding"),De,qe)),ke&&(A=su(A,ke,vi,Ee.get("icon-text-fit-padding"),De,qe)));let jr=ce?de.line.getGranularityForZoomLevel(ce.z):1,dn=(cn,vn)=>{vn.x<0||vn.x>=hr||vn.y<0||vn.y>=hr||function(rn,Vn,pa,Hs,vc,Ef,Vu,xc,sc,za,$c,lu,ql,ep,Cf,tp,gg,Th,Bc,ju,Xc,Sh,K_,u0,xI){let Cv=rn.addToLineVertexArray(Vn,pa),Mb,V2,j2,H2,tQ=0,rQ=0,iQ=0,nQ=0,O8=-1,F8=-1,Q_={},oQ=qs("");if(rn.allowVerticalPlacement&&Hs.vertical){let rd=xc.layout.get("text-rotate").evaluate(Xc,{},u0)+90;j2=new gD(sc,Vn,za,$c,lu,Hs.vertical,ql,ep,Cf,rd),Vu&&(H2=new gD(sc,Vn,za,$c,lu,Vu,gg,Th,Cf,rd))}if(vc){let rd=xc.layout.get("icon-rotate").evaluate(Xc,{}),Tm=xc.layout.get("icon-text-fit")!=="none",Pb=qK(vc,rd,K_,Tm),f0=Vu?qK(Vu,rd,K_,Tm):void 0;V2=new gD(sc,Vn,za,$c,lu,vc,gg,Th,!1,rd),tQ=4*Pb.length;let Rb=rn.iconSizeData,dA=null;Rb.kind==="source"?(dA=[nc*xc.layout.get("icon-size").evaluate(Xc,{})],dA[0]>ka&&ln(`${rn.layerIds[0]}: Value for "icon-size" is >= 255. Reduce your "icon-size".`)):Rb.kind==="composite"&&(dA=[nc*Sh.compositeIconSizes[0].evaluate(Xc,{},u0),nc*Sh.compositeIconSizes[1].evaluate(Xc,{},u0)],(dA[0]>ka||dA[1]>ka)&&ln(`${rn.layerIds[0]}: Value for "icon-size" is >= 255. Reduce your "icon-size".`)),rn.addSymbols(rn.icon,Pb,dA,ju,Bc,Xc,n.aA.none,Vn,Cv.lineStartIndex,Cv.lineLength,-1,u0),O8=rn.icon.placedSymbolArray.length-1,f0&&(rQ=4*f0.length,rn.addSymbols(rn.icon,f0,dA,ju,Bc,Xc,n.aA.vertical,Vn,Cv.lineStartIndex,Cv.lineLength,-1,u0),F8=rn.icon.placedSymbolArray.length-1)}let sQ=Object.keys(Hs.horizontal);for(let rd of sQ){let Tm=Hs.horizontal[rd];if(!Mb){oQ=qs(Tm.text);let f0=xc.layout.get("text-rotate").evaluate(Xc,{},u0);Mb=new gD(sc,Vn,za,$c,lu,Tm,ql,ep,Cf,f0)}let Pb=Tm.positionedLines.length===1;if(iQ+=YK(rn,Vn,Tm,Ef,xc,Cf,Xc,tp,Cv,Hs.vertical?n.aA.horizontal:n.aA.horizontalOnly,Pb?sQ:[rd],Q_,O8,Sh,u0),Pb)break}Hs.vertical&&(nQ+=YK(rn,Vn,Hs.vertical,Ef,xc,Cf,Xc,tp,Cv,n.aA.vertical,["vertical"],Q_,F8,Sh,u0));let xTe=Mb?Mb.boxStartIndex:rn.collisionBoxArray.length,bTe=Mb?Mb.boxEndIndex:rn.collisionBoxArray.length,wTe=j2?j2.boxStartIndex:rn.collisionBoxArray.length,TTe=j2?j2.boxEndIndex:rn.collisionBoxArray.length,STe=V2?V2.boxStartIndex:rn.collisionBoxArray.length,ETe=V2?V2.boxEndIndex:rn.collisionBoxArray.length,CTe=H2?H2.boxStartIndex:rn.collisionBoxArray.length,ITe=H2?H2.boxEndIndex:rn.collisionBoxArray.length,h0=-1,_D=(rd,Tm)=>rd&&rd.circleDiameter?Math.max(rd.circleDiameter,Tm):Tm;h0=_D(Mb,h0),h0=_D(j2,h0),h0=_D(V2,h0),h0=_D(H2,h0);let aQ=h0>-1?1:0;aQ&&(h0*=xI/R),rn.glyphOffsetArray.length>=dl.MAX_GLYPHS&&ln("Too many glyphs being rendered in a tile. See https://github.com/mapbox/mapbox-gl-js/issues/2907"),Xc.sortKey!==void 0&&rn.addToSortKeyRanges(rn.symbolInstances.length,Xc.sortKey);let MTe=ZK(xc,Xc,u0),[PTe,RTe]=function(rd,Tm){let Pb=rd.length,f0=Tm?.values;if(f0?.length>0)for(let Rb=0;Rb=0?Q_.right:-1,Q_.center>=0?Q_.center:-1,Q_.left>=0?Q_.left:-1,Q_.vertical||-1,O8,F8,oQ,xTe,bTe,wTe,TTe,STe,ETe,CTe,ITe,za,iQ,nQ,tQ,rQ,aQ,0,ql,h0,PTe,RTe)}(d,vn,cn,h,A,C,Qr,d.layers[0],d.collisionBoxArray,a.index,a.sourceLayerIndex,d.index,st,[Ht,Ht,Ht,Ht],oi,Z,pt,Qt,Kr,De,a,D,re,ce,O)};if(gi==="line")for(let cn of NK(a.geometry,0,0,hr,hr)){let vn=D_(cn,jr),rn=pTe(vn,_t,Ir,h.vertical||ke,A,24,kt,d.overscaling,hr);for(let Vn of rn)ke&&yTe(d,ke.text,ji,Vn)||dn(vn,Vn)}else if(gi==="line-center"){for(let cn of a.geometry)if(cn.length>1){let vn=D_(cn,jr),rn=dTe(vn,Ir,h.vertical||ke,A,24,kt);rn&&dn(vn,rn)}}else if(a.type==="Polygon")for(let cn of dt(a.geometry,0)){let vn=gTe(cn,16);dn(D_(cn[0],jr,!0),new Ev(vn.x,vn.y,0))}else if(a.type==="LineString")for(let cn of a.geometry){let vn=D_(cn,jr);dn(vn,new Ev(vn[0].x,vn[0].y,0))}else if(a.type==="Point")for(let cn of a.geometry)for(let vn of cn)dn([vn],new Ev(vn.x,vn.y,0))}function YK(d,a,h,A,C,D,O,H,Z,re,ce,de,we,Ee,De){let ke=function(kt,pt,_t,Ht,Qt,Ir,oi,Kr){let gi=Ht.layout.get("text-rotate").evaluate(Ir,{})*Math.PI/180,ji=[];for(let vi of pt.positionedLines)for(let Qr of vi.positionedGlyphs){if(!Qr.rect)continue;let jr=Qr.rect||{},dn=4,cn=!0,vn=1,rn=0,Vn=(Qt||Kr)&&Qr.vertical,pa=Qr.metrics.advance*Qr.scale/2;if(Kr&&pt.verticalizable&&(rn=vi.lineOffset/2-(Qr.imageName?-(R-Qr.metrics.width*Qr.scale)/2:(Qr.scale-1)*R)),Qr.imageName){let Th=oi[Qr.imageName];cn=Th.sdf,vn=Th.pixelRatio,dn=1/vn}let Hs=Qt?[Qr.x+pa,Qr.y]:[0,0],vc=Qt?[0,0]:[Qr.x+pa+_t[0],Qr.y+_t[1]-rn],Ef=[0,0];Vn&&(Ef=vc,vc=[0,0]);let Vu=Qr.metrics.isDoubleResolution?2:1,xc=(Qr.metrics.left-dn)*Qr.scale-pa+vc[0],sc=(-Qr.metrics.top-dn)*Qr.scale+vc[1],za=xc+jr.w/Vu*Qr.scale/vn,$c=sc+jr.h/Vu*Qr.scale/vn,lu=new s(xc,sc),ql=new s(za,sc),ep=new s(xc,$c),Cf=new s(za,$c);if(Vn){let Th=new s(-pa,pa- -17),Bc=-Math.PI/2,ju=12-pa,Xc=new s(22-ju,-(Qr.imageName?ju:0)),Sh=new s(...Ef);lu._rotateAround(Bc,Th)._add(Xc)._add(Sh),ql._rotateAround(Bc,Th)._add(Xc)._add(Sh),ep._rotateAround(Bc,Th)._add(Xc)._add(Sh),Cf._rotateAround(Bc,Th)._add(Xc)._add(Sh)}if(gi){let Th=Math.sin(gi),Bc=Math.cos(gi),ju=[Bc,-Th,Th,Bc];lu._matMult(ju),ql._matMult(ju),ep._matMult(ju),Cf._matMult(ju)}let tp=new s(0,0),gg=new s(0,0);ji.push({tl:lu,tr:ql,bl:ep,br:Cf,tex:jr,writingMode:pt.writingMode,glyphOffset:Hs,sectionIndex:Qr.sectionIndex,isSDF:cn,pixelOffsetTL:tp,pixelOffsetBR:gg,minFontScaleX:0,minFontScaleY:0})}return ji}(0,h,H,C,D,O,A,d.allowVerticalPlacement),qe=d.textSizeData,st=null;qe.kind==="source"?(st=[nc*C.layout.get("text-size").evaluate(O,{})],st[0]>ka&&ln(`${d.layerIds[0]}: Value for "text-size" is >= 255. Reduce your "text-size".`)):qe.kind==="composite"&&(st=[nc*Ee.compositeTextSizes[0].evaluate(O,{},De),nc*Ee.compositeTextSizes[1].evaluate(O,{},De)],(st[0]>ka||st[1]>ka)&&ln(`${d.layerIds[0]}: Value for "text-size" is >= 255. Reduce your "text-size".`)),d.addSymbols(d.text,ke,st,H,D,O,re,a,Z.lineStartIndex,Z.lineLength,we,De);for(let kt of ce)de[kt]=d.text.placedSymbolArray.length-1;return 4*ke.length}function KK(d){for(let a in d)return d[a];return null}function yTe(d,a,h,A){let C=d.compareText;if(a in C){let D=C[a];for(let O=D.length-1;O>=0;O--)if(A.dist(D[O])>4;if(C!==1)throw new Error(`Got v${C} data when expected v1.`);let D=QK[15&A];if(!D)throw new Error("Unrecognized array type.");let[O]=new Uint16Array(a,2,1),[H]=new Uint32Array(a,4,1);return new I8(H,O,D,a)}constructor(a,h=64,A=Float64Array,C){if(isNaN(a)||a<0)throw new Error(`Unpexpected numItems value: ${a}.`);this.numItems=+a,this.nodeSize=Math.min(Math.max(+h,2),65535),this.ArrayType=A,this.IndexArrayType=a<65536?Uint16Array:Uint32Array;let D=QK.indexOf(this.ArrayType),O=2*a*this.ArrayType.BYTES_PER_ELEMENT,H=a*this.IndexArrayType.BYTES_PER_ELEMENT,Z=(8-H%8)%8;if(D<0)throw new Error(`Unexpected typed array class: ${A}.`);C&&C instanceof ArrayBuffer?(this.data=C,this.ids=new this.IndexArrayType(this.data,8,a),this.coords=new this.ArrayType(this.data,8+H+Z,2*a),this._pos=2*a,this._finished=!0):(this.data=new ArrayBuffer(8+O+H+Z),this.ids=new this.IndexArrayType(this.data,8,a),this.coords=new this.ArrayType(this.data,8+H+Z,2*a),this._pos=0,this._finished=!1,new Uint8Array(this.data,0,2).set([219,16+D]),new Uint16Array(this.data,2,1)[0]=h,new Uint32Array(this.data,4,1)[0]=a)}add(a,h){let A=this._pos>>1;return this.ids[A]=A,this.coords[this._pos++]=a,this.coords[this._pos++]=h,A}finish(){let a=this._pos>>1;if(a!==this.numItems)throw new Error(`Added ${a} items when expected ${this.numItems}.`);return M8(this.ids,this.coords,this.nodeSize,0,this.numItems-1,0),this._finished=!0,this}range(a,h,A,C){if(!this._finished)throw new Error("Data not yet indexed - call index.finish().");let{ids:D,coords:O,nodeSize:H}=this,Z=[0,D.length-1,0],re=[];for(;Z.length;){let ce=Z.pop()||0,de=Z.pop()||0,we=Z.pop()||0;if(de-we<=H){for(let qe=we;qe<=de;qe++){let st=O[2*qe],kt=O[2*qe+1];st>=a&&st<=A&&kt>=h&&kt<=C&&re.push(D[qe])}continue}let Ee=we+de>>1,De=O[2*Ee],ke=O[2*Ee+1];De>=a&&De<=A&&ke>=h&&ke<=C&&re.push(D[Ee]),(ce===0?a<=De:h<=ke)&&(Z.push(we),Z.push(Ee-1),Z.push(1-ce)),(ce===0?A>=De:C>=ke)&&(Z.push(Ee+1),Z.push(de),Z.push(1-ce))}return re}within(a,h,A){if(!this._finished)throw new Error("Data not yet indexed - call index.finish().");let{ids:C,coords:D,nodeSize:O}=this,H=[0,C.length-1,0],Z=[],re=A*A;for(;H.length;){let ce=H.pop()||0,de=H.pop()||0,we=H.pop()||0;if(de-we<=O){for(let qe=we;qe<=de;qe++)eQ(D[2*qe],D[2*qe+1],a,h)<=re&&Z.push(C[qe]);continue}let Ee=we+de>>1,De=D[2*Ee],ke=D[2*Ee+1];eQ(De,ke,a,h)<=re&&Z.push(C[Ee]),(ce===0?a-A<=De:h-A<=ke)&&(H.push(we),H.push(Ee-1),H.push(1-ce)),(ce===0?a+A>=De:h+A>=ke)&&(H.push(Ee+1),H.push(de),H.push(1-ce))}return Z}}function M8(d,a,h,A,C,D){if(C-A<=h)return;let O=A+C>>1;JK(d,a,O,A,C,D),M8(d,a,h,A,O-1,1-D),M8(d,a,h,O+1,C,1-D)}function JK(d,a,h,A,C,D){for(;C>A;){if(C-A>600){let re=C-A+1,ce=h-A+1,de=Math.log(re),we=.5*Math.exp(2*de/3),Ee=.5*Math.sqrt(de*we*(re-we)/re)*(ce-re/2<0?-1:1);JK(d,a,h,Math.max(A,Math.floor(h-ce*we/re+Ee)),Math.min(C,Math.floor(h+(re-ce)*we/re+Ee)),D)}let O=a[2*h+D],H=A,Z=C;for(yI(d,a,A,h),a[2*C+D]>O&&yI(d,a,A,C);HO;)Z--}a[2*A+D]===O?yI(d,a,A,Z):(Z++,yI(d,a,Z,C)),Z<=h&&(A=Z+1),h<=Z&&(C=Z-1)}}function yI(d,a,h,A){P8(d,h,A),P8(a,2*h,2*A),P8(a,2*h+1,2*A+1)}function P8(d,a,h){let A=d[a];d[a]=d[h],d[h]=A}function eQ(d,a,h,A){let C=d-h,D=a-A;return C*C+D*D}var R8;n.cI=void 0,(R8=n.cI||(n.cI={})).create="create",R8.load="load",R8.fullLoad="fullLoad";let AD=null,vI=[],B8=1e3/60,L8="loadTime",D8="fullLoadTime",vTe={mark(d){performance.mark(d)},frame(d){let a=d;AD!=null&&vI.push(a-AD),AD=a},clearMetrics(){AD=null,vI=[],performance.clearMeasures(L8),performance.clearMeasures(D8);for(let d in n.cI)performance.clearMarks(n.cI[d])},getPerformanceMetrics(){performance.measure(L8,n.cI.create,n.cI.load),performance.measure(D8,n.cI.create,n.cI.fullLoad);let d=performance.getEntriesByName(L8)[0].duration,a=performance.getEntriesByName(D8)[0].duration,h=vI.length,A=1/(vI.reduce((D,O)=>D+O,0)/h/1e3),C=vI.filter(D=>D>B8).reduce((D,O)=>D+(O-B8)/B8,0);return{loadTime:d,fullLoadTime:a,fps:A,percentDroppedFrames:C/(h+C)*100,totalFrames:h}}};n.$=U,n.A=he,n.B=ct,n.C=ie,n.D=tn,n.E=go,n.F=function([d,a,h]){return a+=90,a*=Math.PI/180,h*=Math.PI/180,{x:d*Math.cos(a)*Math.sin(h),y:d*Math.sin(a)*Math.sin(h),z:d*Math.cos(h)}},n.G=Fr,n.H=Gi,n.I=Jo,n.J=ge,n.K=function(d){if(Ho==null){let a=d.navigator?d.navigator.userAgent:null;Ho=!!d.safari||!(!a||!(/\b(iPad|iPhone|iPod)\b/.test(a)||a.match("Safari")&&!a.match("Chrome")))}return Ho},n.L=class{constructor(d,a){this.target=d,this.mapId=a,this.resolveRejects={},this.tasks={},this.taskQueue=[],this.abortControllers={},this.messageHandlers={},this.invoker=new U_(()=>this.process()),this.subscription=so(this.target,"message",h=>this.receive(h),!1),this.globalScope=Co(self)?d:window}registerMessageHandler(d,a){this.messageHandlers[d]=a}unregisterMessageHandler(d){delete this.messageHandlers[d]}sendAsync(d,a){return new Promise((h,A)=>{let C=Math.round(1e18*Math.random()).toString(36).substring(0,10),D=a?so(a.signal,"abort",()=>{D?.unsubscribe(),delete this.resolveRejects[C];let Z={id:C,type:"",origin:location.origin,targetMapId:d.targetMapId,sourceMapId:this.mapId};this.target.postMessage(Z)},Av):null;this.resolveRejects[C]={resolve:Z=>{D?.unsubscribe(),h(Z)},reject:Z=>{D?.unsubscribe(),A(Z)}};let O=[],H=Object.assign(Object.assign({},d),{id:C,sourceMapId:this.mapId,origin:location.origin,data:Zt(d.data,O)});this.target.postMessage(H,{transfer:O})})}receive(d){let a=d.data,h=a.id;if(!(a.origin!=="file://"&&location.origin!=="file://"&&a.origin!=="resource://android"&&location.origin!=="resource://android"&&a.origin!==location.origin||a.targetMapId&&this.mapId!==a.targetMapId)){if(a.type===""){delete this.tasks[h];let A=this.abortControllers[h];return delete this.abortControllers[h],void(A&&A.abort())}if(Co(self)||a.mustQueue)return this.tasks[h]=a,this.taskQueue.push(h),void this.invoker.trigger();this.processTask(h,a)}}process(){if(this.taskQueue.length===0)return;let d=this.taskQueue.shift(),a=this.tasks[d];delete this.tasks[d],this.taskQueue.length>0&&this.invoker.trigger(),a&&this.processTask(d,a)}processTask(d,a){return o(this,void 0,void 0,function*(){if(a.type===""){let C=this.resolveRejects[d];return delete this.resolveRejects[d],C?void(a.error?C.reject(ir(a.error)):C.resolve(ir(a.data))):void 0}if(!this.messageHandlers[a.type])return void this.completeTask(d,new Error(`Could not find a registered handler for ${a.type}, map ID: ${this.mapId}, available handlers: ${Object.keys(this.messageHandlers).join(", ")}`));let h=ir(a.data),A=new AbortController;this.abortControllers[d]=A;try{let C=yield this.messageHandlers[a.type](a.sourceMapId,h,A);this.completeTask(d,null,C)}catch(C){this.completeTask(d,C)}})}completeTask(d,a,h){let A=[];delete this.abortControllers[d];let C={id:d,type:"",sourceMapId:this.mapId,origin:location.origin,error:a?Zt(a):null,data:Zt(h,A)};this.target.postMessage(C,{transfer:A})}remove(){this.invoker.remove(),this.subscription.unsubscribe()}},n.M=fr,n.N=function(){var d=new he(16);return he!=Float32Array&&(d[1]=0,d[2]=0,d[3]=0,d[4]=0,d[6]=0,d[7]=0,d[8]=0,d[9]=0,d[11]=0,d[12]=0,d[13]=0,d[14]=0),d[0]=1,d[5]=1,d[10]=1,d[15]=1,d},n.O=function(d,a,h){var A,C,D,O,H,Z,re,ce,de,we,Ee,De,ke=h[0],qe=h[1],st=h[2];return a===d?(d[12]=a[0]*ke+a[4]*qe+a[8]*st+a[12],d[13]=a[1]*ke+a[5]*qe+a[9]*st+a[13],d[14]=a[2]*ke+a[6]*qe+a[10]*st+a[14],d[15]=a[3]*ke+a[7]*qe+a[11]*st+a[15]):(C=a[1],D=a[2],O=a[3],H=a[4],Z=a[5],re=a[6],ce=a[7],de=a[8],we=a[9],Ee=a[10],De=a[11],d[0]=A=a[0],d[1]=C,d[2]=D,d[3]=O,d[4]=H,d[5]=Z,d[6]=re,d[7]=ce,d[8]=de,d[9]=we,d[10]=Ee,d[11]=De,d[12]=A*ke+H*qe+de*st+a[12],d[13]=C*ke+Z*qe+we*st+a[13],d[14]=D*ke+re*qe+Ee*st+a[14],d[15]=O*ke+ce*qe+De*st+a[15]),d},n.P=s,n.Q=function(d,a,h){var A=h[0],C=h[1],D=h[2];return d[0]=a[0]*A,d[1]=a[1]*A,d[2]=a[2]*A,d[3]=a[3]*A,d[4]=a[4]*C,d[5]=a[5]*C,d[6]=a[6]*C,d[7]=a[7]*C,d[8]=a[8]*D,d[9]=a[9]*D,d[10]=a[10]*D,d[11]=a[11]*D,d[12]=a[12],d[13]=a[13],d[14]=a[14],d[15]=a[15],d},n.R=rh,n.S=function(d,a,h){var A=a[0],C=a[1],D=a[2],O=a[3],H=a[4],Z=a[5],re=a[6],ce=a[7],de=a[8],we=a[9],Ee=a[10],De=a[11],ke=a[12],qe=a[13],st=a[14],kt=a[15],pt=h[0],_t=h[1],Ht=h[2],Qt=h[3];return d[0]=pt*A+_t*H+Ht*de+Qt*ke,d[1]=pt*C+_t*Z+Ht*we+Qt*qe,d[2]=pt*D+_t*re+Ht*Ee+Qt*st,d[3]=pt*O+_t*ce+Ht*De+Qt*kt,d[4]=(pt=h[4])*A+(_t=h[5])*H+(Ht=h[6])*de+(Qt=h[7])*ke,d[5]=pt*C+_t*Z+Ht*we+Qt*qe,d[6]=pt*D+_t*re+Ht*Ee+Qt*st,d[7]=pt*O+_t*ce+Ht*De+Qt*kt,d[8]=(pt=h[8])*A+(_t=h[9])*H+(Ht=h[10])*de+(Qt=h[11])*ke,d[9]=pt*C+_t*Z+Ht*we+Qt*qe,d[10]=pt*D+_t*re+Ht*Ee+Qt*st,d[11]=pt*O+_t*ce+Ht*De+Qt*kt,d[12]=(pt=h[12])*A+(_t=h[13])*H+(Ht=h[14])*de+(Qt=h[15])*ke,d[13]=pt*C+_t*Z+Ht*we+Qt*qe,d[14]=pt*D+_t*re+Ht*Ee+Qt*st,d[15]=pt*O+_t*ce+Ht*De+Qt*kt,d},n.T=XC,n.U=function(d,a){let h={};for(let A=0;A0||((C=D.addOrUpdateProperties)===null||C===void 0?void 0:C.length)>0;if((H||Z)&&(O=Object.assign({},O),d.set(D.id,O),H&&(O.geometry=D.newGeometry),Z)){if(O.properties=D.removeAllProperties?{}:Object.assign({},O.properties||{}),D.removeProperties)for(let re of D.removeProperties)delete O.properties[re];if(D.addOrUpdateProperties)for(let{key:re,value:ce}of D.addOrUpdateProperties)O.properties[re]=ce}}},n.aB=function(d,{uSize:a,uSizeT:h},{lowerSize:A,upperSize:C}){return d.kind==="source"?A/nc:d.kind==="composite"?Fr.number(A/nc,C/nc,h):a},n.aC=function(d,a){var h=a[0],A=a[1],C=a[2],D=a[3],O=a[4],H=a[5],Z=a[6],re=a[7],ce=a[8],de=a[9],we=a[10],Ee=a[11],De=a[12],ke=a[13],qe=a[14],st=a[15],kt=h*H-A*O,pt=h*Z-C*O,_t=h*re-D*O,Ht=A*Z-C*H,Qt=A*re-D*H,Ir=C*re-D*Z,oi=ce*ke-de*De,Kr=ce*qe-we*De,gi=ce*st-Ee*De,ji=de*qe-we*ke,vi=de*st-Ee*ke,Qr=we*st-Ee*qe,jr=kt*Qr-pt*vi+_t*ji+Ht*gi-Qt*Kr+Ir*oi;return jr?(d[0]=(H*Qr-Z*vi+re*ji)*(jr=1/jr),d[1]=(C*vi-A*Qr-D*ji)*jr,d[2]=(ke*Ir-qe*Qt+st*Ht)*jr,d[3]=(we*Qt-de*Ir-Ee*Ht)*jr,d[4]=(Z*gi-O*Qr-re*Kr)*jr,d[5]=(h*Qr-C*gi+D*Kr)*jr,d[6]=(qe*_t-De*Ir-st*pt)*jr,d[7]=(ce*Ir-we*_t+Ee*pt)*jr,d[8]=(O*vi-H*gi+re*oi)*jr,d[9]=(A*gi-h*vi-D*oi)*jr,d[10]=(De*Qt-ke*_t+st*kt)*jr,d[11]=(de*_t-ce*Qt-Ee*kt)*jr,d[12]=(H*Kr-O*ji-Z*oi)*jr,d[13]=(h*ji-A*Kr+C*oi)*jr,d[14]=(ke*pt-De*Ht-qe*kt)*jr,d[15]=(ce*Ht-de*pt+we*kt)*jr,d):null},n.aD=sr,n.aE=function(d){var a=d[0],h=d[1];return Math.sqrt(a*a+h*h)},n.aF=function(d){return d[0]=0,d[1]=0,d},n.aG=function(d,a,h){return d[0]=a[0]*h,d[1]=a[1]*h,d},n.aH=Bs,n.aI=Et,n.aJ=function(d,a,h,A){let C=a.y-d.y,D=a.x-d.x,O=A.y-h.y,H=A.x-h.x,Z=O*D-H*C;if(Z===0)return null;let re=(H*(d.y-h.y)-O*(d.x-h.x))/Z;return new s(d.x+re*D,d.y+re*C)},n.aK=NK,n.aL=Ro,n.aM=function(d){let a=1/0,h=1/0,A=-1/0,C=-1/0;for(let D of d)a=Math.min(a,D.x),h=Math.min(h,D.y),A=Math.max(A,D.x),C=Math.max(C,D.y);return[a,h,A,C]},n.aN=R,n.aO=mi,n.aP=function(d,a,h,A,C=!1){if(!h[0]&&!h[1])return[0,0];let D=C?A==="map"?-d.bearingInRadians:0:A==="viewport"?d.bearingInRadians:0;if(D){let O=Math.sin(D),H=Math.cos(D);h=[h[0]*H-h[1]*O,h[0]*O+h[1]*H]}return[C?h[0]:mi(a,h[0],d.zoom),C?h[1]:mi(a,h[1],d.zoom)]},n.aR=hs,n.aS=C8,n.aT=js,n.aU=I8,n.aV=na,n.aW=S2,n.aX=Me,n.aY=Ai,n.aZ=br,n.a_=ws,n.aa=_I,n.ab=Fp,n.ac=Ib,n.ad=25,n.ae=yv,n.af=d=>{let a=window.document.createElement("video");return a.muted=!0,new Promise(h=>{a.onloadstart=()=>{h(a)};for(let A of d){let C=window.document.createElement("source");Jr(A)||(a.crossOrigin="Anonymous"),C.src=A,a.appendChild(C)}})},n.ag=Ct,n.ah=function(){return nt++},n.ai=l,n.aj=dl,n.ak=Pc,n.al=Pi,n.am=vb,n.an=function(d){let a={};if(d.replace(/(?:^|(?:\s*\,\s*))([^\x00-\x20\(\)<>@\,;\:\\"\/\[\]\?\=\{\}\x7F]+)(?:\=(?:([^\x00-\x20\(\)<>@\,;\:\\"\/\[\]\?\=\{\}\x7F]+)|(?:\"((?:[^"\\]|\\.)*)\")))?/g,(h,A,C,D)=>{let O=C||D;return a[A]=!O||O.toLowerCase(),""}),a["max-age"]){let h=parseInt(a["max-age"],10);isNaN(h)?delete a["max-age"]:a["max-age"]=h}return a},n.ao=ii,n.ap=85.051129,n.aq=ps,n.ar=function(d){return Math.pow(2,d)},n.as=me,n.at=Ab,n.au=function(d){return Math.log(d)/Math.LN2},n.av=function(d){var a=d[0],h=d[1];return a*a+h*h},n.aw=function(d){if(!d.length)return new Set;let a=Math.max(...d.map(Z=>Z.canonical.z)),h=1/0,A=-1/0,C=1/0,D=-1/0,O=[];for(let Z of d){let{x:re,y:ce,z:de}=Z.canonical,we=Math.pow(2,a-de),Ee=re*we,De=ce*we;O.push({id:Z,x:Ee,y:De}),EeA&&(A=Ee),DeD&&(D=De)}let H=new Set;for(let Z of O)Z.x!==h&&Z.x!==A&&Z.y!==C&&Z.y!==D||H.add(Z.id);return H},n.ax=function(d,a){let h=Math.abs(2*d.wrap)-+(d.wrap<0),A=Math.abs(2*a.wrap)-+(a.wrap<0);return d.overscaledZ-a.overscaledZ||A-h||a.canonical.y-d.canonical.y||a.canonical.x-d.canonical.x},n.ay=class{constructor(d,a){this.max=d,this.onRemove=a,this.reset()}reset(){for(let d in this.data)for(let a of this.data[d])a.timeout&&clearTimeout(a.timeout),this.onRemove(a.value);return this.data={},this.order=[],this}add(d,a,h){let A=d.wrapped().key;this.data[A]===void 0&&(this.data[A]=[]);let C={value:a,timeout:void 0};if(h!==void 0&&(C.timeout=setTimeout(()=>{this.remove(d,C)},h)),this.data[A].push(C),this.order.push(A),this.order.length>this.max){let D=this._getAndRemoveByKey(this.order[0]);D&&this.onRemove(D)}return this}has(d){return d.wrapped().key in this.data}getAndRemove(d){return this.has(d)?this._getAndRemoveByKey(d.wrapped().key):null}_getAndRemoveByKey(d){let a=this.data[d].shift();return a.timeout&&clearTimeout(a.timeout),this.data[d].length===0&&delete this.data[d],this.order.splice(this.order.indexOf(d),1),a.value}getByKey(d){let a=this.data[d];return a?a[0].value:null}get(d){return this.has(d)?this.data[d.wrapped().key][0].value:null}remove(d,a){if(!this.has(d))return this;let h=d.wrapped().key,A=a===void 0?0:this.data[h].indexOf(a),C=this.data[h][A];return this.data[h].splice(A,1),C.timeout&&clearTimeout(C.timeout),this.data[h].length===0&&delete this.data[h],this.onRemove(C.value),this.order.splice(this.order.indexOf(h),1),this}setMaxSize(d){for(this.max=d;this.order.length>this.max;){let a=this._getAndRemoveByKey(this.order[0]);a&&this.onRemove(a)}return this}filter(d){let a=[];for(let h in this.data)for(let A of this.data[h])d(A.value)||a.push(A);for(let h of a)this.remove(h.value.tileID,h)}},n.az=function(d,a){let h=0,A=0;if(d.kind==="constant")A=d.layoutSize;else if(d.kind!=="source"){let{interpolationType:C,minZoom:D,maxZoom:O}=d,H=C?ii(Ut.interpolationFactor(C,a,D,O),0,1):0;d.kind==="camera"?A=Fr.number(d.minSize,d.maxSize,H):h=H}return{uSizeT:h,uSize:A}},n.b=is,n.b$=class extends x{constructor(d,a){super(d,a),this.current=0}set(d){this.current!==d&&(this.current=d,this.gl.uniform1i(this.location,d))}},n.b0=Xe,n.b1=Ge,n.b2=function(d){var a=new he(3);return a[0]=d[0],a[1]=d[1],a[2]=d[2],a},n.b3=function(d,a,h){return d[0]=a[0]-h[0],d[1]=a[1]-h[1],d[2]=a[2]-h[2],d},n.b4=function(d,a){var h=a[0],A=a[1],C=a[2],D=h*h+A*A+C*C;return D>0&&(D=1/Math.sqrt(D)),d[0]=a[0]*D,d[1]=a[1]*D,d[2]=a[2]*D,d},n.b5=Ce,n.b6=function(d,a){return d[0]*a[0]+d[1]*a[1]+d[2]*a[2]},n.b7=function(d,a,h){return d[0]=a[0]*h[0],d[1]=a[1]*h[1],d[2]=a[2]*h[2],d[3]=a[3]*h[3],d},n.b8=Oe,n.b9=function(d,a,h){let A=a[0]*h[0]+a[1]*h[1]+a[2]*h[2];return A===0?null:(-(d[0]*h[0]+d[1]*h[1]+d[2]*h[2])-h[3])/A},n.bA=function(){return new Float64Array(3)},n.bB=function(d,a,h,A){return d[0]=a[0]+h[0]*A,d[1]=a[1]+h[1]*A,d[2]=a[2]+h[2]*A,d},n.bC=xt,n.bD=function(d,a,h){var A=h[0],C=h[1],D=h[2],O=h[3],H=a[0],Z=a[1],re=a[2],ce=C*re-D*Z,de=D*H-A*re,we=A*Z-C*H;return d[0]=H+O*(ce+=ce)+C*(we+=we)-D*(de+=de),d[1]=Z+O*de+D*ce-A*we,d[2]=re+O*we+A*de-C*ce,d},n.bE=function(d,a,h){let A=function(Z){var re=Z[3],ce=Z[4],de=Z[5],we=Z[6],Ee=Z[7],De=Z[8];return Z[0]*(De*ce-de*Ee)+Z[1]*(-De*re+de*we)+Z[2]*(Ee*re-ce*we)}([d[0],d[1],d[2],a[0],a[1],a[2],h[0],h[1],h[2]]);if(A===0)return null;let C=Ce([],[a[0],a[1],a[2]],[h[0],h[1],h[2]]),D=Ce([],[h[0],h[1],h[2]],[d[0],d[1],d[2]]),O=Ce([],[d[0],d[1],d[2]],[a[0],a[1],a[2]]),H=Xe([],C,-d[3]);return Ge(H,H,Xe([],D,-a[3])),Ge(H,H,Xe([],O,-h[3])),Xe(H,H,1/A),H},n.bF=_m,n.bG=function(){return new Float64Array(4)},n.bH=function(d,a,h,A){var C=[],D=[];return C[0]=a[0]-h[0],C[1]=a[1]-h[1],C[2]=a[2]-h[2],D[0]=C[0]*Math.cos(A)-C[1]*Math.sin(A),D[1]=C[0]*Math.sin(A)+C[1]*Math.cos(A),D[2]=C[2],d[0]=D[0]+h[0],d[1]=D[1]+h[1],d[2]=D[2]+h[2],d},n.bI=function(d,a,h,A){var C=[],D=[];return C[0]=a[0]-h[0],C[1]=a[1]-h[1],C[2]=a[2]-h[2],D[0]=C[0],D[1]=C[1]*Math.cos(A)-C[2]*Math.sin(A),D[2]=C[1]*Math.sin(A)+C[2]*Math.cos(A),d[0]=D[0]+h[0],d[1]=D[1]+h[1],d[2]=D[2]+h[2],d},n.bJ=function(d,a,h,A){var C=[],D=[];return C[0]=a[0]-h[0],C[1]=a[1]-h[1],C[2]=a[2]-h[2],D[0]=C[2]*Math.sin(A)+C[0]*Math.cos(A),D[1]=C[1],D[2]=C[2]*Math.cos(A)-C[0]*Math.sin(A),d[0]=D[0]+h[0],d[1]=D[1]+h[1],d[2]=D[2]+h[2],d},n.bK=function(d,a,h){var A=Math.sin(h),C=Math.cos(h),D=a[0],O=a[1],H=a[2],Z=a[3],re=a[8],ce=a[9],de=a[10],we=a[11];return a!==d&&(d[4]=a[4],d[5]=a[5],d[6]=a[6],d[7]=a[7],d[12]=a[12],d[13]=a[13],d[14]=a[14],d[15]=a[15]),d[0]=D*C-re*A,d[1]=O*C-ce*A,d[2]=H*C-de*A,d[3]=Z*C-we*A,d[8]=D*A+re*C,d[9]=O*A+ce*C,d[10]=H*A+de*C,d[11]=Z*A+we*C,d},n.bL=function(d,a){let h=bi(d,360),A=bi(a,360),C=A-h,D=A>h?C-360:C+360;return Math.abs(C)0?O:-O},n.bO=function(d,a){let h=bi(d,2*Math.PI),A=bi(a,2*Math.PI);return Math.min(Math.abs(h-A),Math.abs(h-A+2*Math.PI),Math.abs(h-A-2*Math.PI))},n.bP=function(){let d={},a=wr.$version;for(let h in wr.$root){let A=wr.$root[h];if(A.required){let C=null;C=h==="version"?a:A.type==="array"?[]:{},C!=null&&(d[h]=C)}}return d},n.bQ=xr,n.bR=dr,n.bS=function d(a,h){if(Array.isArray(a)){if(!Array.isArray(h)||a.length!==h.length)return!1;for(let A=0;Ad.type==="raster",n.bW=Xr,n.bX=function(d,a){if(!d)return[{command:"setStyle",args:[a]}];let h=[];try{if(!Be(d.version,a.version))return[{command:"setStyle",args:[a]}];Be(d.center,a.center)||h.push({command:"setCenter",args:[a.center]}),Be(d.state,a.state)||h.push({command:"setGlobalState",args:[a.state]}),Be(d.centerAltitude,a.centerAltitude)||h.push({command:"setCenterAltitude",args:[a.centerAltitude]}),Be(d.zoom,a.zoom)||h.push({command:"setZoom",args:[a.zoom]}),Be(d.bearing,a.bearing)||h.push({command:"setBearing",args:[a.bearing]}),Be(d.pitch,a.pitch)||h.push({command:"setPitch",args:[a.pitch]}),Be(d.roll,a.roll)||h.push({command:"setRoll",args:[a.roll]}),Be(d.sprite,a.sprite)||h.push({command:"setSprite",args:[a.sprite]}),Be(d.glyphs,a.glyphs)||h.push({command:"setGlyphs",args:[a.glyphs]}),Be(d.transition,a.transition)||h.push({command:"setTransition",args:[a.transition]}),Be(d.light,a.light)||h.push({command:"setLight",args:[a.light]}),Be(d.terrain,a.terrain)||h.push({command:"setTerrain",args:[a.terrain]}),Be(d.sky,a.sky)||h.push({command:"setSky",args:[a.sky]}),Be(d.projection,a.projection)||h.push({command:"setProjection",args:[a.projection]});let A={},C=[];(function(O,H,Z,re){let ce;for(ce in H=H||{},O=O||{})Object.prototype.hasOwnProperty.call(O,ce)&&(Object.prototype.hasOwnProperty.call(H,ce)||mt(ce,Z,re));for(ce in H)Object.prototype.hasOwnProperty.call(H,ce)&&(Object.prototype.hasOwnProperty.call(O,ce)?Be(O[ce],H[ce])||(O[ce].type==="geojson"&&H[ce].type==="geojson"&&$t(O,H,ce)?$e(Z,{command:"setGeoJSONSourceData",args:[ce,H[ce].data]}):Qe(ce,H,Z,re)):it(ce,H,Z))})(d.sources,a.sources,C,A);let D=[];d.layers&&d.layers.forEach(O=>{"source"in O&&A[O.source]?h.push({command:"removeLayer",args:[O.id]}):D.push(O)}),h=h.concat(C),function(O,H,Z){H=H||[];let re=(O=O||[]).map(ht),ce=H.map(ht),de=O.reduce(Ot,{}),we=H.reduce(Ot,{}),Ee=re.slice(),De=Object.create(null),ke,qe,st,kt,pt;for(let _t=0,Ht=0;_tee?(C=Math.acos(D),O=Math.sin(C),H=Math.sin((1-A)*C)/O,Z=Math.sin(A*C)/O):(H=1-A,Z=A),d[0]=H*re+Z*Ee,d[1]=H*ce+Z*De,d[2]=H*de+Z*ke,d[3]=H*we+Z*qe,d},n.bo=function(d){let a=new Float64Array(9);(function(D,O){var H=O[0],Z=O[1],re=O[2],ce=O[3],de=H+H,we=Z+Z,Ee=re+re,De=H*de,ke=Z*de,qe=Z*we,st=re*de,kt=re*we,pt=re*Ee,_t=ce*de,Ht=ce*we,Qt=ce*Ee;D[0]=1-qe-pt,D[3]=ke-Qt,D[6]=st+Ht,D[1]=ke+Qt,D[4]=1-De-pt,D[7]=kt-_t,D[2]=st-Ht,D[5]=kt+_t,D[8]=1-De-qe})(a,d);let h=ws(-Math.asin(ii(a[2],-1,1))),A,C;return Math.hypot(a[5],a[8])<.001?(A=0,C=-ws(Math.atan2(a[3],a[4]))):(A=ws(a[5]===0&&a[8]===0?0:Math.atan2(a[5],a[8])),C=ws(a[1]===0&&a[0]===0?0:Math.atan2(a[1],a[0]))),{roll:A,pitch:h+90,bearing:C}},n.bp=function(d,a){return d.roll==a.roll&&d.pitch==a.pitch&&d.bearing==a.bearing},n.bq=Io,n.br=E,n.bs=hv,n.bt=lb,n.bu=L_,n.bv=un,n.bw=Yr,n.bx=vl,n.by=function(d,a,h,A,C){return un(A,C,ii((d-a)/(h-a),0,1))},n.bz=bi,n.c=Gt,n.c$=class{constructor(d){this._marks={start:[d.url,"start"].join("#"),end:[d.url,"end"].join("#"),measure:d.url.toString()},performance.mark(this._marks.start)}finish(){performance.mark(this._marks.end);let d=performance.getEntriesByName(this._marks.measure);return d.length===0&&(performance.measure(this._marks.measure,this._marks.start,this._marks.end),d=performance.getEntriesByName(this._marks.measure),performance.clearMarks(this._marks.start),performance.clearMarks(this._marks.end),performance.clearMeasures(this._marks.measure)),d}},n.c0=N,n.c1=class extends x{constructor(d,a){super(d,a),this.current=G}set(d){if(d[12]!==this.current[12]||d[0]!==this.current[0])return this.current=d,void this.gl.uniformMatrix4fv(this.location,!1,d);for(let a=1;a<16;a++)if(d[a]!==this.current[a]){this.current=d,this.gl.uniformMatrix4fv(this.location,!1,d);break}}},n.c2=B,n.c3=class extends x{constructor(d,a){super(d,a),this.current=[0,0,0]}set(d){d[0]===this.current[0]&&d[1]===this.current[1]&&d[2]===this.current[2]||(this.current=d,this.gl.uniform3f(this.location,d[0],d[1],d[2]))}},n.c4=class extends x{constructor(d,a){super(d,a),this.current=[0,0]}set(d){d[0]===this.current[0]&&d[1]===this.current[1]||(this.current=d,this.gl.uniform2f(this.location,d[0],d[1]))}},n.c5=xe,n.c6=function(d,a){var h=Math.sin(a),A=Math.cos(a);return d[0]=A,d[1]=h,d[2]=0,d[3]=-h,d[4]=A,d[5]=0,d[6]=0,d[7]=0,d[8]=1,d},n.c7=function(d,a,h){var A=a[0],C=a[1],D=a[2];return d[0]=A*h[0]+C*h[3]+D*h[6],d[1]=A*h[1]+C*h[4]+D*h[7],d[2]=A*h[2]+C*h[5]+D*h[8],d},n.c8=function(d,a,h,A,C,D,O){var H=1/(a-h),Z=1/(A-C),re=1/(D-O);return d[0]=-2*H,d[1]=0,d[2]=0,d[3]=0,d[4]=0,d[5]=-2*Z,d[6]=0,d[7]=0,d[8]=0,d[9]=0,d[10]=2*re,d[11]=0,d[12]=(a+h)*H,d[13]=(C+A)*Z,d[14]=(O+D)*re,d[15]=1,d},n.c9=class extends x{constructor(d,a){super(d,a),this.current=new Array}set(d){if(d!=this.current){this.current=d;let a=new Float32Array(4*d.length);for(let h=0;h25||A<0||A>=1||h<0||h>=1)},n.cF=function(d,a){return d[0]=a[0],d[1]=0,d[2]=0,d[3]=0,d[4]=0,d[5]=a[1],d[6]=0,d[7]=0,d[8]=0,d[9]=0,d[10]=a[2],d[11]=0,d[12]=0,d[13]=0,d[14]=0,d[15]=1,d},n.cG=class extends Jh{},n.cH=vTe,n.cJ=nr,n.cK=function(d,a){Gt.REGISTERED_PROTOCOLS[d]=a},n.cL=function(d){delete Gt.REGISTERED_PROTOCOLS[d]},n.cM=function(d,a){let h={};for(let C=0;CQr*R)}let Kr=O?"center":h.get("text-justify").evaluate(re,{},d.canonical),gi=h.get("symbol-placement")==="point"?h.get("text-max-width").evaluate(re,{},d.canonical)*R:1/0,ji=()=>{d.bucket.allowVerticalPlacement&&ai(_t)&&(De.vertical=In(ke,d.glyphMap,d.glyphPositions,d.imagePositions,ce,gi,D,Ir,"left",Qt,st,n.aA.vertical,!0,we,de))};if(!O&&oi){let vi=new Set;if(Kr==="auto")for(let jr=0;jr=this.maxEntries){let h=this.map.keys().next().value;this.map.delete(h)}this.map.set(d,a)}clear(){this.map.clear()}},n.cY=ub,n.cZ=tr,n.c_=DK,n.ca=class extends x{constructor(d,a){super(d,a),this.current=new Array}set(d){if(d!=this.current){this.current=d;let a=new Float32Array(d);this.gl.uniform1fv(this.location,a)}}},n.cb=class extends Tf{},n.cc=p,n.cd=class extends Fu{},n.ce=rA,n.cf=function(d){return d<=1?1:Math.pow(2,Math.ceil(Math.log(d)/Math.LN2))},n.cg=Qf,n.ch=function(d,a,h){var A=a[0],C=a[1],D=a[2],O=h[3]*A+h[7]*C+h[11]*D+h[15];return d[0]=(h[0]*A+h[4]*C+h[8]*D+h[12])/(O=O||1),d[1]=(h[1]*A+h[5]*C+h[9]*D+h[13])/O,d[2]=(h[2]*A+h[6]*C+h[10]*D+h[14])/O,d},n.ci=class extends Ul{},n.cj=class extends tA{},n.ck=function(d,a){return d[0]===a[0]&&d[1]===a[1]&&d[2]===a[2]&&d[3]===a[3]&&d[4]===a[4]&&d[5]===a[5]&&d[6]===a[6]&&d[7]===a[7]&&d[8]===a[8]&&d[9]===a[9]&&d[10]===a[10]&&d[11]===a[11]&&d[12]===a[12]&&d[13]===a[13]&&d[14]===a[14]&&d[15]===a[15]},n.cl=function(d,a){var h=d[0],A=d[1],C=d[2],D=d[3],O=d[4],H=d[5],Z=d[6],re=d[7],ce=d[8],de=d[9],we=d[10],Ee=d[11],De=d[12],ke=d[13],qe=d[14],st=d[15],kt=a[0],pt=a[1],_t=a[2],Ht=a[3],Qt=a[4],Ir=a[5],oi=a[6],Kr=a[7],gi=a[8],ji=a[9],vi=a[10],Qr=a[11],jr=a[12],dn=a[13],cn=a[14],vn=a[15];return Math.abs(h-kt)<=ee*Math.max(1,Math.abs(h),Math.abs(kt))&&Math.abs(A-pt)<=ee*Math.max(1,Math.abs(A),Math.abs(pt))&&Math.abs(C-_t)<=ee*Math.max(1,Math.abs(C),Math.abs(_t))&&Math.abs(D-Ht)<=ee*Math.max(1,Math.abs(D),Math.abs(Ht))&&Math.abs(O-Qt)<=ee*Math.max(1,Math.abs(O),Math.abs(Qt))&&Math.abs(H-Ir)<=ee*Math.max(1,Math.abs(H),Math.abs(Ir))&&Math.abs(Z-oi)<=ee*Math.max(1,Math.abs(Z),Math.abs(oi))&&Math.abs(re-Kr)<=ee*Math.max(1,Math.abs(re),Math.abs(Kr))&&Math.abs(ce-gi)<=ee*Math.max(1,Math.abs(ce),Math.abs(gi))&&Math.abs(de-ji)<=ee*Math.max(1,Math.abs(de),Math.abs(ji))&&Math.abs(we-vi)<=ee*Math.max(1,Math.abs(we),Math.abs(vi))&&Math.abs(Ee-Qr)<=ee*Math.max(1,Math.abs(Ee),Math.abs(Qr))&&Math.abs(De-jr)<=ee*Math.max(1,Math.abs(De),Math.abs(jr))&&Math.abs(ke-dn)<=ee*Math.max(1,Math.abs(ke),Math.abs(dn))&&Math.abs(qe-cn)<=ee*Math.max(1,Math.abs(qe),Math.abs(cn))&&Math.abs(st-vn)<=ee*Math.max(1,Math.abs(st),Math.abs(vn))},n.cm=function(d,a){return d[0]=a[0],d[1]=a[1],d[2]=a[2],d[3]=a[3],d[4]=a[4],d[5]=a[5],d[6]=a[6],d[7]=a[7],d[8]=a[8],d[9]=a[9],d[10]=a[10],d[11]=a[11],d[12]=a[12],d[13]=a[13],d[14]=a[14],d[15]=a[15],d},n.cn=d=>d.type==="symbol",n.co=d=>d.type==="circle",n.cp=d=>d.type==="heatmap",n.cq=d=>d.type==="line",n.cr=d=>d.type==="fill",n.cs=d=>d.type==="fill-extrusion",n.ct=d=>d.type==="hillshade",n.cu=d=>d.type==="color-relief",n.cv=d=>d.type==="background",n.cw=d=>d.type==="custom",n.cx=Xi,n.cy=function(d,a,h){let A=Mr(a.x-h.x,a.y-h.y),C=Mr(d.x-h.x,d.y-h.y),D=Math.atan2(A[0]*C[1]-A[1]*C[0],function(O,H){return O[0]*H[0]+O[1]*H[1]}(A,C));return ws(D)},n.cz=xi,n.d=Jr,n.d0=function(d,a,h,A,C){return o(this,void 0,void 0,function*(){if(K())try{return yield zs(d,a,h,A,C)}catch{}return function(D,O,H,Z,re){let ce=D.width,de=D.height;Ba&&ds||(Ba=new OffscreenCanvas(ce,de),ds=Ba.getContext("2d",{willReadFrequently:!0})),Ba.width=ce,Ba.height=de,ds.drawImage(D,0,0,ce,de);let we=ds.getImageData(O,H,Z,re);return ds.clearRect(0,0,ce,de),we.data}(d,a,h,A,C)})},n.d1=ZC,n.d2=c,n.d3=class{constructor(d,a){this.layers={[_I]:this},this.name=_I,this.version=a?a.version:1,this.extent=a?a.extent:4096,this.length=d.length,this.features=d}feature(d){return new iTe(this.features[d],this.extent)}},n.d4=$d,n.d5=$n,n.e=Ve,n.f=d=>o(void 0,void 0,void 0,function*(){if(d.byteLength===0)return createImageBitmap(new ImageData(1,1));let a=new Blob([new Uint8Array(d)],{type:"image/png"});try{return createImageBitmap(a)}catch(h){throw new Error(`Could not load image because of ${h.message}. Please make sure to use a supported image type such as PNG or JPEG. Note that SVGs are not supported.`)}}),n.g=yr,n.h=d=>new Promise((a,h)=>{let A=new Image;A.onload=()=>{a(A),URL.revokeObjectURL(A.src),A.onload=null,window.requestAnimationFrame(()=>{A.src=mo})},A.onerror=()=>h(new Error("Could not load image. Please make sure to use a supported image type such as PNG or JPEG. Note that SVGs are not supported."));let C=new Blob([new Uint8Array(d)],{type:"image/png"});A.src=d.byteLength?URL.createObjectURL(C):mo}),n.i=Co,n.j=(d,a)=>ti(Ve(d,{type:"json"}),a),n.k=bs,n.l=Wn,n.m=ti,n.n=(d,a)=>ti(Ve(d,{type:"arrayBuffer"}),a),n.o=function(d){return new tr(d).readFields(en,[])},n.p=pn,n.q=function(d){return/[\u02EA\u02EB\u1100-\u11FF\u2E80-\u2FDF\u3000-\u30FF\u3105-\u312F\u3131-\u318E\u31A0-\u4DBF\u4E00-\uA48C\uA490-\uA4C6\uA960-\uA97C\uAC00-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFE10-\uFE1F\uFE30-\uFE4F\uFF00-\uFFEF]|\uD81B[\uDFE0-\uDFFF]|[\uD81C-\uD822\uD840-\uD868\uD86A-\uD86D\uD86F-\uD872\uD874-\uD879\uD880-\uD883\uD885-\uD88C][\uDC00-\uDFFF]|\uD823[\uDC00-\uDCD5\uDCFF-\uDD1E\uDD80-\uDDF2]|\uD82B[\uDFF0-\uDFFF]|\uD82C[\uDC00-\uDEFB]|\uD83C[\uDE00-\uDEFF]|\uD869[\uDC00-\uDEDF\uDF00-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEAD\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0\uDFF0-\uDFFF]|\uD87B[\uDC00-\uDE5D]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A\uDF50-\uDFFF]|\uD88D[\uDC00-\uDC79]/gim.test(String.fromCodePoint(d))},n.r=n0,n.s=so,n.t=Fa,n.u=wr,n.v=Y,n.w=ln,n.x=Il,n.y=ae,n.z=eo}),r("worker",["./shared"],function(n){"use strict";class o{constructor(Fe,Ne){this.keyCache={},Fe&&this.replace(Fe,Ne)}replace(Fe,Ne){this._layerConfigs={},this._layers={},this.update(Fe,[],Ne)}update(Fe,Ne,rt){for(let Gt of Fe){this._layerConfigs[Gt.id]=Gt;let yr=this._layers[Gt.id]=n.bU(Gt,rt);yr._featureFilter=n.ak(yr.filter,rt),this.keyCache[Gt.id]&&delete this.keyCache[Gt.id]}for(let Gt of Ne)delete this.keyCache[Gt],delete this._layerConfigs[Gt],delete this._layers[Gt];this.familiesBySource={};let Vt=n.cM(Object.values(this._layerConfigs),this.keyCache);for(let Gt of Vt){let yr=Gt.map(Wi=>this._layers[Wi.id]),fr=yr[0];if(fr.visibility==="none")continue;let nr=fr.source||"",xr=this.familiesBySource[nr];xr||(xr=this.familiesBySource[nr]={});let ti=fr.sourceLayer||n.aa,Jr=xr[ti];Jr||(Jr=xr[ti]=[]),Jr.push(yr)}}}class s{constructor(Fe){let Ne={},rt=[];for(let fr in Fe){let nr=Fe[fr],xr=Ne[fr]={};for(let ti in nr){let Jr=nr[+ti];if(!Jr||Jr.bitmap.width===0||Jr.bitmap.height===0)continue;let Wi={x:0,y:0,w:Jr.bitmap.width+2,h:Jr.bitmap.height+2};rt.push(Wi),xr[ti]={rect:Wi,metrics:Jr.metrics}}}let{w:Vt,h:Gt}=n.p(rt),yr=new n.r({width:Vt||1,height:Gt||1});for(let fr in Fe){let nr=Fe[fr];for(let xr in nr){let ti=nr[+xr];if(!ti||ti.bitmap.width===0||ti.bitmap.height===0)continue;let Jr=Ne[fr][xr].rect;n.r.copy(ti.bitmap,yr,{x:0,y:0},{x:Jr.x+1,y:Jr.y+1},ti.bitmap)}}this.image=yr,this.positions=Ne}}n.cN("GlyphAtlas",s);class c{constructor(Fe){this.tileID=new n.a2(Fe.tileID.overscaledZ,Fe.tileID.wrap,Fe.tileID.canonical.z,Fe.tileID.canonical.x,Fe.tileID.canonical.y),this.uid=Fe.uid,this.zoom=Fe.zoom,this.pixelRatio=Fe.pixelRatio,this.tileSize=Fe.tileSize,this.source=Fe.source,this.overscaling=this.tileID.overscaleFactor(),this.showCollisionBoxes=Fe.showCollisionBoxes,this.collectResourceTiming=!!Fe.collectResourceTiming,this.returnDependencies=!!Fe.returnDependencies,this.promoteId=Fe.promoteId,this.inFlightDependencies=[]}parse(Fe,Ne,rt,Vt,Gt){return n._(this,void 0,void 0,function*(){this.status="parsing",this.data=Fe,this.collisionBoxArray=new n.ai;let yr=new n.cO(Object.keys(Fe.layers).sort()),fr=new n.cP(this.tileID,this.promoteId);fr.bucketLayerIDs=[];let nr={},xr={featureIndex:fr,iconDependencies:{},patternDependencies:{},glyphDependencies:{},dashDependencies:{},availableImages:rt,subdivisionGranularity:Gt},ti=Ne.familiesBySource[this.source];for(let $t in ti){let Jt=Fe.layers[$t];if(!Jt)continue;Jt.version===1&&n.w(`Vector tile source "${this.source}" layer "${$t}" does not use vector tile spec v2 and therefore may have some rendering errors.`);let ht=yr.encode($t),Ot=[];for(let Ct=0;Ctui.id)))}}let Jr=n.bZ(xr.glyphDependencies,$t=>Object.keys($t).map(Number));this.inFlightDependencies.forEach($t=>$t?.abort()),this.inFlightDependencies=[];let Wi=Promise.resolve({});if(Object.keys(Jr).length){let $t=new AbortController;this.inFlightDependencies.push($t),Wi=Vt.sendAsync({type:"GG",data:{stacks:Jr,source:this.source,tileID:this.tileID,type:"glyphs"}},$t)}let fn=Object.keys(xr.iconDependencies),Wn=Promise.resolve({});if(fn.length){let $t=new AbortController;this.inFlightDependencies.push($t),Wn=Vt.sendAsync({type:"GI",data:{icons:fn,source:this.source,tileID:this.tileID,type:"icons"}},$t)}let bs=Object.keys(xr.patternDependencies),go=Promise.resolve({});if(bs.length){let $t=new AbortController;this.inFlightDependencies.push($t),go=Vt.sendAsync({type:"GI",data:{icons:bs,source:this.source,tileID:this.tileID,type:"patterns"}},$t)}let wr=xr.dashDependencies,Us=Promise.resolve({});if(Object.keys(wr).length){let $t=new AbortController;this.inFlightDependencies.push($t),Us=Vt.sendAsync({type:"GDA",data:{dashes:wr}},$t)}let[ns,Be,$e,it]=yield Promise.all([Wi,Wn,go,Us]),mt=new s(ns),Qe=new n.cQ(Be,$e);for(let $t in nr){let Jt=nr[$t];Jt instanceof n.aj?(f(Jt.layers,this.zoom,rt),n.cR({bucket:Jt,glyphMap:ns,glyphPositions:mt.positions,imageMap:Be,imagePositions:Qe.iconPositions,showCollisionBoxes:this.showCollisionBoxes,canonical:this.tileID.canonical,subdivisionGranularity:xr.subdivisionGranularity})):Jt.hasDependencies&&(Jt instanceof n.cS||Jt instanceof n.cT||Jt instanceof n.cU)&&(f(Jt.layers,this.zoom,rt),Jt.addFeatures(xr,this.tileID.canonical,Qe.patternPositions,it))}return this.status="done",{buckets:Object.values(nr).filter($t=>!$t.isEmpty()),featureIndex:fr,collisionBoxArray:this.collisionBoxArray,glyphAtlasImage:mt.image,imageAtlas:Qe,dashPositions:it,glyphMap:this.returnDependencies?ns:null,iconMap:this.returnDependencies?Be:null,glyphPositions:this.returnDependencies?mt.positions:null}})}}function f(Yt,Fe,Ne){let rt=new n.H(Fe);for(let Vt of Yt)Vt.recalculate(rt,Ne)}class g{constructor(Fe,Ne,rt,Vt,Gt){this.type=Fe,this.properties=rt||{},this.extent=Gt,this.pointsArray=Ne,this.id=Vt}loadGeometry(){return this.pointsArray.map(Fe=>Fe.map(Ne=>new n.P(Ne.x,Ne.y)))}}class y{constructor(Fe,Ne,rt){this.version=2,this._myFeatures=Fe,this.name=Ne,this.length=Fe.length,this.extent=rt}feature(Fe){return this._myFeatures[Fe]}}class I{constructor(){this.layers={}}addLayer(Fe){this.layers[Fe.name]=Fe}}function F(Yt){let Fe=n.cV(Yt);return Fe.byteOffset===0&&Fe.byteLength===Fe.buffer.byteLength||(Fe=new Uint8Array(Fe)),{vectorTile:Yt,rawData:Fe.buffer}}function k(Yt,Fe,Ne){let{extent:rt}=Yt,Vt=Math.pow(2,Ne.z-Fe.z),Gt=(Ne.x-Fe.x*Vt)*rt,yr=(Ne.y-Fe.y*Vt)*rt,fr=[];for(let nr=0;nr0&&xr.addLayer(Wn)}let Jr=F(xr);return this.overzoomedTileResultCache.set(fr,Jr),Jr}reloadTile(Fe){return n._(this,void 0,void 0,function*(){let Ne=Fe.uid;if(!this.loaded||!this.loaded[Ne])throw new Error("Should not be trying to reload a tile that was never loaded or has been removed");let rt=this.loaded[Ne];if(rt.showCollisionBoxes=Fe.showCollisionBoxes,rt.status==="parsing"){let Vt=yield rt.parse(rt.vectorTile,this.layerIndex,this.availableImages,this.actor,Fe.subdivisionGranularity),Gt;if(this.fetching[Ne]){let{rawTileData:yr,cacheControl:fr,resourceTiming:nr}=this.fetching[Ne];delete this.fetching[Ne],Gt=n.e({rawTileData:yr.slice(0),encoding:Fe.encoding},Vt,fr,nr)}else Gt=Vt;return Gt}if(rt.status==="done"&&rt.vectorTile)return rt.parse(rt.vectorTile,this.layerIndex,this.availableImages,this.actor,Fe.subdivisionGranularity)})}abortTile(Fe){return n._(this,void 0,void 0,function*(){let Ne=this.loading,rt=Fe.uid;Ne&&Ne[rt]&&Ne[rt].abort&&(Ne[rt].abort.abort(),delete Ne[rt])})}removeTile(Fe){return n._(this,void 0,void 0,function*(){this.loaded&&this.loaded[Fe.uid]&&delete this.loaded[Fe.uid]})}}class K{constructor(){this.loaded={}}loadTile(Fe){return n._(this,void 0,void 0,function*(){let{uid:Ne,encoding:rt,rawImageData:Vt,redFactor:Gt,greenFactor:yr,blueFactor:fr,baseShift:nr}=Fe,xr=Vt.width+2,ti=Vt.height+2,Jr=n.b(Vt)?new n.R({width:xr,height:ti},yield n.d0(Vt,-1,-1,xr,ti)):Vt,Wi=new n.d1(Ne,Jr,rt,Gt,yr,fr,nr);return this.loaded=this.loaded||{},this.loaded[Ne]=Wi,Wi})}removeTile(Fe){let Ne=this.loaded,rt=Fe.uid;Ne&&Ne[rt]&&delete Ne[rt]}}var ee,he,xe=function(){if(he)return ee;function Yt(Ne,rt){if(Ne.length!==0){Fe(Ne[0],rt);for(var Vt=1;Vt=Math.abs(xr)?Vt-ti+xr:xr-ti+Vt,Vt=ti}Vt+Gt>=0!=!!rt&&Ne.reverse()}return he=1,ee=function Ne(rt,Vt){var Gt,yr=rt&&rt.type;if(yr==="FeatureCollection")for(Gt=0;GtYt},Oe=Math.fround||(ne=new Float32Array(1),Yt=>(ne[0]=+Yt,ne[0]));var ne;class Ge{constructor(Fe){this.options=Object.assign(Object.create(Se),Fe),this.trees=new Array(this.options.maxZoom+1),this.stride=this.options.reduce?7:6,this.clusterProps=[]}load(Fe){let{log:Ne,minZoom:rt,maxZoom:Vt}=this.options;Ne&&console.time("total time");let Gt=`prepare ${Fe.length} points`;Ne&&console.time(Gt),this.points=Fe;let yr=[];for(let nr=0;nr=rt;nr--){let xr=+Date.now();fr=this.trees[nr]=this._createTree(this._cluster(fr,nr)),Ne&&console.log("z%d: %d clusters in %dms",nr,fr.numItems,+Date.now()-xr)}return Ne&&console.timeEnd("total time"),this}getClusters(Fe,Ne){let rt=((Fe[0]+180)%360+360)%360-180,Vt=Math.max(-90,Math.min(90,Fe[1])),Gt=Fe[2]===180?180:((Fe[2]+180)%360+360)%360-180,yr=Math.max(-90,Math.min(90,Fe[3]));if(Fe[2]-Fe[0]>=360)rt=-180,Gt=180;else if(rt>Gt){let Jr=this.getClusters([rt,Vt,180,yr],Ne),Wi=this.getClusters([-180,Vt,Gt,yr],Ne);return Jr.concat(Wi)}let fr=this.trees[this._limitZoom(Ne)],nr=fr.range(_e(rt),Je(yr),_e(Gt),Je(Vt)),xr=fr.data,ti=[];for(let Jr of nr){let Wi=this.stride*Jr;ti.push(xr[Wi+5]>1?Xe(xr,Wi,this.clusterProps):this.points[xr[Wi+3]])}return ti}getChildren(Fe){let Ne=this._getOriginId(Fe),rt=this._getOriginZoom(Fe),Vt="No cluster with the specified id.",Gt=this.trees[rt];if(!Gt)throw new Error(Vt);let yr=Gt.data;if(Ne*this.stride>=yr.length)throw new Error(Vt);let fr=this.options.radius/(this.options.extent*Math.pow(2,rt-1)),nr=Gt.within(yr[Ne*this.stride],yr[Ne*this.stride+1],fr),xr=[];for(let ti of nr){let Jr=ti*this.stride;yr[Jr+4]===Fe&&xr.push(yr[Jr+5]>1?Xe(yr,Jr,this.clusterProps):this.points[yr[Jr+3]])}if(xr.length===0)throw new Error(Vt);return xr}getLeaves(Fe,Ne,rt){let Vt=[];return this._appendLeaves(Vt,Fe,Ne=Ne||10,rt=rt||0,0),Vt}getTile(Fe,Ne,rt){let Vt=this.trees[this._limitZoom(Fe)],Gt=Math.pow(2,Fe),{extent:yr,radius:fr}=this.options,nr=fr/yr,xr=(rt-nr)/Gt,ti=(rt+1+nr)/Gt,Jr={features:[]};return this._addTileFeatures(Vt.range((Ne-nr)/Gt,xr,(Ne+1+nr)/Gt,ti),Vt.data,Ne,rt,Gt,Jr),Ne===0&&this._addTileFeatures(Vt.range(1-nr/Gt,xr,1,ti),Vt.data,Gt,rt,Gt,Jr),Ne===Gt-1&&this._addTileFeatures(Vt.range(0,xr,nr/Gt,ti),Vt.data,-1,rt,Gt,Jr),Jr.features.length?Jr:null}getClusterExpansionZoom(Fe){let Ne=this._getOriginZoom(Fe)-1;for(;Ne<=this.options.maxZoom;){let rt=this.getChildren(Fe);if(Ne++,rt.length!==1)break;Fe=rt[0].properties.cluster_id}return Ne}_appendLeaves(Fe,Ne,rt,Vt,Gt){let yr=this.getChildren(Ne);for(let fr of yr){let nr=fr.properties;if(nr&&nr.cluster?Gt+nr.point_count<=Vt?Gt+=nr.point_count:Gt=this._appendLeaves(Fe,nr.cluster_id,rt,Vt,Gt):Gt1,ti,Jr,Wi;if(xr)ti=Ce(Ne,nr,this.clusterProps),Jr=Ne[nr],Wi=Ne[nr+1];else{let bs=this.points[Ne[nr+3]];ti=bs.properties;let[go,wr]=bs.geometry.coordinates;Jr=_e(go),Wi=Je(wr)}let fn={type:1,geometry:[[Math.round(this.options.extent*(Jr*Gt-rt)),Math.round(this.options.extent*(Wi*Gt-Vt))]],tags:ti},Wn;Wn=xr||this.options.generateId?Ne[nr+3]:this.points[Ne[nr+3]].id,Wn!==void 0&&(fn.id=Wn),yr.features.push(fn)}}_limitZoom(Fe){return Math.max(this.options.minZoom,Math.min(Math.floor(+Fe),this.options.maxZoom+1))}_cluster(Fe,Ne){let{radius:rt,extent:Vt,reduce:Gt,minPoints:yr}=this.options,fr=rt/(Vt*Math.pow(2,Ne)),nr=Fe.data,xr=[],ti=this.stride;for(let Jr=0;JrNe&&(go+=nr[Us+5])}if(go>bs&&go>=yr){let wr,Us=Wi*bs,ns=fn*bs,Be=-1,$e=(Jr/ti<<5)+(Ne+1)+this.points.length;for(let it of Wn){let mt=it*ti;if(nr[mt+2]<=Ne)continue;nr[mt+2]=Ne;let Qe=nr[mt+5];Us+=nr[mt]*Qe,ns+=nr[mt+1]*Qe,nr[mt+4]=$e,Gt&&(wr||(wr=this._map(nr,Jr,!0),Be=this.clusterProps.length,this.clusterProps.push(wr)),Gt(wr,this._map(nr,mt)))}nr[Jr+4]=$e,xr.push(Us/go,ns/go,1/0,$e,-1,go),Gt&&xr.push(Be)}else{for(let wr=0;wr1)for(let wr of Wn){let Us=wr*ti;if(!(nr[Us+2]<=Ne)){nr[Us+2]=Ne;for(let ns=0;ns>5}_getOriginZoom(Fe){return(Fe-this.points.length)%32}_map(Fe,Ne,rt){if(Fe[Ne+5]>1){let yr=this.clusterProps[Fe[Ne+6]];return rt?Object.assign({},yr):yr}let Vt=this.points[Fe[Ne+3]].properties,Gt=this.options.map(Vt);return rt&&Gt===Vt?Object.assign({},Gt):Gt}}function Xe(Yt,Fe,Ne){return{type:"Feature",id:Yt[Fe+3],properties:Ce(Yt,Fe,Ne),geometry:{type:"Point",coordinates:[(rt=Yt[Fe],360*(rt-.5)),Et(Yt[Fe+1])]}};var rt}function Ce(Yt,Fe,Ne){let rt=Yt[Fe+5],Vt=rt>=1e4?`${Math.round(rt/1e3)}k`:rt>=1e3?Math.round(rt/100)/10+"k":rt,Gt=Yt[Fe+6],yr=Gt===-1?{}:Object.assign({},Ne[Gt]);return Object.assign(yr,{cluster:!0,cluster_id:Yt[Fe+3],point_count:rt,point_count_abbreviated:Vt})}function _e(Yt){return Yt/360+.5}function Je(Yt){let Fe=Math.sin(Yt*Math.PI/180),Ne=.5-.25*Math.log((1+Fe)/(1-Fe))/Math.PI;return Ne<0?0:Ne>1?1:Ne}function Et(Yt){let Fe=(180-360*Yt)*Math.PI/180;return 360*Math.atan(Math.exp(Fe))/Math.PI-90}function Ze(Yt,Fe,Ne,rt){let Vt=rt,Gt=Fe+(Ne-Fe>>1),yr,fr=Ne-Fe,nr=Yt[Fe],xr=Yt[Fe+1],ti=Yt[Ne],Jr=Yt[Ne+1];for(let Wi=Fe+3;WiVt)yr=Wi,Vt=fn;else if(fn===Vt){let Wn=Math.abs(Wi-Gt);Wnrt&&(yr-Fe>3&&Ze(Yt,Fe,yr,rt),Yt[yr+2]=Vt,Ne-yr>3&&Ze(Yt,yr,Ne,rt))}function xt(Yt,Fe,Ne,rt,Vt,Gt){let yr=Vt-Ne,fr=Gt-rt;if(yr!==0||fr!==0){let nr=((Yt-Ne)*yr+(Fe-rt)*fr)/(yr*yr+fr*fr);nr>1?(Ne=Vt,rt=Gt):nr>0&&(Ne+=yr*nr,rt+=fr*nr)}return yr=Yt-Ne,fr=Fe-rt,yr*yr+fr*fr}function sr(Yt,Fe,Ne,rt){let Vt={id:Yt??null,type:Fe,geometry:Ne,tags:rt,minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0};if(Fe==="Point"||Fe==="MultiPoint"||Fe==="LineString")Mr(Vt,Ne);else if(Fe==="Polygon")Mr(Vt,Ne[0]);else if(Fe==="MultiLineString")for(let Gt of Ne)Mr(Vt,Gt);else if(Fe==="MultiPolygon")for(let Gt of Ne)Mr(Vt,Gt[0]);return Vt}function Mr(Yt,Fe){for(let Ne=0;Ne0&&(yr+=rt?(Vt*ti-xr*Gt)/2:Math.sqrt(Math.pow(xr-Vt,2)+Math.pow(ti-Gt,2))),Vt=xr,Gt=ti}let fr=Fe.length-3;Fe[2]=1,Ze(Fe,0,fr,Ne),Fe[fr+2]=1,Fe.size=Math.abs(yr),Fe.start=0,Fe.end=Fe.size}function un(Yt,Fe,Ne,rt){for(let Vt=0;Vt1?1:Ne}function xi(Yt,Fe,Ne,rt,Vt,Gt,yr,fr){if(rt/=Fe,Gt>=(Ne/=Fe)&&yr=rt)return null;let nr=[];for(let xr of Yt){let ti=xr.geometry,Jr=xr.type,Wi=Vt===0?xr.minX:xr.minY,fn=Vt===0?xr.maxX:xr.maxY;if(Wi>=Ne&&fn=rt)continue;let Wn=[];if(Jr==="Point"||Jr==="MultiPoint")ii(ti,Wn,Ne,rt,Vt);else if(Jr==="LineString")Gn(ti,Wn,Ne,rt,Vt,!1,fr.lineMetrics);else if(Jr==="MultiLineString")nt(ti,Wn,Ne,rt,Vt,!1);else if(Jr==="Polygon")nt(ti,Wn,Ne,rt,Vt,!0);else if(Jr==="MultiPolygon")for(let bs of ti){let go=[];nt(bs,go,Ne,rt,Vt,!0),go.length&&Wn.push(go)}if(Wn.length){if(fr.lineMetrics&&Jr==="LineString"){for(let bs of Wn)nr.push(sr(xr.id,Jr,bs,xr.tags));continue}Jr!=="LineString"&&Jr!=="MultiLineString"||(Wn.length===1?(Jr="LineString",Wn=Wn[0]):Jr="MultiLineString"),Jr!=="Point"&&Jr!=="MultiPoint"||(Jr=Wn.length===3?"Point":"MultiPoint"),nr.push(sr(xr.id,Jr,Wn,xr.tags))}}return nr.length?nr:null}function ii(Yt,Fe,Ne,rt,Vt){for(let Gt=0;Gt=Ne&&yr<=rt&&Ft(Fe,Yt[Gt],Yt[Gt+1],Yt[Gt+2])}}function Gn(Yt,Fe,Ne,rt,Vt,Gt,yr){let fr=Ve(Yt),nr=Vt===0?mr:Xr,xr,ti,Jr=Yt.start;for(let go=0;goNe&&(ti=nr(fr,wr,Us,Be,$e,Ne),yr&&(fr.start=Jr+xr*ti)):it>rt?mt=Ne&&(ti=nr(fr,wr,Us,Be,$e,Ne),Qe=!0),mt>rt&&it<=rt&&(ti=nr(fr,wr,Us,Be,$e,rt),Qe=!0),!Gt&&Qe&&(yr&&(fr.end=Jr+xr*ti),Fe.push(fr),fr=Ve(Yt)),yr&&(Jr+=xr)}let Wi=Yt.length-3,fn=Yt[Wi],Wn=Yt[Wi+1],bs=Vt===0?fn:Wn;bs>=Ne&&bs<=rt&&Ft(fr,fn,Wn,Yt[Wi+2]),Wi=fr.length-3,Gt&&Wi>=3&&(fr[Wi]!==fr[0]||fr[Wi+1]!==fr[1])&&Ft(fr,fr[0],fr[1],fr[2]),fr.length&&Fe.push(fr)}function Ve(Yt){let Fe=[];return Fe.size=Yt.size,Fe.start=Yt.start,Fe.end=Yt.end,Fe}function nt(Yt,Fe,Ne,rt,Vt,Gt){for(let yr of Yt)Gn(yr,Fe,Ne,rt,Vt,Gt,!1)}function Ft(Yt,Fe,Ne,rt){Yt.push(Fe,Ne,rt)}function mr(Yt,Fe,Ne,rt,Vt,Gt){let yr=(Gt-Fe)/(rt-Fe);return Ft(Yt,Gt,Ne+(Vt-Ne)*yr,1),yr}function Xr(Yt,Fe,Ne,rt,Vt,Gt){let yr=(Gt-Ne)/(Vt-Ne);return Ft(Yt,Fe+(rt-Fe)*yr,Gt,1),yr}function zr(Yt,Fe){let Ne=[];for(let rt=0;rt0&&Fe.size<(Vt?yr:rt))return void(Ne.numPoints+=Fe.length/3);let fr=[];for(let nr=0;nryr)&&(Ne.numSimplified++,fr.push(Fe[nr],Fe[nr+1])),Ne.numPoints++;Vt&&function(nr,xr){let ti=0;for(let Jr=0,Wi=nr.length,fn=Wi-2;Jr0===xr)for(let Jr=0,Wi=nr.length;Jr24)throw new Error("maxZoom should be in the 0-24 range");if(Ne.promoteId&&Ne.generateId)throw new Error("promoteId and generateId cannot be used together.");let Vt=function(Gt,yr){let fr=[];if(Gt.type==="FeatureCollection")for(let nr=0;nr1&&console.time("creation"),fn=this.tiles[Wi]=Ho(Fe,Ne,rt,Vt,xr),this.tileCoords.push({z:Ne,x:rt,y:Vt}),ti)){ti>1&&(console.log("tile z%d-%d-%d (features: %d, points: %d, simplified: %d)",Ne,rt,Vt,fn.numFeatures,fn.numPoints,fn.numSimplified),console.timeEnd("creation"));let Qe=`z${Ne}`;this.stats[Qe]=(this.stats[Qe]||0)+1,this.total++}if(fn.source=Fe,Gt==null){if(Ne===xr.indexMaxZoom||fn.numPoints<=xr.indexMaxPoints)continue}else{if(Ne===xr.maxZoom||Ne===Gt)continue;if(Gt!=null){let Qe=Gt-Ne;if(rt!==yr>>Qe||Vt!==fr>>Qe)continue}}if(fn.source=null,Fe.length===0)continue;ti>1&&console.time("clipping");let Wn=.5*xr.buffer/xr.extent,bs=.5-Wn,go=.5+Wn,wr=1+Wn,Us=null,ns=null,Be=null,$e=null,it=xi(Fe,Jr,rt-Wn,rt+go,0,fn.minX,fn.maxX,xr),mt=xi(Fe,Jr,rt+bs,rt+wr,0,fn.minX,fn.maxX,xr);Fe=null,it&&(Us=xi(it,Jr,Vt-Wn,Vt+go,1,fn.minY,fn.maxY,xr),ns=xi(it,Jr,Vt+bs,Vt+wr,1,fn.minY,fn.maxY,xr),it=null),mt&&(Be=xi(mt,Jr,Vt-Wn,Vt+go,1,fn.minY,fn.maxY,xr),$e=xi(mt,Jr,Vt+bs,Vt+wr,1,fn.minY,fn.maxY,xr),mt=null),ti>1&&console.timeEnd("clipping"),nr.push(Us||[],Ne+1,2*rt,2*Vt),nr.push(ns||[],Ne+1,2*rt,2*Vt+1),nr.push(Be||[],Ne+1,2*rt+1,2*Vt),nr.push($e||[],Ne+1,2*rt+1,2*Vt+1)}}getTile(Fe,Ne,rt){Fe=+Fe,Ne=+Ne,rt=+rt;let Vt=this.options,{extent:Gt,debug:yr}=Vt;if(Fe<0||Fe>24)return null;let fr=1<1&&console.log("drilling down to z%d-%d-%d",Fe,Ne,rt);let xr,ti=Fe,Jr=Ne,Wi=rt;for(;!xr&&ti>0;)ti--,Jr>>=1,Wi>>=1,xr=this.tiles[ds(ti,Jr,Wi)];return xr&&xr.source?(yr>1&&(console.log("found parent tile z%d-%d-%d",ti,Jr,Wi),console.time("drilling down")),this.splitTile(xr.source,ti,Jr,Wi,Fe,Ne,rt),yr>1&&console.timeEnd("drilling down"),this.tiles[nr]?Nn(this.tiles[nr],Gt):null):null}}function ds(Yt,Fe,Ne){return 32*((1<`${Gt.key}: ${Gt.message}`).join(", "));let Vt=Fe.features.filter(Gt=>rt.value.evaluate({zoom:0},Gt));return this._toFeatureCollection(Vt)}_toFeatureCollection(Fe){return{type:"FeatureCollection",features:Fe}}removeSource(Fe){return n._(this,void 0,void 0,function*(){this._pendingRequest&&this._pendingRequest.abort()})}getClusterExpansionZoom(Fe){return this._geoJSONIndex.getClusterExpansionZoom(Fe.clusterId)}getClusterChildren(Fe){return this._geoJSONIndex.getChildren(Fe.clusterId)}getClusterLeaves(Fe){return this._geoJSONIndex.getLeaves(Fe.clusterId,Fe.limit,Fe.offset)}}function ps(Yt,Fe){return Fe.cluster?new Ge(function({superclusterOptions:Ne,clusterProperties:rt}){if(!rt||!Ne)return Ne;let Vt={},Gt={},yr={accumulated:null,zoom:0},fr={properties:null},nr=Object.keys(rt);for(let xr of nr){let[ti,Jr]=rt[xr],Wi=n.d4(Jr),fn=n.d4(typeof ti=="string"?[ti,["accumulated"],["get",xr]]:ti);Vt[xr]=Wi.value,Gt[xr]=fn.value}return Ne.map=xr=>{fr.properties=xr;let ti={};for(let Jr of nr)ti[Jr]=Vt[Jr].evaluate(yr,fr);return ti},Ne.reduce=(xr,ti)=>{fr.properties=ti;for(let Jr of nr)yr.accumulated=xr[Jr],xr[Jr]=Gt[Jr].evaluate(yr,fr)},Ne}(Fe)).load(Yt.features):function(Ne,rt){return new Ba(Ne,rt)}(Yt,Fe.geojsonVtOptions)}class ws{constructor(Fe){this.self=Fe,this.actor=new n.L(Fe),this.layerIndexes={},this.availableImages={},this.workerSources={},this.demWorkerSources={},this.externalWorkerSourceTypes={},this.globalStates=new Map,this.self.registerWorkerSource=(Ne,rt)=>{if(this.externalWorkerSourceTypes[Ne])throw new Error(`Worker source with name "${Ne}" already registered.`);this.externalWorkerSourceTypes[Ne]=rt},this.self.addProtocol=n.cK,this.self.removeProtocol=n.cL,this.self.registerRTLTextPlugin=Ne=>{n.d5.setMethods(Ne)},this.actor.registerMessageHandler("LDT",(Ne,rt)=>this._getDEMWorkerSource(Ne,rt.source).loadTile(rt)),this.actor.registerMessageHandler("RDT",(Ne,rt)=>n._(this,void 0,void 0,function*(){this._getDEMWorkerSource(Ne,rt.source).removeTile(rt)})),this.actor.registerMessageHandler("GCEZ",(Ne,rt)=>n._(this,void 0,void 0,function*(){return this._getWorkerSource(Ne,rt.type,rt.source).getClusterExpansionZoom(rt)})),this.actor.registerMessageHandler("GCC",(Ne,rt)=>n._(this,void 0,void 0,function*(){return this._getWorkerSource(Ne,rt.type,rt.source).getClusterChildren(rt)})),this.actor.registerMessageHandler("GCL",(Ne,rt)=>n._(this,void 0,void 0,function*(){return this._getWorkerSource(Ne,rt.type,rt.source).getClusterLeaves(rt)})),this.actor.registerMessageHandler("LD",(Ne,rt)=>this._getWorkerSource(Ne,rt.type,rt.source).loadData(rt)),this.actor.registerMessageHandler("GD",(Ne,rt)=>this._getWorkerSource(Ne,rt.type,rt.source).getData()),this.actor.registerMessageHandler("LT",(Ne,rt)=>this._getWorkerSource(Ne,rt.type,rt.source).loadTile(rt)),this.actor.registerMessageHandler("RT",(Ne,rt)=>this._getWorkerSource(Ne,rt.type,rt.source).reloadTile(rt)),this.actor.registerMessageHandler("AT",(Ne,rt)=>this._getWorkerSource(Ne,rt.type,rt.source).abortTile(rt)),this.actor.registerMessageHandler("RMT",(Ne,rt)=>this._getWorkerSource(Ne,rt.type,rt.source).removeTile(rt)),this.actor.registerMessageHandler("RS",(Ne,rt)=>n._(this,void 0,void 0,function*(){if(!this.workerSources[Ne]||!this.workerSources[Ne][rt.type]||!this.workerSources[Ne][rt.type][rt.source])return;let Vt=this.workerSources[Ne][rt.type][rt.source];delete this.workerSources[Ne][rt.type][rt.source],Vt.removeSource!==void 0&&Vt.removeSource(rt)})),this.actor.registerMessageHandler("RM",Ne=>n._(this,void 0,void 0,function*(){delete this.layerIndexes[Ne],delete this.availableImages[Ne],delete this.workerSources[Ne],delete this.demWorkerSources[Ne],this.globalStates.delete(Ne)})),this.actor.registerMessageHandler("SR",(Ne,rt)=>n._(this,void 0,void 0,function*(){this.referrer=rt})),this.actor.registerMessageHandler("SRPS",(Ne,rt)=>this._syncRTLPluginState(Ne,rt)),this.actor.registerMessageHandler("IS",(Ne,rt)=>n._(this,void 0,void 0,function*(){this.self.importScripts(rt)})),this.actor.registerMessageHandler("SI",(Ne,rt)=>this._setImages(Ne,rt)),this.actor.registerMessageHandler("UL",(Ne,rt)=>n._(this,void 0,void 0,function*(){this._getLayerIndex(Ne).update(rt.layers,rt.removedIds,this._getGlobalState(Ne))})),this.actor.registerMessageHandler("UGS",(Ne,rt)=>n._(this,void 0,void 0,function*(){let Vt=this._getGlobalState(Ne);for(let Gt in rt)Vt[Gt]=rt[Gt]})),this.actor.registerMessageHandler("SL",(Ne,rt)=>n._(this,void 0,void 0,function*(){this._getLayerIndex(Ne).replace(rt,this._getGlobalState(Ne))}))}_getGlobalState(Fe){let Ne=this.globalStates.get(Fe);return Ne||(Ne={},this.globalStates.set(Fe,Ne)),Ne}_setImages(Fe,Ne){return n._(this,void 0,void 0,function*(){this.availableImages[Fe]=Ne;for(let rt in this.workerSources[Fe]){let Vt=this.workerSources[Fe][rt];for(let Gt in Vt)Vt[Gt].availableImages=Ne}})}_syncRTLPluginState(Fe,Ne){return n._(this,void 0,void 0,function*(){return yield n.d5.syncState(Ne,this.self.importScripts)})}_getAvailableImages(Fe){let Ne=this.availableImages[Fe];return Ne||(Ne=[]),Ne}_getLayerIndex(Fe){let Ne=this.layerIndexes[Fe];return Ne||(Ne=this.layerIndexes[Fe]=new o),Ne}_getWorkerSource(Fe,Ne,rt){if(this.workerSources[Fe]||(this.workerSources[Fe]={}),this.workerSources[Fe][Ne]||(this.workerSources[Fe][Ne]={}),!this.workerSources[Fe][Ne][rt]){let Vt={sendAsync:(Gt,yr)=>(Gt.targetMapId=Fe,this.actor.sendAsync(Gt,yr))};switch(Ne){case"vector":this.workerSources[Fe][Ne][rt]=new U(Vt,this._getLayerIndex(Fe),this._getAvailableImages(Fe));break;case"geojson":this.workerSources[Fe][Ne][rt]=new so(Vt,this._getLayerIndex(Fe),this._getAvailableImages(Fe));break;default:this.workerSources[Fe][Ne][rt]=new this.externalWorkerSourceTypes[Ne](Vt,this._getLayerIndex(Fe),this._getAvailableImages(Fe))}}return this.workerSources[Fe][Ne][rt]}_getDEMWorkerSource(Fe,Ne){return this.demWorkerSources[Fe]||(this.demWorkerSources[Fe]={}),this.demWorkerSources[Fe][Ne]||(this.demWorkerSources[Fe][Ne]=new K),this.demWorkerSources[Fe][Ne]}}return n.i(self)&&(self.worker=new ws(self)),ws}),r("index",["exports","./shared"],function(n,o){"use strict";var s="5.14.0";function c(){var z=new o.A(4);return o.A!=Float32Array&&(z[1]=0,z[2]=0),z[0]=1,z[3]=1,z}let f,g,y,I={frame(z,l,m){let T=requestAnimationFrame(V=>{P(),l(V)}),{unsubscribe:P}=o.s(z.signal,"abort",()=>{P(),cancelAnimationFrame(T),m(new o.a(z.signal.reason))},!1)},frameAsync(z){return new Promise((l,m)=>{this.frame(z,l,m)})},getImageData(z,l=0){return this.getImageCanvasContext(z).getImageData(-l,-l,z.width+2*l,z.height+2*l)},getImageCanvasContext(z){let l=window.document.createElement("canvas"),m=l.getContext("2d",{willReadFrequently:!0});if(!m)throw new Error("failed to create canvas 2d context");return l.width=z.width,l.height=z.height,m.drawImage(z,0,0,z.width,z.height),m},resolveURL:z=>(f||(f=document.createElement("a")),f.href=z,f.href),hardwareConcurrency:typeof navigator<"u"&&navigator.hardwareConcurrency||4,get prefersReducedMotion(){return y!==void 0?y:!!matchMedia&&(g==null&&(g=matchMedia("(prefers-reduced-motion: reduce)")),g.matches)},set prefersReducedMotion(z){y=z}},F=new class{constructor(){this._realTime=typeof performance<"u"&&performance&&performance.now?performance.now.bind(performance):Date.now.bind(Date),this._frozenAt=null}getCurrentTime(){return this._frozenAt!==null?this._frozenAt:this._realTime()}setNow(z){this._frozenAt=z}restoreNow(){this._frozenAt=null}isFrozen(){return this._frozenAt!==null}};function k(){return F.getCurrentTime()}class U{static testProp(l){if(!U.docStyle)return l[0];for(let m=0;m{window.removeEventListener("click",U.suppressClickInternal,!0)},0)}static getScale(l){let m=l.getBoundingClientRect();return{x:m.width/l.offsetWidth||1,y:m.height/l.offsetHeight||1,boundingClientRect:m}}static getPoint(l,m,T){let P=m.boundingClientRect;return new o.P((T.clientX-P.left)/m.x-l.clientLeft,(T.clientY-P.top)/m.y-l.clientTop)}static mousePos(l,m){let T=U.getScale(l);return U.getPoint(l,T,m)}static touchPos(l,m){let T=[],P=U.getScale(l);for(let V=0;V{ee&&Se(ee),ee=null,me=!0},he.onerror=()=>{xe=!0,ee=null},he.src="data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAQAAAAfQ//73v/+BiOh/AAA="),function(z){let l,m,T,P;z.resetRequestQueue=()=>{l=[],m=0,T=0,P={}},z.addThrottleControl=se=>{let fe=T++;return P[fe]=se,fe},z.removeThrottleControl=se=>{delete P[se],W()},z.getImage=(se,fe,ye=!0)=>new Promise((Re,Me)=>{K.supported&&(se.headers||(se.headers={}),se.headers.accept="image/webp,*/*"),o.e(se,{type:"image"}),l.push({abortController:fe,requestParameters:se,supportImageRefresh:ye,state:"queued",onError:je=>{Me(je)},onSuccess:je=>{Re(je)}}),W()});let V=se=>o._(this,void 0,void 0,function*(){se.state="running";let{requestParameters:fe,supportImageRefresh:ye,onError:Re,onSuccess:Me,abortController:je}=se,tt=ye===!1&&!o.i(self)&&!o.g(fe.url)&&(!fe.headers||Object.keys(fe.headers).reduce((vt,Lt)=>vt&&Lt==="accept",!0));m++;let yt=tt?te(fe,je):o.m(fe,je);try{let vt=yield yt;delete se.abortController,se.state="completed",vt.data instanceof HTMLImageElement||o.b(vt.data)?Me(vt):vt.data&&Me({data:yield(At=vt.data,typeof createImageBitmap=="function"?o.f(At):o.h(At)),cacheControl:vt.cacheControl,expires:vt.expires})}catch(vt){delete se.abortController,Re(vt)}finally{m--,W()}var At}),W=()=>{let se=(()=>{for(let fe of Object.keys(P))if(P[fe]())return!0;return!1})()?o.c.MAX_PARALLEL_IMAGE_REQUESTS_PER_FRAME:o.c.MAX_PARALLEL_IMAGE_REQUESTS;for(let fe=m;fe0;fe++){let ye=l.shift();ye.abortController.signal.aborted?fe--:V(ye)}},te=(se,fe)=>new Promise((ye,Re)=>{let Me=new Image,je=se.url,tt=se.credentials;tt&&tt==="include"?Me.crossOrigin="use-credentials":(tt&&tt==="same-origin"||!o.d(je))&&(Me.crossOrigin="anonymous"),fe.signal.addEventListener("abort",()=>{Me.src="",Re(new o.a(fe.signal.reason))}),Me.fetchPriority="high",Me.onload=()=>{Me.onerror=Me.onload=null,ye({data:Me})},Me.onerror=()=>{Me.onerror=Me.onload=null,fe.signal.aborted||Re(new Error("Could not load image. Please make sure to use a supported image type such as PNG or JPEG. Note that SVGs are not supported."))},Me.src=je})}(Oe||(Oe={})),Oe.resetRequestQueue();class ne{constructor(l){this._transformRequestFn=l??null}transformRequest(l,m){return this._transformRequestFn&&this._transformRequestFn(l,m)||{url:l}}setTransformRequest(l){this._transformRequestFn=l}}function Ge(z){let l=[];if(typeof z=="string")l.push({id:"default",url:z});else if(z&&z.length>0){let m=[];for(let{id:T,url:P}of z){let V=`${T}${P}`;m.indexOf(V)===-1&&(m.push(V),l.push({id:T,url:P}))}}return l}function Xe(z,l,m){try{let T=new URL(z);return T.pathname+=`${l}${m}`,T.toString()}catch{throw new Error(`Invalid sprite URL "${z}", must be absolute. Modify style specification directly or use TransformStyleFunction to correct the issue dynamically`)}}function Ce(z){let{userImage:l}=z;return!!(l&&l.render&&l.render())&&(z.data.replace(new Uint8Array(l.data.buffer)),!0)}class _e extends o.E{constructor(){super(),this.images={},this.updatedImages={},this.callbackDispatchedThisFrame={},this.loaded=!1,this.requestors=[],this.patterns={},this.atlasImage=new o.R({width:1,height:1}),this.dirty=!0}destroy(){this.atlasTexture&&(this.atlasTexture.destroy(),this.atlasTexture=null);for(let l of Object.keys(this.images))this.removeImage(l);this.patterns={},this.atlasImage=new o.R({width:1,height:1}),this.dirty=!0}isLoaded(){return this.loaded}setLoaded(l){if(this.loaded!==l&&(this.loaded=l,l)){for(let{ids:m,promiseResolve:T}of this.requestors)T(this._getImagesForIds(m));this.requestors=[]}}getImage(l){let m=this.images[l];if(m&&!m.data&&m.spriteData){let T=m.spriteData;m.data=new o.R({width:T.width,height:T.height},T.context.getImageData(T.x,T.y,T.width,T.height).data),m.spriteData=null}return m}addImage(l,m){if(this.images[l])throw new Error(`Image id ${l} already exist, use updateImage instead`);this._validate(l,m)&&(this.images[l]=m)}_validate(l,m){let T=!0,P=m.data||m.spriteData;return this._validateStretch(m.stretchX,P&&P.width)||(this.fire(new o.k(new Error(`Image "${l}" has invalid "stretchX" value`))),T=!1),this._validateStretch(m.stretchY,P&&P.height)||(this.fire(new o.k(new Error(`Image "${l}" has invalid "stretchY" value`))),T=!1),this._validateContent(m.content,m)||(this.fire(new o.k(new Error(`Image "${l}" has invalid "content" value`))),T=!1),T}_validateStretch(l,m){if(!l)return!0;let T=0;for(let P of l){if(P[0]{let P=!0;if(!this.isLoaded())for(let V of l)this.images[V]||(P=!1);this.isLoaded()||P?m(this._getImagesForIds(l)):this.requestors.push({ids:l,promiseResolve:m})})}_getImagesForIds(l){let m={};for(let T of l){let P=this.getImage(T);P||(this.fire(new o.l("styleimagemissing",{id:T})),P=this.getImage(T)),P?m[T]={data:P.data.clone(),pixelRatio:P.pixelRatio,sdf:P.sdf,version:P.version,stretchX:P.stretchX,stretchY:P.stretchY,content:P.content,textFitWidth:P.textFitWidth,textFitHeight:P.textFitHeight,hasRenderCallback:Boolean(P.userImage&&P.userImage.render)}:o.w(`Image "${T}" could not be loaded. Please make sure you have added the image with map.addImage() or a "sprite" property in your style. You can provide missing images by listening for the "styleimagemissing" map event.`)}return m}getPixelSize(){let{width:l,height:m}=this.atlasImage;return{width:l,height:m}}getPattern(l){let m=this.patterns[l],T=this.getImage(l);if(!T)return null;if(m&&m.position.version===T.version)return m.position;if(m)m.position.version=T.version;else{let P={w:T.data.width+2,h:T.data.height+2,x:0,y:0},V=new o.I(P,T);this.patterns[l]={bin:P,position:V}}return this._updatePatternAtlas(),this.patterns[l].position}bind(l){let m=l.gl;this.atlasTexture?this.dirty&&(this.atlasTexture.update(this.atlasImage),this.dirty=!1):this.atlasTexture=new o.T(l,this.atlasImage,m.RGBA),this.atlasTexture.bind(m.LINEAR,m.CLAMP_TO_EDGE)}_updatePatternAtlas(){let l=[];for(let V in this.patterns)l.push(this.patterns[V].bin);let{w:m,h:T}=o.p(l),P=this.atlasImage;P.resize({width:m||1,height:T||1});for(let V in this.patterns){let{bin:W}=this.patterns[V],te=W.x+1,se=W.y+1,fe=this.getImage(V).data,ye=fe.width,Re=fe.height;o.R.copy(fe,P,{x:0,y:0},{x:te,y:se},{width:ye,height:Re}),o.R.copy(fe,P,{x:0,y:Re-1},{x:te,y:se-1},{width:ye,height:1}),o.R.copy(fe,P,{x:0,y:0},{x:te,y:se+Re},{width:ye,height:1}),o.R.copy(fe,P,{x:ye-1,y:0},{x:te-1,y:se},{width:1,height:Re}),o.R.copy(fe,P,{x:0,y:0},{x:te+ye,y:se},{width:1,height:Re})}this.dirty=!0}beginFrame(){this.callbackDispatchedThisFrame={}}dispatchRenderCallbacks(l){for(let m of l){if(this.callbackDispatchedThisFrame[m])continue;this.callbackDispatchedThisFrame[m]=!0;let T=this.getImage(m);T||o.w(`Image with ID: "${m}" was not found`),Ce(T)&&this.updateImage(m,T)}}cloneImages(){let l={};for(let m in this.images){let T=this.images[m];l[m]=Object.assign(Object.assign({},T),{data:T.data?T.data.clone():null})}return l}}let Je=1e20;function Et(z,l,m,T,P,V,W,te,se){for(let fe=l;fe-1);se++,V[se]=te,W[se]=fe,W[se+1]=Je}for(let te=0,se=0;te/[-\w]+/.test(P)?P:`'${CSS.escape(P)}'`).join(",");return new sr.TinySDF({fontSize:48,buffer:6,radius:16,cutoff:.25,fontFamily:T,fontWeight:this._fontWeight(m[0]),fontStyle:this._fontStyle(m[0]),lang:this.lang})}_fontStyle(l){return/italic/i.test(l)?"italic":/oblique/i.test(l)?"oblique":"normal"}_fontWeight(l){let m={thin:100,hairline:100,"extra light":200,"ultra light":200,light:300,normal:400,regular:400,medium:500,semibold:600,demibold:600,bold:700,"extra bold":800,"ultra bold":800,black:900,heavy:900,"extra black":950,"ultra black":950},T;for(let[P,V]of Object.entries(m))new RegExp(`\\b${P}\\b`,"i").test(l)&&(T=`${V}`);return T}destroy(){for(let l in this.entries){let m=this.entries[l];m.tinySDF&&(m.tinySDF=null),m.ideographTinySDF&&(m.ideographTinySDF=null),m.glyphs={},m.requests={},m.ranges={}}this.entries={}}}sr.loadGlyphRange=function(z,l,m,T){return o._(this,void 0,void 0,function*(){let P=256*l,V=P+255,W=T.transformRequest(m.replace("{fontstack}",z).replace("{range}",`${P}-${V}`),"Glyphs"),te=yield o.n(W,new AbortController);if(!te||!te.data)throw new Error(`Could not load glyph range. range: ${l}, ${P}-${V}`);let se={};for(let fe of o.o(te.data))se[fe.id]=fe;return se})},sr.TinySDF=class{constructor({fontSize:z=24,buffer:l=3,radius:m=8,cutoff:T=.25,fontFamily:P="sans-serif",fontWeight:V="normal",fontStyle:W="normal",lang:te=null}={}){this.buffer=l,this.cutoff=T,this.radius=m,this.lang=te;let se=this.size=z+4*l,fe=this._createCanvas(se),ye=this.ctx=fe.getContext("2d",{willReadFrequently:!0});ye.font=`${W} ${V} ${z}px ${P}`,ye.textBaseline="alphabetic",ye.textAlign="left",ye.fillStyle="black",this.gridOuter=new Float64Array(se*se),this.gridInner=new Float64Array(se*se),this.f=new Float64Array(se),this.z=new Float64Array(se+1),this.v=new Uint16Array(se)}_createCanvas(z){let l=document.createElement("canvas");return l.width=l.height=z,l}draw(z){let{width:l,actualBoundingBoxAscent:m,actualBoundingBoxDescent:T,actualBoundingBoxLeft:P,actualBoundingBoxRight:V}=this.ctx.measureText(z),W=Math.ceil(m),te=Math.max(0,Math.min(this.size-this.buffer,Math.ceil(V-P))),se=Math.min(this.size-this.buffer,W+Math.ceil(T)),fe=te+2*this.buffer,ye=se+2*this.buffer,Re=Math.max(fe*ye,0),Me=new Uint8ClampedArray(Re),je={data:Me,width:fe,height:ye,glyphWidth:te,glyphHeight:se,glyphTop:W,glyphLeft:0,glyphAdvance:l};if(te===0||se===0)return je;let{ctx:tt,buffer:yt,gridInner:At,gridOuter:vt}=this;this.lang&&(tt.lang=this.lang),tt.clearRect(yt,yt,te,se),tt.fillText(z,yt,yt+W);let Lt=tt.getImageData(yt,yt,te,se);vt.fill(Je,0,Re),At.fill(0,0,Re);for(let Kt=0;Kt0?zt*zt:0,At[Rt]=zt<0?zt*zt:0}}Et(vt,0,0,fe,ye,fe,this.f,this.v,this.z),Et(At,yt,yt,te,se,fe,this.f,this.v,this.z);for(let Kt=0;Kt1&&(se=l[++te]);let ye=Math.abs(fe-se.left),Re=Math.abs(fe-se.right),Me=Math.min(ye,Re),je,tt=V/T*(P+1);if(se.isDash){let yt=P-Math.abs(tt);je=Math.sqrt(Me*Me+yt*yt)}else je=P-Math.sqrt(Me*Me+tt*tt);this.data[W+fe]=Math.max(0,Math.min(255,je+128))}}}addRegularDash(l){for(let te=l.length-1;te>=0;--te){let se=l[te],fe=l[te+1];se.zeroLength?l.splice(te,1):fe&&fe.isDash===se.isDash&&(fe.left=se.left,l.splice(te,1))}let m=l[0],T=l[l.length-1];m.isDash===T.isDash&&(m.left=T.left-this.width,T.right=m.right+this.width);let P=this.width*this.nextRow,V=0,W=l[V];for(let te=0;te1&&(W=l[++V]);let se=Math.abs(te-W.left),fe=Math.abs(te-W.right),ye=Math.min(se,fe);this.data[P+te]=Math.max(0,Math.min(255,(W.isDash?ye:-ye)+128))}}addDash(l,m){let T=m?7:0,P=2*T+1;if(this.nextRow+P>this.height)return o.w("LineAtlas out of space"),null;let V=0;for(let te=0;te{m.terminate()}),this.workers=null)}isPreloaded(){return!!this.active[Xi]}numActive(){return Object.keys(this.active).length}}let ii=Math.floor(I.hardwareConcurrency/2),Gn,Ve;function nt(){return Gn||(Gn=new xi),Gn}xi.workerCount=o.K(globalThis)?Math.max(Math.min(ii,3),1):1;class Ft{constructor(l,m){this.workerPool=l,this.actors=[],this.currentActor=0,this.id=m;let T=this.workerPool.acquire(m);for(let P=0;P{m.remove()}),this.actors=[],l&&this.workerPool.release(this.id)}registerMessageHandler(l,m){for(let T of this.actors)T.registerMessageHandler(l,m)}unregisterMessageHandler(l){for(let m of this.actors)m.unregisterMessageHandler(l)}}function mr(){return Ve||(Ve=new Ft(nt(),o.M),Ve.registerMessageHandler("GR",(z,l,m)=>o.m(l,m))),Ve}function Xr(z,l){let m=o.N();return o.O(m,m,[1,1,0]),o.Q(m,m,[.5*z.width,.5*z.height,1]),z.calculatePosMatrix?o.S(m,m,z.calculatePosMatrix(l.toUnwrapped())):m}function zr(z,l,m,T,P,V,W){var te;let se=function(Me,je,tt){if(Me)for(let yt of Me){let At=je[yt];if(At&&At.source===tt&&At.type==="fill-extrusion")return!0}else for(let yt in je){let At=je[yt];if(At.source===tt&&At.type==="fill-extrusion")return!0}return!1}((te=P?.layers)!==null&&te!==void 0?te:null,l,z.id),fe=V.maxPitchScaleFactor(),ye=z.tilesIn(T,fe,se);ye.sort(ln);let Re=[];for(let Me of ye)Re.push({wrappedTileID:Me.tileID.wrapped().key,queryResults:Me.tile.queryRenderedFeatures(l,m,z.getState(),Me.queryGeometry,Me.cameraQueryGeometry,Me.scale,P,V,fe,Xr(V,Me.tileID),W?(je,tt)=>W(Me.tileID,je,tt):void 0)});return function(Me,je){for(let tt in Me)for(let yt of Me[tt])Nn(yt,je);return Me}(function(Me){let je={},tt={};for(let yt of Me){let At=yt.queryResults,vt=yt.wrappedTileID,Lt=tt[vt]=tt[vt]||{};for(let Kt in At){let It=At[Kt],Xt=Lt[Kt]=Lt[Kt]||{},Rt=je[Kt]=je[Kt]||[];for(let zt of It)Xt[zt.featureIndex]||(Xt[zt.featureIndex]=!0,Rt.push(zt))}}return je}(Re),z)}function ln(z,l){let m=z.tileID,T=l.tileID;return m.overscaledZ-T.overscaledZ||m.canonical.y-T.canonical.y||m.wrap-T.wrap||m.canonical.x-T.canonical.x}function Nn(z,l){let m=z.feature,T=l.getFeatureState(m.layer["source-layer"],m.id);m.source=m.layer.source,m.layer["source-layer"]&&(m.sourceLayer=m.layer["source-layer"]),m.state=T}function Co(z,l,m){return o._(this,void 0,void 0,function*(){let T=z;if(z.url?T=(yield o.j(l.transformRequest(z.url,"Source"),m)).data:yield I.frameAsync(m),!T)return null;let P=o.U(o.e(T,z),["tiles","minzoom","maxzoom","attribution","bounds","scheme","tileSize","encoding"]);return"vector_layers"in T&&T.vector_layers&&(P.vectorLayerIds=T.vector_layers.map(V=>V.id)),P})}class Ho{constructor(l,m){l&&(m?this.setSouthWest(l).setNorthEast(m):Array.isArray(l)&&(l.length===4?this.setSouthWest([l[0],l[1]]).setNorthEast([l[2],l[3]]):this.setSouthWest(l[0]).setNorthEast(l[1])))}setNorthEast(l){return this._ne=l instanceof o.V?new o.V(l.lng,l.lat):o.V.convert(l),this}setSouthWest(l){return this._sw=l instanceof o.V?new o.V(l.lng,l.lat):o.V.convert(l),this}extend(l){let m=this._sw,T=this._ne,P,V;if(l instanceof o.V)P=l,V=l;else{if(!(l instanceof Ho))return Array.isArray(l)?l.length===4||l.every(Array.isArray)?this.extend(Ho.convert(l)):this.extend(o.V.convert(l)):l&&("lng"in l||"lon"in l)&&"lat"in l?this.extend(o.V.convert(l)):this;if(P=l._sw,V=l._ne,!P||!V)return this}return m||T?(m.lng=Math.min(P.lng,m.lng),m.lat=Math.min(P.lat,m.lat),T.lng=Math.max(V.lng,T.lng),T.lat=Math.max(V.lat,T.lat)):(this._sw=new o.V(P.lng,P.lat),this._ne=new o.V(V.lng,V.lat)),this}getCenter(){return new o.V((this._sw.lng+this._ne.lng)/2,(this._sw.lat+this._ne.lat)/2)}getSouthWest(){return this._sw}getNorthEast(){return this._ne}getNorthWest(){return new o.V(this.getWest(),this.getNorth())}getSouthEast(){return new o.V(this.getEast(),this.getSouth())}getWest(){return this._sw.lng}getSouth(){return this._sw.lat}getEast(){return this._ne.lng}getNorth(){return this._ne.lat}toArray(){return[this._sw.toArray(),this._ne.toArray()]}toString(){return`LngLatBounds(${this._sw.toString()}, ${this._ne.toString()})`}isEmpty(){return!(this._sw&&this._ne)}contains(l){let{lng:m,lat:T}=o.V.convert(l),P=this._sw.lng<=m&&m<=this._ne.lng;return this._sw.lng>this._ne.lng&&(P=this._sw.lng>=m&&m>=this._ne.lng),this._sw.lat<=T&&T<=this._ne.lat&&P}intersects(l){if(!((l=Ho.convert(l)).getNorth()>=this.getSouth()&&l.getSouth()<=this.getNorth()))return!1;let m=o.W(this.getWest(),-180,180),T=o.W(this.getEast(),-180,180),P=o.W(l.getWest(),-180,180),V=o.W(l.getEast(),-180,180),W=m>=T,te=P>=V;return!(!W||!te)||(W?V>=m||P<=T:te?T>=P||m<=V:P<=T&&V>=m)}static convert(l){return l instanceof Ho?l:l&&new Ho(l)}static fromLngLat(l,m=0){let T=360*m/40075017,P=T/Math.cos(Math.PI/180*l.lat);return new Ho(new o.V(l.lng-P,l.lat-T),new o.V(l.lng+P,l.lat+T))}adjustAntiMeridian(){let l=new o.V(this._sw.lng,this._sw.lat),m=new o.V(this._ne.lng,this._ne.lat);return new Ho(l,l.lng>m.lng?new o.V(m.lng+360,m.lat):m)}}class is{constructor(l,m,T){this.bounds=Ho.convert(this.validateBounds(l)),this.minzoom=m||0,this.maxzoom=T||24}validateBounds(l){return Array.isArray(l)&&l.length===4?[Math.max(-180,l[0]),Math.max(-90,l[1]),Math.min(180,l[2]),Math.min(90,l[3])]:[-180,-90,180,90]}contains(l){let m=Math.pow(2,l.z),T=Math.floor(o.Y(this.bounds.getWest())*m),P=Math.floor(o.X(this.bounds.getNorth())*m),V=Math.ceil(o.Y(this.bounds.getEast())*m),W=Math.ceil(o.X(this.bounds.getSouth())*m);return l.x>=T&&l.x=P&&l.y{this._options.tiles=l}),this}setUrl(l){return this.setSourceProperty(()=>{this.url=l,this._options.url=l}),this}onRemove(){this._tileJSONRequest&&(this._tileJSONRequest.abort(),this._tileJSONRequest=null)}serialize(){return o.e({},this._options)}loadTile(l){return o._(this,void 0,void 0,function*(){let m=l.tileID.canonical.url(this.tiles,this.map.getPixelRatio(),this.scheme),T={request:this.map._requestManager.transformRequest(m,"Tile"),uid:l.uid,tileID:l.tileID,zoom:l.tileID.overscaledZ,tileSize:this.tileSize*l.tileID.overscaleFactor(),type:this.type,source:this.id,pixelRatio:this.map.getPixelRatio(),showCollisionBoxes:this.map.showCollisionBoxes,promoteId:this.promoteId,subdivisionGranularity:this.map.style.projection.subdivisionGranularity,encoding:this.encoding,overzoomParameters:this._getOverzoomParameters(l)};T.request.collectResourceTiming=this._collectResourceTiming;let P="RT";if(l.actor&&l.state!=="expired"){if(l.state==="loading")return new Promise((V,W)=>{l.reloadPromise={resolve:V,reject:W}})}else l.actor=this.dispatcher.getActor(),P="LT";l.abortController=new AbortController;try{let V=yield l.actor.sendAsync({type:P,data:T},l.abortController);if(delete l.abortController,l.aborted)return;this._afterTileLoadWorkerResponse(l,V)}catch(V){if(delete l.abortController,l.aborted)return;if(V&&V.status!==404)throw V;this._afterTileLoadWorkerResponse(l,null)}})}_getOverzoomParameters(l){if(l.tileID.canonical.z<=this.maxzoom||this.map._zoomLevelsToOverscale===void 0)return;let m=l.tileID.scaledTo(this.maxzoom).canonical,T=m.url(this.tiles,this.map.getPixelRatio(),this.scheme);return{maxZoomTileID:m,overzoomRequest:this.map._requestManager.transformRequest(T,"Tile")}}_afterTileLoadWorkerResponse(l,m){if(m&&m.resourceTiming&&(l.resourceTiming=m.resourceTiming),m&&this.map._refreshExpiredTiles&&l.setExpiryData(m),l.loadVectorData(m,this.map.painter),l.reloadPromise){let T=l.reloadPromise;l.reloadPromise=null,this.loadTile(l).then(T.resolve).catch(T.reject)}}abortTile(l){return o._(this,void 0,void 0,function*(){l.abortController&&(l.abortController.abort(),delete l.abortController),l.actor&&(yield l.actor.sendAsync({type:"AT",data:{uid:l.uid,type:this.type,source:this.id}}))})}unloadTile(l){return o._(this,void 0,void 0,function*(){l.unloadVectorData(),l.actor&&(yield l.actor.sendAsync({type:"RMT",data:{uid:l.uid,type:this.type,source:this.id}}))})}hasTransition(){return!1}}class zs extends o.E{constructor(l,m,T,P){super(),this.id=l,this.dispatcher=T,this.setEventedParent(P),this.type="raster",this.minzoom=0,this.maxzoom=22,this.roundZoom=!0,this.scheme="xyz",this.tileSize=512,this._loaded=!1,this._options=o.e({type:"raster"},m),o.e(this,o.U(m,["url","scheme","tileSize"]))}load(){return o._(this,arguments,void 0,function*(l=!1){this._loaded=!1,this.fire(new o.l("dataloading",{dataType:"source"})),this._tileJSONRequest=new AbortController;try{let m=yield Co(this._options,this.map._requestManager,this._tileJSONRequest);this._tileJSONRequest=null,this._loaded=!0,m&&(o.e(this,m),m.bounds&&(this.tileBounds=new is(m.bounds,this.minzoom,this.maxzoom)),this.fire(new o.l("data",{dataType:"source",sourceDataType:"metadata"})),this.fire(new o.l("data",{dataType:"source",sourceDataType:"content",sourceDataChanged:l})))}catch(m){this._tileJSONRequest=null,this._loaded=!0,o.Z(m)||this.fire(new o.k(m))}})}loaded(){return this._loaded}onAdd(l){this.map=l,this.load()}onRemove(){this._tileJSONRequest&&(this._tileJSONRequest.abort(),this._tileJSONRequest=null)}setSourceProperty(l){this._tileJSONRequest&&(this._tileJSONRequest.abort(),this._tileJSONRequest=null),l(),this.load(!0)}setTiles(l){return this.setSourceProperty(()=>{this._options.tiles=l}),this}setUrl(l){return this.setSourceProperty(()=>{this.url=l,this._options.url=l}),this}serialize(){return o.e({},this._options)}hasTile(l){return!this.tileBounds||this.tileBounds.contains(l.canonical)}loadTile(l){return o._(this,void 0,void 0,function*(){let m=l.tileID.canonical.url(this.tiles,this.map.getPixelRatio(),this.scheme);l.abortController=new AbortController;try{let T=yield Oe.getImage(this.map._requestManager.transformRequest(m,"Tile"),l.abortController,this.map._refreshExpiredTiles);if(delete l.abortController,l.aborted)return void(l.state="unloaded");if(T&&T.data){this.map._refreshExpiredTiles&&(T.cacheControl||T.expires)&&l.setExpiryData({cacheControl:T.cacheControl,expires:T.expires});let P=this.map.painter.context,V=P.gl,W=T.data;l.texture=this.map.painter.getTileTexture(W.width),l.texture?l.texture.update(W,{useMipmap:!0}):(l.texture=new o.T(P,W,V.RGBA,{useMipmap:!0}),l.texture.bind(V.LINEAR,V.CLAMP_TO_EDGE,V.LINEAR_MIPMAP_NEAREST)),l.state="loaded"}}catch(T){if(delete l.abortController,l.aborted)l.state="unloaded";else if(T)throw l.state="errored",T}})}abortTile(l){return o._(this,void 0,void 0,function*(){l.abortController&&(l.abortController.abort(),delete l.abortController)})}unloadTile(l){return o._(this,void 0,void 0,function*(){l.texture&&this.map.painter.saveTileTexture(l.texture)})}hasTransition(){return!1}}class Ba extends zs{constructor(l,m,T,P){super(l,m,T,P),this.type="raster-dem",this.maxzoom=22,this._options=o.e({type:"raster-dem"},m),this.encoding=m.encoding||"mapbox",this.redFactor=m.redFactor,this.greenFactor=m.greenFactor,this.blueFactor=m.blueFactor,this.baseShift=m.baseShift}loadTile(l){return o._(this,void 0,void 0,function*(){let m=l.tileID.canonical.url(this.tiles,this.map.getPixelRatio(),this.scheme),T=this.map._requestManager.transformRequest(m,"Tile");l.neighboringTiles=this._getNeighboringTiles(l.tileID),l.abortController=new AbortController;try{let P=yield Oe.getImage(T,l.abortController,this.map._refreshExpiredTiles);if(delete l.abortController,l.aborted)return void(l.state="unloaded");if(P&&P.data){let V=P.data;this.map._refreshExpiredTiles&&(P.cacheControl||P.expires)&&l.setExpiryData({cacheControl:P.cacheControl,expires:P.expires});let W=o.b(V)&&o.$()?V:yield this.readImageNow(V),te={type:this.type,uid:l.uid,source:this.id,rawImageData:W,encoding:this.encoding,redFactor:this.redFactor,greenFactor:this.greenFactor,blueFactor:this.blueFactor,baseShift:this.baseShift};if(!l.actor||l.state==="expired"){l.actor=this.dispatcher.getActor();let se=yield l.actor.sendAsync({type:"LDT",data:te});l.dem=se,l.needsHillshadePrepare=!0,l.needsTerrainPrepare=!0,l.state="loaded"}}}catch(P){if(delete l.abortController,l.aborted)l.state="unloaded";else if(P)throw l.state="errored",P}})}readImageNow(l){return o._(this,void 0,void 0,function*(){if(typeof VideoFrame<"u"&&o.a0()){let m=l.width+2,T=l.height+2;try{return new o.R({width:m,height:T},yield o.a1(l,-1,-1,m,T))}catch{}}return I.getImageData(l,1)})}_getNeighboringTiles(l){let m=l.canonical,T=Math.pow(2,m.z),P=(m.x-1+T)%T,V=m.x===0?l.wrap-1:l.wrap,W=(m.x+1+T)%T,te=m.x+1===T?l.wrap+1:l.wrap,se={};return se[new o.a2(l.overscaledZ,V,m.z,P,m.y).key]={backfilled:!1},se[new o.a2(l.overscaledZ,te,m.z,W,m.y).key]={backfilled:!1},m.y>0&&(se[new o.a2(l.overscaledZ,V,m.z,P,m.y-1).key]={backfilled:!1},se[new o.a2(l.overscaledZ,l.wrap,m.z,m.x,m.y-1).key]={backfilled:!1},se[new o.a2(l.overscaledZ,te,m.z,W,m.y-1).key]={backfilled:!1}),m.y+1l.coordinates).flat(1/0):z.coordinates.flat(1/0)}function so(z){let l=new Ho,m;switch(z.type){case"FeatureCollection":m=z.features.map(T=>ds(T.geometry)).flat(1/0);break;case"Feature":m=ds(z.geometry);break;default:m=ds(z)}if(m.length==0)return l;for(let T=0;T0&&o.e(W,{resourceTiming:V}),this.fire(new o.l("data",Object.assign(Object.assign({},W),{sourceDataType:"metadata"}))),this.fire(new o.l("data",Object.assign(Object.assign({},W),{sourceDataType:"content",shouldReloadTileOptions:this._getShouldReloadTileOptions(m)})))}catch(P){if(this._isUpdatingWorker=!1,this._removed)return void this.fire(new o.l("dataabort",{dataType:"source"}));this.fire(new o.k(P))}finally{this._hasPendingWorkerUpdate()&&this._updateWorkerData()}})}_applyDiff(l){let m=typeof this.promoteId=="string"?this.promoteId:void 0;if(!this._data.url&&!this._data.updateable){if(!o.a7(this._data.geojson,m))throw new Error(`GeoJSONSource "${this.id}": GeoJSON data is not compatible with updateData`);this._data={updateable:o.a8(this._data.geojson,m)}}this._data.updateable&&o.a9(this._data.updateable,l,m)}_getShouldReloadTileOptions(l){if(this._options.cluster||!l||l.removeAll)return;let{add:m=[],update:T=[],remove:P=[]}=l||{},V=new Set([...T.map(W=>W.id),...P]);for(let W of V.values())if(typeof W!="number"&&this.promoteId==null)return void o.w(`GeoJSONSource "${this.id}": updateData is slower when using string GeoJSON feature IDs. Consider using promoteId or numeric IDs for better performance.`);return{nextBounds:[...T.map(W=>W.newGeometry),...m.map(W=>W.geometry)].filter(Boolean).map(W=>so(W)),prevIds:V}}shouldReloadTile(l,{nextBounds:m,prevIds:T}){if(!l.latestFeatureIndex)return l.state!=="unloaded";let P=l.latestFeatureIndex.loadVTLayers();for(let se=0;se{this.texture=null}),this):this}_finishLoading(){this.map&&(this.setCoordinates(this.coordinates),this.fire(new o.l("data",{dataType:"source",sourceDataType:"metadata"})))}onAdd(l){this.map=l,this.load()}onRemove(){this._request&&(this._request.abort(),this._request=null)}setCoordinates(l){this.coordinates=l;let m=l.map(o.ab.fromLngLat);var T;return this.tileID=function(P){let V=o.ac.fromPoints(P),W=V.width(),te=V.height(),se=Math.max(W,te),fe=Math.max(0,Math.floor(-Math.log(se)/Math.LN2)),ye=Math.pow(2,fe);return new o.ae(fe,Math.floor((V.minX+V.maxX)/2*ye),Math.floor((V.minY+V.maxY)/2*ye))}(m),this.terrainTileRanges=this._getOverlappingTileRanges(m),this.minzoom=this.maxzoom=this.tileID.z,this.tileCoords=m.map(P=>this.tileID.getTilePoint(P)._round()),this.flippedWindingOrder=((T=this.tileCoords)[1].x-T[0].x)*(T[2].y-T[0].y)-(T[1].y-T[0].y)*(T[2].x-T[0].x)<0,this.fire(new o.l("data",{dataType:"source",sourceDataType:"content"})),this}prepare(){if(Object.keys(this.tiles).length===0||!this.image)return;let l=this.map.painter.context,m=l.gl;this.texture||(this.texture=new o.T(l,this.image,m.RGBA),this.texture.bind(m.LINEAR,m.CLAMP_TO_EDGE));let T=!1;for(let P in this.tiles){let V=this.tiles[P];V.state!=="loaded"&&(V.state="loaded",V.texture=this.texture,T=!0)}T&&this.fire(new o.l("data",{dataType:"source",sourceDataType:"idle",sourceId:this.id}))}loadTile(l){return o._(this,void 0,void 0,function*(){this.tileID&&this.tileID.equals(l.tileID.canonical)?(this.tiles[String(l.tileID.wrap)]=l,l.buckets={}):l.state="errored"})}serialize(){return{type:"image",url:this.options.url,coordinates:this.coordinates}}hasTransition(){return!1}_getOverlappingTileRanges(l){let{minX:m,minY:T,maxX:P,maxY:V}=o.ac.fromPoints(l),W={};for(let te=0;te<=o.ad;te++){let se=Math.pow(2,te),fe=Math.floor(m*se),ye=Math.floor(T*se),Re=Math.floor(P*se),Me=Math.floor(V*se);W[te]={minTileX:fe,minTileY:ye,maxTileX:Re,maxTileY:Me}}return W}}class Yt extends ws{constructor(l,m,T,P){super(l,m,T,P),this.roundZoom=!0,this.type="video",this.options=m}load(){return o._(this,void 0,void 0,function*(){this._loaded=!1;let l=this.options;this.urls=[];for(let m of l.urls)this.urls.push(this.map._requestManager.transformRequest(m,"Source").url);try{let m=yield o.af(this.urls);if(this._loaded=!0,!m)return;this.video=m,this.video.loop=!0,this.video.addEventListener("playing",()=>{this.map.triggerRepaint()}),this.map&&this.video.play(),this._finishLoading()}catch(m){this.fire(new o.k(m))}})}pause(){this.video&&this.video.pause()}play(){this.video&&this.video.play()}seek(l){if(this.video){let m=this.video.seekable;lm.end(0)?this.fire(new o.k(new o.ag(`sources.${this.id}`,null,`Playback for this video can be set only between the ${m.start(0)} and ${m.end(0)}-second mark.`))):this.video.currentTime=l}}getVideo(){return this.video}onAdd(l){this.map||(this.map=l,this.load(),this.video&&(this.video.play(),this.setCoordinates(this.coordinates)))}prepare(){if(Object.keys(this.tiles).length===0||this.video.readyState<2)return;let l=this.map.painter.context,m=l.gl;this.texture?this.video.paused||(this.texture.bind(m.LINEAR,m.CLAMP_TO_EDGE),m.texSubImage2D(m.TEXTURE_2D,0,0,0,m.RGBA,m.UNSIGNED_BYTE,this.video)):(this.texture=new o.T(l,this.video,m.RGBA),this.texture.bind(m.LINEAR,m.CLAMP_TO_EDGE));let T=!1;for(let P in this.tiles){let V=this.tiles[P];V.state!=="loaded"&&(V.state="loaded",V.texture=this.texture,T=!0)}T&&this.fire(new o.l("data",{dataType:"source",sourceDataType:"idle",sourceId:this.id}))}serialize(){return{type:"video",urls:this.urls,coordinates:this.coordinates}}hasTransition(){return this.video&&!this.video.paused}}class Fe extends ws{constructor(l,m,T,P){super(l,m,T,P),m.coordinates?Array.isArray(m.coordinates)&&m.coordinates.length===4&&!m.coordinates.some(V=>!Array.isArray(V)||V.length!==2||V.some(W=>typeof W!="number"))||this.fire(new o.k(new o.ag(`sources.${l}`,null,'"coordinates" property must be an array of 4 longitude/latitude array pairs'))):this.fire(new o.k(new o.ag(`sources.${l}`,null,'missing required property "coordinates"'))),m.animate&&typeof m.animate!="boolean"&&this.fire(new o.k(new o.ag(`sources.${l}`,null,'optional "animate" property must be a boolean value'))),m.canvas?typeof m.canvas=="string"||m.canvas instanceof HTMLCanvasElement||this.fire(new o.k(new o.ag(`sources.${l}`,null,'"canvas" must be either a string representing the ID of the canvas element from which to read, or an HTMLCanvasElement instance'))):this.fire(new o.k(new o.ag(`sources.${l}`,null,'missing required property "canvas"'))),this.options=m,this.animate=m.animate===void 0||m.animate}load(){return o._(this,void 0,void 0,function*(){this._loaded=!0,this.canvas||(this.canvas=this.options.canvas instanceof HTMLCanvasElement?this.options.canvas:document.getElementById(this.options.canvas)),this.width=this.canvas.width,this.height=this.canvas.height,this._hasInvalidDimensions()?this.fire(new o.k(new Error("Canvas dimensions cannot be less than or equal to zero."))):(this.play=function(){this._playing=!0,this.map.triggerRepaint()},this.pause=function(){this._playing&&(this.prepare(),this._playing=!1)},this._finishLoading())})}getCanvas(){return this.canvas}onAdd(l){this.map=l,this.load(),this.canvas&&this.animate&&this.play()}onRemove(){this.pause()}prepare(){let l=!1;if(this.canvas.width!==this.width&&(this.width=this.canvas.width,l=!0),this.canvas.height!==this.height&&(this.height=this.canvas.height,l=!0),this._hasInvalidDimensions()||Object.keys(this.tiles).length===0)return;let m=this.map.painter.context,T=m.gl;this.texture?(l||this._playing)&&this.texture.update(this.canvas,{premultiply:!0}):(this.texture=new o.T(m,this.canvas,T.RGBA,{premultiply:!0}),this.texture.bind(T.LINEAR,T.CLAMP_TO_EDGE));let P=!1;for(let V in this.tiles){let W=this.tiles[V];W.state!=="loaded"&&(W.state="loaded",W.texture=this.texture,P=!0)}P&&this.fire(new o.l("data",{dataType:"source",sourceDataType:"idle",sourceId:this.id}))}serialize(){return{type:"canvas",animate:this.animate,canvas:this.options.canvas,coordinates:this.coordinates}}hasTransition(){return this._playing}_hasInvalidDimensions(){for(let l of[this.canvas.width,this.canvas.height])if(isNaN(l)||l<=0)return!0;return!1}}let Ne={},rt=z=>{switch(z){case"geojson":return ps;case"image":return ws;case"raster":return zs;case"raster-dem":return Ba;case"vector":return mo;case"video":return Yt;case"canvas":return Fe}return Ne[z]},Vt="RTLPluginLoaded";class Gt extends o.E{constructor(){super(...arguments),this.status="unavailable",this.url=null,this.dispatcher=mr()}_syncState(l){return this.status=l,this.dispatcher.broadcast("SRPS",{pluginStatus:l,pluginURL:this.url}).catch(m=>{throw this.status="error",m})}getRTLTextPluginStatus(){return this.status}clearRTLTextPlugin(){this.status="unavailable",this.url=null}setRTLTextPlugin(l){return o._(this,arguments,void 0,function*(m,T=!1){if(this.url)throw new Error("setRTLTextPlugin cannot be called multiple times.");if(this.url=I.resolveURL(m),!this.url)throw new Error(`requested url ${m} is invalid`);if(this.status==="unavailable"){if(!T)return this._requestImport();this.status="deferred",this._syncState(this.status)}else if(this.status==="requested")return this._requestImport()})}_requestImport(){return o._(this,void 0,void 0,function*(){yield this._syncState("loading"),this.status="loaded",this.fire(new o.l(Vt))})}lazyLoad(){this.status==="unavailable"?this.status="requested":this.status==="deferred"&&this._requestImport()}}let yr=null;function fr(){return yr||(yr=new Gt),yr}var nr,xr;(function(z){z[z.Base=0]="Base",z[z.Parent=1]="Parent"})(nr||(nr={})),function(z){z[z.Departing=0]="Departing",z[z.Incoming=1]="Incoming"}(xr||(xr={}));class ti{constructor(l,m){this.timeAdded=0,this.fadeEndTime=0,this.fadeOpacity=1,this.tileID=l,this.uid=o.ah(),this.uses=0,this.tileSize=m,this.buckets={},this.expirationTime=null,this.queryPadding=0,this.hasSymbolBuckets=!1,this.hasRTLText=!1,this.dependencies={},this.rtt=[],this.rttCoords={},this.expiredRequestCount=0,this.state="loading"}isRenderable(l){return this.hasData()&&(!this.fadeEndTime||this.fadeOpacity>0)&&(l||!this.holdingForSymbolFade())}setCrossFadeLogic({fadingRole:l,fadingDirection:m,fadingParentID:T,fadeEndTime:P}){this.resetFadeLogic(),this.fadingRole=l,this.fadingDirection=m,this.fadingParentID=T,this.fadeEndTime=P}setSelfFadeLogic(l){this.resetFadeLogic(),this.selfFading=!0,this.fadeEndTime=l}resetFadeLogic(){this.fadingRole=null,this.fadingDirection=null,this.fadingParentID=null,this.selfFading=!1,this.timeAdded=k(),this.fadeEndTime=0,this.fadeOpacity=1}wasRequested(){return this.state==="errored"||this.state==="loaded"||this.state==="reloading"}clearTextures(l){this.demTexture&&l.saveTileTexture(this.demTexture),this.demTexture=null}loadVectorData(l,m,T){if(this.hasData()&&this.unloadVectorData(),this.state="loaded",l){l.featureIndex&&(this.latestFeatureIndex=l.featureIndex,l.rawTileData?(this.latestRawTileData=l.rawTileData,this.latestFeatureIndex.rawTileData=l.rawTileData,this.latestFeatureIndex.encoding=l.encoding):this.latestRawTileData&&(this.latestFeatureIndex.rawTileData=this.latestRawTileData,this.latestFeatureIndex.encoding=this.latestEncoding)),this.collisionBoxArray=l.collisionBoxArray,this.buckets=function(P,V){let W={};if(!V)return W;for(let te of P){let se=te.layerIds.map(fe=>V.getLayer(fe)).filter(Boolean);if(se.length!==0){te.layers=se,te.stateDependentLayerIds&&(te.stateDependentLayers=te.stateDependentLayerIds.map(fe=>se.filter(ye=>ye.id===fe)[0]));for(let fe of se)W[fe.id]=te}}return W}(l.buckets,m?.style),this.hasSymbolBuckets=!1;for(let P in this.buckets){let V=this.buckets[P];if(V instanceof o.aj){if(this.hasSymbolBuckets=!0,!T)break;V.justReloaded=!0}}if(this.hasRTLText=!1,this.hasSymbolBuckets)for(let P in this.buckets){let V=this.buckets[P];if(V instanceof o.aj&&V.hasRTLText){this.hasRTLText=!0,fr().lazyLoad();break}}this.queryPadding=0;for(let P in this.buckets){let V=this.buckets[P];this.queryPadding=Math.max(this.queryPadding,m.style.getLayer(P).queryRadius(V))}l.imageAtlas&&(this.imageAtlas=l.imageAtlas),l.glyphAtlasImage&&(this.glyphAtlasImage=l.glyphAtlasImage),this.dashPositions=l.dashPositions}else this.collisionBoxArray=new o.ai}unloadVectorData(){for(let l in this.buckets)this.buckets[l].destroy();this.buckets={},this.imageAtlasTexture&&this.imageAtlasTexture.destroy(),this.imageAtlas&&(this.imageAtlas=null),this.glyphAtlasTexture&&this.glyphAtlasTexture.destroy(),this.dashPositions&&(this.dashPositions=null),this.latestFeatureIndex=null,this.state="unloaded"}getBucket(l){return this.buckets[l.id]}upload(l){for(let T in this.buckets){let P=this.buckets[T];P.uploadPending()&&P.upload(l)}let m=l.gl;this.imageAtlas&&!this.imageAtlas.uploaded&&(this.imageAtlasTexture=new o.T(l,this.imageAtlas.image,m.RGBA),this.imageAtlas.uploaded=!0),this.glyphAtlasImage&&(this.glyphAtlasTexture=new o.T(l,this.glyphAtlasImage,m.ALPHA),this.glyphAtlasImage=null)}prepare(l){this.imageAtlas&&this.imageAtlas.patchUpdatedImages(l,this.imageAtlasTexture)}queryRenderedFeatures(l,m,T,P,V,W,te,se,fe,ye,Re){return this.latestFeatureIndex&&this.latestFeatureIndex.rawTileData?this.latestFeatureIndex.query({queryGeometry:P,cameraQueryGeometry:V,scale:W,tileSize:this.tileSize,pixelPosMatrix:ye,transform:se,params:te,queryPadding:this.queryPadding*fe,getElevation:Re},l,m,T):{}}querySourceFeatures(l,m){let T=this.latestFeatureIndex;if(!T||!T.rawTileData)return;let P=T.loadVTLayers(),V=m&&m.sourceLayer?m.sourceLayer:"",W=P[o.aa]||P[V];if(!W)return;let te=o.ak(m?.filter,m?.globalState),{z:se,x:fe,y:ye}=this.tileID.canonical,Re={z:se,x:fe,y:ye};for(let Me=0;MeT)P=!1;else if(m)if(this.expirationTime({zoom:0,x:0,y:0,wrap:Xt,fullyVisible:!1}),Kt=[],It=[];if(z.renderWorldCopies&&W.allowWorldCopies())for(let Xt=1;Xt<=3;Xt++)Kt.push(Lt(-Xt)),Kt.push(Lt(Xt));for(Kt.push(Lt(0));Kt.length>0;){let Xt=Kt.pop(),Rt=Xt.x,zt=Xt.y,jt=Xt.fullyVisible,br={x:Rt,y:zt,z:Xt.zoom},Cr=W.getTileBoundingVolume(br,Xt.wrap,z.elevation,l);if(!jt){let _i=ns(m,Cr,T);if(_i===0)continue;jt=_i===2}let Rr=W.distanceToTile2d(P.x,P.y,br,Cr),Pr=se;te&&(Pr=(l.calculateTileZoom||it)(z.zoom+o.au(z.tileSize/l.tileSize),Rr,At,vt,z.fov)),Pr=(l.roundZoom?Math.round:Math.floor)(Pr),Pr=Math.max(0,Pr);let Ai=Math.min(Pr,ye);if(Xt.wrap=W.getWrap(V,br,Xt.wrap),Xt.zoom>=Ai){if(Xt.zoom>1),wrap:Xt.wrap,fullyVisible:jt})}return It.sort((Xt,Rt)=>Xt.distanceSq-Rt.distanceSq).map(Xt=>Xt.tileID)}let $t=o.ac.fromPoints([new o.P(0,0),new o.P(o.a5,o.a5)]);function Jt(z){return z==="raster"||z==="image"||z==="video"}function ht(z,l,m,T,P,V,W){if(!l.hasData())return!1;let{tileID:te,fadingRole:se,fadingDirection:fe,fadingParentID:ye}=l;if(se===nr.Base&&fe===xr.Incoming&&ye)return m[ye.key]=ye,!0;let Re=Math.max(te.overscaledZ-P,V);for(let Me=te.overscaledZ-1;Me>=Re;Me--){let je=te.scaledTo(Me),tt=z.getLoadedTile(je);if(tt)return l.setCrossFadeLogic({fadingRole:nr.Base,fadingDirection:xr.Incoming,fadingParentID:tt.tileID,fadeEndTime:T+W}),tt.setCrossFadeLogic({fadingRole:nr.Parent,fadingDirection:xr.Departing,fadeEndTime:T+W}),m[je.key]=je,!0}return!1}function Ot(z,l,m,T,P,V){if(!l.hasData())return!1;let W=l.tileID.children(P),te=Ct(z,l,W,m,T,P,V);if(te)return!0;for(let se of W)Ct(z,l,se.children(P),m,T,P,V)&&(te=!0);return te}function Ct(z,l,m,T,P,V,W){if(m[0].overscaledZ>=V)return!1;let te=!1;for(let se of m){let fe=z.getLoadedTile(se);if(!fe)continue;let{fadingRole:ye,fadingDirection:Re,fadingParentID:Me}=fe;ye===nr.Base&&Re===xr.Departing&&Me||(fe.setCrossFadeLogic({fadingRole:nr.Base,fadingDirection:xr.Departing,fadingParentID:l.tileID,fadeEndTime:P+W}),l.setCrossFadeLogic({fadingRole:nr.Parent,fadingDirection:xr.Incoming,fadeEndTime:P+W})),T[se.key]=se,te=!0}return te}function ei(z,l,m,T){let P=z.tileID;return!!z.selfFading||!z.hasData()&&!!l.has(P)&&(z.setSelfFadeLogic(m+T),!0)}function ui(z,l){var m;z.needsHillshadePrepare=!0,z.needsTerrainPrepare=!0;let T=l.tileID.canonical.x-z.tileID.canonical.x,P=l.tileID.canonical.y-z.tileID.canonical.y,V=Math.pow(2,z.tileID.canonical.z),W=l.tileID.key;T===0&&P===0||Math.abs(P)>1||(Math.abs(T)>1&&(Math.abs(T+V)===1?T+=V:Math.abs(T-V)===1&&(T-=V)),l.dem&&z.dem&&(z.dem.backfillBorder(l.dem,T,P),!((m=z.neighboringTiles)===null||m===void 0)&&m[W]&&(z.neighboringTiles[W].backfilled=!0)))}class Hr{constructor(){this._tiles={}}handleWrapJump(l){let m={};for(let T in this._tiles){let P=this._tiles[T];P.tileID=P.tileID.unwrapTo(P.tileID.wrap+l),m[P.tileID.key]=P}this._tiles=m}setFeatureState(l,m){for(let T in this._tiles)this._tiles[T].setFeatureState(l,m)}getAllTiles(){return Object.values(this._tiles)}getAllIds(l=!1){return l?Object.values(this._tiles).map(m=>m.tileID).sort(o.ax).map(m=>m.key):Object.keys(this._tiles)}getTileById(l){return this._tiles[l]}setTile(l,m){this._tiles[l]=m}deleteTileById(l){delete this._tiles[l]}getLoadedTile(l){let m=this.getTileById(l.key);return m?.hasData()?m:null}isIdRenderable(l,m=!1){var T;return(T=this.getTileById(l))===null||T===void 0?void 0:T.isRenderable(m)}getRenderableIds(l=0,m){let T=[];for(let P of this.getAllIds())this.isIdRenderable(P,m)&&T.push(this.getTileById(P));return m?T.sort((P,V)=>{let W=P.tileID,te=V.tileID,se=new o.P(W.canonical.x,W.canonical.y)._rotate(-l),fe=new o.P(te.canonical.x,te.canonical.y)._rotate(-l);return W.overscaledZ-te.overscaledZ||fe.y-se.y||fe.x-se.x}).map(P=>P.tileID.key):T.map(P=>P.tileID).sort(o.ax).map(P=>P.key)}}class si extends o.E{constructor(l,m,T){super(),this.id=l,this.dispatcher=T,this.on("data",P=>this._dataHandler(P)),this.on("dataloading",()=>{this._sourceErrored=!1}),this.on("error",()=>{this._sourceErrored=this._source.loaded()}),this._source=((P,V,W,te)=>{let se=new(rt(V.type))(P,V,W,te);if(se.id!==P)throw new Error(`Expected Source id to be ${P} instead of ${se.id}`);return se})(l,m,T,this),this._inViewTiles=new Hr,this._outOfViewCache=new o.ay(0,P=>this._unloadTile(P)),this._timers={},this._maxTileCacheSize=null,this._maxTileCacheZoomLevels=null,this._rasterFadeDuration=0,this._maxFadingAncestorLevels=5,this._state=new Jr,this._didEmitContent=!1,this._updated=!1}onAdd(l){this.map=l,this._maxTileCacheSize=l?l._maxTileCacheSize:null,this._maxTileCacheZoomLevels=l?l._maxTileCacheZoomLevels:null,this._source&&this._source.onAdd&&this._source.onAdd(l)}onRemove(l){for(let m of this._inViewTiles.getAllTiles())m.unloadVectorData();this.clearTiles(),this._source&&this._source.onRemove&&this._source.onRemove(l),this._inViewTiles=new Hr}loaded(){if(this._sourceErrored)return!0;if(!this._sourceLoaded||!this._source.loaded())return!1;if(!(this.used===void 0&&this.usedForTerrain===void 0||this.used||this.usedForTerrain))return!0;if(!this._updated)return!1;for(let l of this._inViewTiles.getAllTiles())if(l.state!=="loaded"&&l.state!=="errored")return!1;return!0}getSource(){return this._source}getState(){return this._state}pause(){this._paused=!0}resume(){if(!this._paused)return;let l=this._shouldReloadOnResume;this._paused=!1,this._shouldReloadOnResume=!1,l&&this.reload(),this.transform&&this.update(this.transform,this.terrain)}_loadTile(l,m,T){return o._(this,void 0,void 0,function*(){try{yield this._source.loadTile(l),this._tileLoaded(l,m,T)}catch(P){l.state="errored",P.status!==404?this._source.fire(new o.k(P,{tile:l})):this.update(this.transform,this.terrain)}})}_unloadTile(l){this._source.unloadTile&&this._source.unloadTile(l)}_abortTile(l){this._source.abortTile&&this._source.abortTile(l),this._source.fire(new o.l("dataabort",{tile:l,coord:l.tileID,dataType:"source"}))}serialize(){return this._source.serialize()}prepare(l){this._source.prepare&&this._source.prepare(),this._state.coalesceChanges(this._inViewTiles,this.map?this.map.painter:null);for(let m of this._inViewTiles.getAllTiles())m.upload(l),m.prepare(this.map.style.imageManager)}getIds(){return this._inViewTiles.getAllIds(!0)}getRenderableIds(l){var m;return this._inViewTiles.getRenderableIds((m=this.transform)===null||m===void 0?void 0:m.bearingInRadians,l)}hasRenderableParent(l){let m=l.overscaledZ-1;if(m>=this._source.minzoom){let T=this.getLoadedTile(l.scaledTo(m));if(T)return this._inViewTiles.isIdRenderable(T.tileID.key)}return!1}reload(l,m=void 0){if(this._paused)this._shouldReloadOnResume=!0;else{this._outOfViewCache.reset();for(let T of this._inViewTiles.getAllIds()){let P=this._inViewTiles.getTileById(T);m&&!this._source.shouldReloadTile(P,m)||(l?this._reloadTile(T,"expired"):P.state!=="errored"&&this._reloadTile(T,"reloading"))}}}_reloadTile(l,m){return o._(this,void 0,void 0,function*(){let T=this._inViewTiles.getTileById(l);T&&(T.state!=="loading"&&(T.state=m),yield this._loadTile(T,l,m))})}_tileLoaded(l,m,T){l.timeAdded=k(),l.selfFading&&(l.fadeEndTime=l.timeAdded+this._rasterFadeDuration),T==="expired"&&(l.refreshedUponExpiration=!0),this._setTileReloadTimer(m,l),this.getSource().type==="raster-dem"&&l.dem&&function(P,V){var W,te;let se=V.getRenderableIds();for(let fe of se){if(!P.neighboringTiles||!P.neighboringTiles[fe])continue;let ye=V.getTileById(fe);P.neighboringTiles[fe].backfilled||ui(P,ye),!((te=(W=ye.neighboringTiles)===null||W===void 0?void 0:W[P.tileID.key])===null||te===void 0)&&te.backfilled||ui(ye,P)}}(l,this._inViewTiles),this._state.initializeTileState(l,this.map?this.map.painter:null),l.aborted||this._source.fire(new o.l("data",{dataType:"source",tile:l,coord:l.tileID}))}getTile(l){return this.getTileByID(l.key)}getTileByID(l){return this._inViewTiles.getTileById(l)}_retainLoadedChildren(l,m){let T=this._getLoadedDescendents(m),P=new Set;for(let V of m){let W=T[V.key];if(!W?.length){P.add(V);continue}let te=V.overscaledZ+si.maxOverzooming,se=W.filter(Re=>Re.tileID.overscaledZ<=te);if(!se.length){P.add(V);continue}let fe=Math.min(...se.map(Re=>Re.tileID.overscaledZ)),ye=se.filter(Re=>Re.tileID.overscaledZ===fe).map(Re=>Re.tileID);for(let Re of ye)l[Re.key]=Re;this._areDescendentsComplete(ye,fe,V.overscaledZ)||P.add(V)}return P}_getLoadedDescendents(l){var m;let T={};for(let P of this._inViewTiles.getAllTiles().filter(V=>V.hasData()))for(let V of l)P.tileID.isChildOf(V)&&(T[m=V.key]||(T[m]=[])).push(P);return T}_areDescendentsComplete(l,m,T){return l.length===1&&l[0].isOverscaled()?l[0].overscaledZ===m:Math.pow(4,m-T)===l.length}getLoadedTile(l){return this._inViewTiles.getLoadedTile(l)}updateCacheSize(l){let m=Math.ceil(l.width/this._source.tileSize)+1,T=Math.ceil(l.height/this._source.tileSize)+1,P=Math.floor(m*T*(this._maxTileCacheZoomLevels===null?o.c.MAX_TILE_CACHE_ZOOM_LEVELS:this._maxTileCacheZoomLevels)),V=typeof this._maxTileCacheSize=="number"?Math.min(this._maxTileCacheSize,P):P;this._outOfViewCache.setMaxSize(V)}handleWrapJump(l){let m=Math.round((l-(this._prevLng===void 0?l:this._prevLng))/360);this._prevLng=l,m&&(this._inViewTiles.handleWrapJump(m),this._resetTileReloadTimers())}update(l,m){if(!this._sourceLoaded||this._paused)return;let T;this.transform=l,this.terrain=m,this.updateCacheSize(l),this.handleWrapJump(this.transform.center.lng),this.used||this.usedForTerrain?this._source.tileID?T=l.getVisibleUnwrappedCoordinates(this._source.tileID).map(se=>new o.a2(se.canonical.z,se.wrap,se.canonical.z,se.canonical.x,se.canonical.y)):(T=Qe(l,{tileSize:this.usedForTerrain?this.tileSize:this._source.tileSize,minzoom:this._source.minzoom,maxzoom:this._source.type==="vector"&&this.map._zoomLevelsToOverscale!==void 0?l.maxZoom-this.map._zoomLevelsToOverscale:this._source.maxzoom,roundZoom:!this.usedForTerrain&&this._source.roundZoom,reparseOverscaled:this._source.reparseOverscaled,terrain:m,calculateTileZoom:this._source.calculateTileZoom}),this._source.hasTile&&(T=T.filter(se=>this._source.hasTile(se)))):T=[],this.usedForTerrain&&(T=this._addTerrainIdealTiles(T));let P=T.length===0&&!this._updated&&this._didEmitContent;this._updated=!0,P&&this.fire(new o.l("data",{sourceDataType:"idle",dataType:"source",sourceId:this.id}));let V=mt(l,this._source),W=this._updateRetainedTiles(T,V),te=Jt(this._source.type);te&&this._rasterFadeDuration>0&&!m&&function(se,fe,ye,Re,Me,je,tt){let yt=k(),At=o.aw(fe);for(let vt of fe){let Lt=se.getTileById(vt.key);Lt.fadingDirection!==xr.Departing&&Lt.fadeOpacity!==0||Lt.resetFadeLogic(),ht(se,Lt,ye,yt,Re,Me,tt)||Ot(se,Lt,ye,yt,je,tt)||ei(Lt,At,yt,tt)||Lt.resetFadeLogic()}}(this._inViewTiles,T,W,this._maxFadingAncestorLevels,this._source.minzoom,this._source.maxzoom,this._rasterFadeDuration),te?this._cleanUpRasterTiles(W):this._cleanUpVectorTiles(W)}_cleanUpRasterTiles(l){for(let m of this._inViewTiles.getAllIds())l[m]||this._removeTile(m)}_cleanUpVectorTiles(l){for(let m of this._inViewTiles.getAllIds()){let T=this._inViewTiles.getTileById(m);l[m]?T.clearSymbolFadeHold():T.hasSymbolBuckets?T.holdingForSymbolFade()?T.symbolFadeFinished()&&this._removeTile(m):T.setSymbolHoldDuration(this.map._fadeDuration):this._removeTile(m)}}_addTerrainIdealTiles(l){let m=[];for(let T of l)if(T.canonical.z>this._source.minzoom){let P=T.scaledTo(T.canonical.z-1);m.push(P);let V=T.scaledTo(Math.max(this._source.minzoom,Math.min(T.canonical.z,5)));m.push(V)}return l.concat(m)}releaseSymbolFadeTiles(){for(let l of this._inViewTiles.getAllIds())this._inViewTiles.getTileById(l).holdingForSymbolFade()&&this._removeTile(l)}_updateRetainedTiles(l,m){var T;let P=new Set;for(let fe of l)this._addTile(fe).hasData()||P.add(fe);let V=l.reduce((fe,ye)=>(fe[ye.key]=ye,fe),{}),W=this._retainLoadedChildren(V,P),te={},se=Math.max(m-si.maxUnderzooming,this._source.minzoom);for(let fe of W){let ye=this._inViewTiles.getTileById(fe.key),Re=ye?.wasRequested();for(let Me=fe.overscaledZ-1;Me>=se;--Me){let je=fe.scaledTo(Me);if(te[je.key])break;if(te[je.key]=!0,ye=this.getTile(je),!ye&&Re&&(ye=this._addTile(je)),ye){let tt=ye.hasData();if((tt||!(!((T=this.map)===null||T===void 0)&&T.cancelPendingTileRequestsWhileZooming)||Re)&&(V[je.key]=je),Re=ye.wasRequested(),tt)break}}}return V}_addTile(l){let m=this._inViewTiles.getTileById(l.key);if(m)return m;m=this._outOfViewCache.getAndRemove(l),m&&(m.resetFadeLogic(),this._setTileReloadTimer(l.key,m),m.tileID=l,this._state.initializeTileState(m,this.map?this.map.painter:null));let T=m;return m||(m=new ti(l,this._source.tileSize*l.overscaleFactor()),this._loadTile(m,l.key,m.state)),m.uses++,this._inViewTiles.setTile(l.key,m),T||this._source.fire(new o.l("dataloading",{tile:m,coord:m.tileID,dataType:"source"})),m}_setTileReloadTimer(l,m){this._clearTileReloadTimer(l);let T=m.getExpiryTimeout();T&&(this._timers[l]=setTimeout(()=>{this._reloadTile(l,"expired"),delete this._timers[l]},T))}_clearTileReloadTimer(l){let m=this._timers[l];m&&(clearTimeout(m),delete this._timers[l])}_resetTileReloadTimers(){for(let l in this._timers)clearTimeout(this._timers[l]),delete this._timers[l];for(let l of this._inViewTiles.getAllIds()){let m=this._inViewTiles.getTileById(l);this._setTileReloadTimer(l,m)}}refreshTiles(l){for(let m of this._inViewTiles.getAllIds()){let T=this._inViewTiles.getTileById(m);(this._inViewTiles.isIdRenderable(m)||T.state=="errored")&&l.some(P=>P.equals(T.tileID.canonical))&&this._reloadTile(m,"expired")}}_removeTile(l){let m=this._inViewTiles.getTileById(l);m&&(m.uses--,this._inViewTiles.deleteTileById(l),this._clearTileReloadTimer(l),m.uses>0||(m.hasData()&&m.state!=="reloading"?this._outOfViewCache.add(m.tileID,m,m.getExpiryTimeout()):(m.aborted=!0,this._abortTile(m),this._unloadTile(m))))}_dataHandler(l){l.dataType==="source"&&(l.sourceDataType!=="metadata"?l.sourceDataType==="content"&&this._sourceLoaded&&!this._paused&&(this.reload(l.sourceDataChanged,l.shouldReloadTileOptions),this.transform&&this.update(this.transform,this.terrain),this._didEmitContent=!0):this._sourceLoaded=!0)}clearTiles(){this._shouldReloadOnResume=!1,this._paused=!1;for(let l of this._inViewTiles.getAllIds())this._removeTile(l);this._outOfViewCache.reset()}tilesIn(l,m,T){let P=[],V=this.transform;if(!V)return P;let W=V.getCoveringTilesDetailsProvider().allowWorldCopies(),te=T?V.getCameraQueryGeometry(l):l,se=je=>V.screenPointToMercatorCoordinate(je,this.terrain),fe=this.transformBbox(l,se,!W),ye=this.transformBbox(te,se,!W),Re=this.getIds(),Me=o.ac.fromPoints(ye);for(let je=0;jeLt.getTilePoint(new o.ab(It.x,It.y)));if(Kt.expandBy(vt),Kt.intersects($t)){let It=fe.map(Rt=>Lt.getTilePoint(Rt)),Xt=ye.map(Rt=>Lt.getTilePoint(Rt));P.push({tile:tt,tileID:W?Lt:Lt.unwrapTo(0),queryGeometry:It,cameraQueryGeometry:Xt,scale:At})}}}return P}transformBbox(l,m,T){let P=l.map(m);if(T){let V=o.ac.fromPoints(l);V.shrinkBy(.001*Math.min(V.width(),V.height()));let W=V.map(m);o.ac.fromPoints(P).covers(W)||(P=P.map(te=>te.x>.5?new o.ab(te.x-1,te.y,te.z):te))}return P}getVisibleCoordinates(l){let m=this.getRenderableIds(l).map(T=>this._inViewTiles.getTileById(T).tileID);return this.transform&&this.transform.populateCache(m),m}hasTransition(){return!!this._source.hasTransition()||!(!Jt(this._source.type)||!function(l,m){if(m<=0)return!1;let T=k();for(let P of l.getAllTiles())if(P.fadeEndTime>=T)return!0;return!1}(this._inViewTiles,this._rasterFadeDuration))}setRasterFadeDuration(l){this._rasterFadeDuration=l}setFeatureState(l,m,T){this._state.updateState(l=l||o.aa,m,T)}removeFeatureState(l,m,T){this._state.removeFeatureState(l=l||o.aa,m,T)}getFeatureState(l,m){return this._state.getState(l=l||o.aa,m)}setDependencies(l,m,T){let P=this._inViewTiles.getTileById(l);P&&P.setDependencies(m,T)}reloadTilesForDependencies(l,m){for(let T of this._inViewTiles.getAllIds())this._inViewTiles.getTileById(T).hasDependency(l,m)&&this._reloadTile(T,"reloading");this._outOfViewCache.filter(T=>!T.hasDependency(l,m))}areTilesLoaded(){for(let l of this._inViewTiles.getAllTiles())if(l.state!=="loaded"&&l.state!=="errored")return!1;return!0}}si.maxUnderzooming=10,si.maxOverzooming=3;class Or{constructor(l,m){this.reset(l,m)}reset(l,m){this.points=l||[],this._distances=[0];for(let T=1;T0?(P-W)/te:0;return this.points[V].mult(1-se).add(this.points[m].mult(se))}}function fi(z,l){let m=!0;return z==="always"||z!=="never"&&l!=="never"||(m=!1),m}class pr{constructor(l,m,T){let P=this.boxCells=[],V=this.circleCells=[];this.xCellCount=Math.ceil(l/T),this.yCellCount=Math.ceil(m/T);for(let W=0;Wthis.width||P<0||m>this.height)return[];let se=[];if(l<=0&&m<=0&&this.width<=T&&this.height<=P){if(V)return[{key:null,x1:l,y1:m,x2:T,y2:P}];for(let fe=0;fe0}hitTestCircle(l,m,T,P,V){let W=l-T,te=l+T,se=m-T,fe=m+T;if(te<0||W>this.width||fe<0||se>this.height)return!1;let ye=[];return this._forEachCell(W,se,te,fe,this._queryCellCircle,ye,{hitTest:!0,overlapMode:P,circle:{x:l,y:m,radius:T},seenUids:{box:{},circle:{}}},V),ye.length>0}_queryCell(l,m,T,P,V,W,te,se){let{seenUids:fe,hitTest:ye,overlapMode:Re}=te,Me=this.boxCells[V];if(Me!==null){let tt=this.bboxes;for(let yt of Me)if(!fe.box[yt]){fe.box[yt]=!0;let At=4*yt,vt=this.boxKeys[yt];if(l<=tt[At+2]&&m<=tt[At+3]&&T>=tt[At+0]&&P>=tt[At+1]&&(!se||se(vt))&&(!ye||!fi(Re,vt.overlapMode))&&(W.push({key:vt,x1:tt[At],y1:tt[At+1],x2:tt[At+2],y2:tt[At+3]}),ye))return!0}}let je=this.circleCells[V];if(je!==null){let tt=this.circles;for(let yt of je)if(!fe.circle[yt]){fe.circle[yt]=!0;let At=3*yt,vt=this.circleKeys[yt];if(this._circleAndRectCollide(tt[At],tt[At+1],tt[At+2],l,m,T,P)&&(!se||se(vt))&&(!ye||!fi(Re,vt.overlapMode))){let Lt=tt[At],Kt=tt[At+1],It=tt[At+2];if(W.push({key:vt,x1:Lt-It,y1:Kt-It,x2:Lt+It,y2:Kt+It}),ye)return!0}}}return!1}_queryCellCircle(l,m,T,P,V,W,te,se){let{circle:fe,seenUids:ye,overlapMode:Re}=te,Me=this.boxCells[V];if(Me!==null){let tt=this.bboxes;for(let yt of Me)if(!ye.box[yt]){ye.box[yt]=!0;let At=4*yt,vt=this.boxKeys[yt];if(this._circleAndRectCollide(fe.x,fe.y,fe.radius,tt[At+0],tt[At+1],tt[At+2],tt[At+3])&&(!se||se(vt))&&!fi(Re,vt.overlapMode))return W.push(!0),!0}}let je=this.circleCells[V];if(je!==null){let tt=this.circles;for(let yt of je)if(!ye.circle[yt]){ye.circle[yt]=!0;let At=3*yt,vt=this.circleKeys[yt];if(this._circlesCollide(tt[At],tt[At+1],tt[At+2],fe.x,fe.y,fe.radius)&&(!se||se(vt))&&!fi(Re,vt.overlapMode))return W.push(!0),!0}}}_forEachCell(l,m,T,P,V,W,te,se){let fe=this._convertToXCellCoord(l),ye=this._convertToYCellCoord(m),Re=this._convertToXCellCoord(T),Me=this._convertToYCellCoord(P);for(let je=fe;je<=Re;je++)for(let tt=ye;tt<=Me;tt++)if(V.call(this,l,m,T,P,this.xCellCount*tt+je,W,te,se))return}_convertToXCellCoord(l){return Math.max(0,Math.min(this.xCellCount-1,Math.floor(l*this.xScale)))}_convertToYCellCoord(l){return Math.max(0,Math.min(this.yCellCount-1,Math.floor(l*this.yScale)))}_circlesCollide(l,m,T,P,V,W){let te=P-l,se=V-m,fe=T+W;return fe*fe>te*te+se*se}_circleAndRectCollide(l,m,T,P,V,W,te){let se=(W-P)/2,fe=Math.abs(l-(P+se));if(fe>se+T)return!1;let ye=(te-V)/2,Re=Math.abs(m-(V+ye));if(Re>ye+T)return!1;if(fe<=se||Re<=ye)return!0;let Me=fe-se,je=Re-ye;return Me*Me+je*je<=T*T}}function Di(z,l,m){let T=o.N();if(!z){let{vecSouth:Re,vecEast:Me}=Mi(l),je=c();je[0]=Me[0],je[1]=Me[1],je[2]=Re[0],je[3]=Re[1],P=je,(ye=(W=(V=je)[0])*(fe=V[3])-(se=V[2])*(te=V[1]))&&(P[0]=fe*(ye=1/ye),P[1]=-te*ye,P[2]=-se*ye,P[3]=W*ye),T[0]=je[0],T[1]=je[1],T[4]=je[2],T[5]=je[3]}var P,V,W,te,se,fe,ye;return o.Q(T,T,[1/m,1/m,1]),T}function Ii(z,l,m,T){if(z){let P=o.N();if(!l){let{vecSouth:V,vecEast:W}=Mi(m);P[0]=W[0],P[1]=W[1],P[4]=V[0],P[5]=V[1]}return o.Q(P,P,[T,T,1]),P}return m.pixelsToClipSpaceMatrix}function Mi(z){let l=Math.cos(z.rollInRadians),m=Math.sin(z.rollInRadians),T=Math.cos(z.pitchInRadians),P=Math.cos(z.bearingInRadians),V=Math.sin(z.bearingInRadians),W=o.aD();W[0]=-P*T*m-V*l,W[1]=-V*T*m+P*l;let te=o.aE(W);te<1e-9?o.aF(W):o.aG(W,W,1/te);let se=o.aD();se[0]=P*T*l-V*m,se[1]=V*T*l+P*m;let fe=o.aE(se);return fe<1e-9?o.aF(se):o.aG(se,se,1/fe),{vecEast:se,vecSouth:W}}function Ni(z,l,m,T){let P;T?(P=[z,l,T(z,l),1],o.aI(P,P,m)):(P=[z,l,0,1],md(P,P,m));let V=P[3];return{point:new o.P(P[0]/V,P[1]/V),signedDistanceFromCamera:V,isOccluded:!1}}function zi(z,l){return .5+z/l*.5}function po(z,l){return z.x>=-l[0]&&z.x<=l[0]&&z.y>=-l[1]&&z.y<=l[1]}function Ls(z,l,m,T,P,V,W,te,se,fe,ye,Re,Me){let je=m?z.textSizeData:z.iconSizeData,tt=o.az(je,l.transform.zoom),yt=[256/l.width*2+1,256/l.height*2+1],At=m?z.text.dynamicLayoutVertexArray:z.icon.dynamicLayoutVertexArray;At.clear();let vt=z.lineVertexArray,Lt=m?z.text.placedSymbolArray:z.icon.placedSymbolArray,Kt=l.transform.width/l.transform.height,It=!1;for(let Xt=0;XtMath.abs(m.x-l.x)*T?{useVertical:!0}:(z===o.aA.vertical?l.ym.x)?{needsFlipping:!0}:null}function wo(z){let{projectionContext:l,pitchedLabelPlaneMatrixInverse:m,symbol:T,fontSize:P,flip:V,keepUpright:W,glyphOffsetArray:te,dynamicLayoutVertexArray:se,aspectRatio:fe,rotateToLine:ye}=z,Re=P/24,Me=T.lineOffsetX*Re,je=T.lineOffsetY*Re,tt;if(T.numGlyphs>1){let yt=T.glyphStartIndex+T.numGlyphs,At=T.lineStartIndex,vt=T.lineStartIndex+T.lineLength,Lt=co(Re,te,Me,je,V,T,ye,l);if(!Lt)return{notEnoughRoom:!0};let Kt=Ds(Lt.first.point.x,Lt.first.point.y,l,m),It=Ds(Lt.last.point.x,Lt.last.point.y,l,m);if(W&&!V){let Xt=No(T.writingMode,Kt,It,fe);if(Xt)return Xt}tt=[Lt.first];for(let Xt=T.glyphStartIndex+1;Xt0?Kt.point:Al(l.tileAnchorPoint,Lt,At,1,l),Xt=Ds(At.x,At.y,l,m),Rt=Ds(It.x,It.y,l,m),zt=No(T.writingMode,Xt,Rt,fe);if(zt)return zt}let yt=zc(Re*te.getoffsetX(T.glyphStartIndex),Me,je,V,T.segment,T.lineStartIndex,T.lineStartIndex+T.lineLength,l,ye);if(!yt||l.projectionCache.anyProjectionOccluded)return{notEnoughRoom:!0};tt=[yt]}for(let yt of tt)o.aH(se,yt.point,yt.angle);return{}}function Al(z,l,m,T,P){let V=z.add(z.sub(l)._unit()),W=Qn(V.x,V.y,P).point,te=m.sub(W);return m.add(te._mult(T/te.mag()))}function uo(z,l,m){let T=l.projectionCache;if(T.projections[z])return T.projections[z];let P=new o.P(l.lineVertexArray.getx(z),l.lineVertexArray.gety(z)),V=Qn(P.x,P.y,l);if(V.signedDistanceFromCamera>0)return T.projections[z]=V.point,T.anyProjectionOccluded=T.anyProjectionOccluded||V.isOccluded,V.point;let W=z-m.direction;return Al(m.distanceFromAnchor===0?l.tileAnchorPoint:new o.P(l.lineVertexArray.getx(W),l.lineVertexArray.gety(W)),P,m.previousVertex,m.absOffsetX-m.distanceFromAnchor+1,l)}function Qn(z,l,m){let T=z+m.translation[0],P=l+m.translation[1],V;return m.pitchWithMap?(V=Ni(T,P,m.pitchedLabelPlaneMatrix,m.getElevation),V.isOccluded=!1):(V=m.transform.projectTileCoordinates(T,P,m.unwrappedTileID,m.getElevation),V.point.x=(.5*V.point.x+.5)*m.width,V.point.y=(.5*-V.point.y+.5)*m.height),V}function Ds(z,l,m,T){if(m.pitchWithMap){let P=[z,l,0,1];return o.aI(P,P,T),m.transform.projectTileCoordinates(P[0]/P[3],P[1]/P[3],m.unwrappedTileID,m.getElevation).point}return{x:z/m.width*2-1,y:1-l/m.height*2}}function ho(z,l,m){return m.transform.projectTileCoordinates(z,l,m.unwrappedTileID,m.getElevation)}function cs(z,l,m){return z._unit()._perp()._mult(l*m)}function _l(z,l,m,T,P,V,W,te,se){if(te.projectionCache.offsets[z])return te.projectionCache.offsets[z];let fe=m.add(l);if(z+se.direction=P)return te.projectionCache.offsets[z]=fe,fe;let ye=uo(z+se.direction,te,se),Re=cs(ye.sub(m),W,se.direction),Me=m.add(Re),je=ye.add(Re);return te.projectionCache.offsets[z]=o.aJ(V,fe,Me,je)||fe,te.projectionCache.offsets[z]}function zc(z,l,m,T,P,V,W,te,se){let fe=T?z-l:z+l,ye=fe>0?1:-1,Re=0;T&&(ye*=-1,Re=Math.PI),ye<0&&(Re+=Math.PI);let Me,je=ye>0?V+P:V+P+1;te.projectionCache.cachedAnchorPoint?Me=te.projectionCache.cachedAnchorPoint:(Me=Qn(te.tileAnchorPoint.x,te.tileAnchorPoint.y,te).point,te.projectionCache.cachedAnchorPoint=Me);let tt,yt,At=Me,vt=Me,Lt=0,Kt=0,It=Math.abs(fe),Xt=[],Rt;for(;Lt+Kt<=It;){if(je+=ye,je=W)return null;Lt+=Kt,vt=At,yt=tt;let br={absOffsetX:It,direction:ye,distanceFromAnchor:Lt,previousVertex:vt};if(At=uo(je,te,br),m===0)Xt.push(vt),Rt=At.sub(vt);else{let Cr,Rr=At.sub(vt);Cr=Rr.mag()===0?cs(uo(je+ye,te,br).sub(At),m,ye):cs(Rr,m,ye),yt||(yt=vt.add(Cr)),tt=_l(je,Cr,At,V,W,yt,m,te,br),Xt.push(yt),Rt=tt.sub(yt)}Kt=Rt.mag()}let zt=Rt._mult((It-Lt)/Kt)._add(yt||vt),jt=Re+Math.atan2(At.y-vt.y,At.x-vt.x);return Xt.push(zt),{point:zt,angle:se?jt:0,path:Xt}}let yl=new Float32Array([-1/0,-1/0,0,-1/0,-1/0,0,-1/0,-1/0,0,-1/0,-1/0,0]);function Ya(z,l){for(let m=0;m=1;fo--)_i.push(Pr.path[fo]);for(let fo=1;fo$r.signedDistanceFromCamera<=0)?[]:fo.map($r=>$r.point)}let hn=[];if(_i.length>0){let fo=_i[0].clone(),$r=_i[0].clone();for(let di=1;di<_i.length;di++)fo.x=Math.min(fo.x,_i[di].x),fo.y=Math.min(fo.y,_i[di].y),$r.x=Math.max($r.x,_i[di].x),$r.y=Math.max($r.y,_i[di].y);hn=fo.x>=br.x&&$r.x<=Cr.x&&fo.y>=br.y&&$r.y<=Cr.y?[_i]:$r.xCr.x||$r.yCr.y?[]:o.aK([_i],br.x,br.y,Cr.x,Cr.y)}for(let fo of hn){Rr.reset(fo,.25*jt);let $r=0;$r=Rr.length<=.5*jt?1:Math.ceil(Rr.paddedLength/hi)+1;for(let di=0;di<$r;di++){let oa=di/Math.max($r-1,1),Ja=Rr.lerp(oa),ya=Ja.x+os,jl=Ja.y+os;yt.push(ya,jl,jt,0);let qs=ya-jt,Wa=jl-jt,Hl=ya+jt,Ea=jl+jt;if(zt=zt&&this.isOffscreen(qs,Wa,Hl,Ea),Rt=Rt||this.isInsideGrid(qs,Wa,Hl,Ea),l!=="always"&&this.grid.hitTestCircle(ya,jl,jt,l,ye)&&(Xt=!0,!se))return{circles:[],offscreen:!1,collisionDetected:Xt}}}}return{circles:!se&&Xt||!Rt||vt{let se=Ni(te.x,te.y,W,V.getElevation),fe=V.transform.projectTileCoordinates(se.point.x,se.point.y,V.unwrappedTileID,V.getElevation);return fe.point.x=(.5*fe.point.x+.5)*V.width,fe.point.y=(.5*-fe.point.y+.5)*V.height,fe})}(l,m);return function(P){let V=0,W=0,te=0,se=0;for(let fe=0;feW&&(W=se,V=te));return P.slice(V,V+W)}(T)}queryRenderedSymbols(l){if(l.length===0||this.grid.keysLength()===0&&this.ignoredGrid.keysLength()===0)return{};let m=[],T=new o.ac;for(let Re of l){let Me=new o.P(Re.x+os,Re.y+os);T.extend(Me),m.push(Me)}let{minX:P,minY:V,maxX:W,maxY:te}=T,se=this.grid.query(P,V,W,te).concat(this.ignoredGrid.query(P,V,W,te)),fe={},ye={};for(let Re of se){let Me=Re.key;if(fe[Me.bucketInstanceId]===void 0&&(fe[Me.bucketInstanceId]={}),fe[Me.bucketInstanceId][Me.featureIndex])continue;let je=[new o.P(Re.x1,Re.y1),new o.P(Re.x2,Re.y1),new o.P(Re.x2,Re.y2),new o.P(Re.x1,Re.y2)];o.aL(m,je)&&(fe[Me.bucketInstanceId][Me.featureIndex]=!0,ye[Me.bucketInstanceId]===void 0&&(ye[Me.bucketInstanceId]=[]),ye[Me.bucketInstanceId].push(Me.featureIndex))}return ye}insertCollisionBox(l,m,T,P,V,W){(T?this.ignoredGrid:this.grid).insert({bucketInstanceId:P,featureIndex:V,collisionGroupID:W,overlapMode:m},l[0],l[1],l[2],l[3])}insertCollisionCircles(l,m,T,P,V,W){let te=T?this.ignoredGrid:this.grid,se={bucketInstanceId:P,featureIndex:V,collisionGroupID:W,overlapMode:m};for(let fe=0;fe=this.screenRightBoundary||Pthis.screenBottomBoundary}isInsideGrid(l,m,T,P){return T>=0&&l=0&&mthis.projectAndGetPerspectiveRatio(hi.x,hi.y,P,fe,Re));Ai=_i.some(hi=>!hi.isOccluded),Pr=_i.map(hi=>new o.P(hi.x,hi.y))}else Ai=!0;return{box:o.aM(Pr),allPointsOccluded:!Ai}}}class mf{constructor(l,m,T,P){this.opacity=l?Math.max(0,Math.min(1,l.opacity+(l.placed?m:-m))):P&&T?1:0,this.placed=T}isHidden(){return this.opacity===0&&!this.placed}}class Ll{constructor(l,m,T,P,V){this.text=new mf(l?l.text:null,m,T,V),this.icon=new mf(l?l.icon:null,m,P,V)}isHidden(){return this.text.isHidden()&&this.icon.isHidden()}}class Dl{constructor(l,m,T){this.text=l,this.icon=m,this.skipFade=T}}class eu{constructor(l,m,T,P,V){this.bucketInstanceId=l,this.featureIndex=m,this.sourceLayerIndex=T,this.bucketIndex=P,this.tileID=V}}class ua{constructor(l){this.crossSourceCollisions=l,this.maxGroupID=0,this.collisionGroups={}}get(l){if(this.crossSourceCollisions)return{ID:0,predicate:null};if(!this.collisionGroups[l]){let m=++this.maxGroupID;this.collisionGroups[l]={ID:m,predicate:T=>T.collisionGroupID===m}}return this.collisionGroups[l]}}function Tc(z,l,m,T,P){let{horizontalAlign:V,verticalAlign:W}=o.aT(z);return new o.P(-(V-.5)*l+T[0]*P,-(W-.5)*m+T[1]*P)}class Uc{constructor(l,m,T,P,V){this.transform=l.clone(),this.terrain=m,this.collisionIndex=new ca(this.transform),this.placements={},this.opacities={},this.variableOffsets={},this.stale=!1,this.commitTime=0,this.fadeDuration=T,this.retainedQueryData={},this.collisionGroups=new ua(P),this.collisionCircleArrays={},this.collisionBoxArrays=new Map,this.prevPlacement=V,V&&(V.prevPlacement=void 0),this.placedOrientations={}}_getTerrainElevationFunc(l){let m=this.terrain;return m?(T,P)=>m.getElevation(l,T,P):null}getBucketParts(l,m,T,P){let V=T.getBucket(m),W=T.latestFeatureIndex;if(!V||!W||m.id!==V.layerIds[0])return;let te=T.collisionBoxArray,se=V.layers[0].layout,fe=V.layers[0].paint,ye=Math.pow(2,this.transform.zoom-T.tileID.overscaledZ),Re=T.tileSize/o.a5,Me=T.tileID.toUnwrapped(),je=se.get("text-rotation-alignment")==="map",tt=o.aO(T,1,this.transform.zoom),yt=o.aP(this.collisionIndex.transform,T,fe.get("text-translate"),fe.get("text-translate-anchor")),At=o.aP(this.collisionIndex.transform,T,fe.get("icon-translate"),fe.get("icon-translate-anchor")),vt=Di(je,this.transform,tt);this.retainedQueryData[V.bucketInstanceId]=new eu(V.bucketInstanceId,W,V.sourceLayerIndex,V.index,T.tileID);let Lt={bucket:V,layout:se,translationText:yt,translationIcon:At,unwrappedTileID:Me,pitchedLabelPlaneMatrix:vt,scale:ye,textPixelRatio:Re,holdingForFade:T.holdingForSymbolFade(),collisionBoxArray:te,partiallyEvaluatedTextSize:o.az(V.textSizeData,this.transform.zoom),collisionGroup:this.collisionGroups.get(V.sourceID)};if(P)for(let Kt of V.sortKeyRanges){let{sortKey:It,symbolInstanceStart:Xt,symbolInstanceEnd:Rt}=Kt;l.push({sortKey:It,symbolInstanceStart:Xt,symbolInstanceEnd:Rt,parameters:Lt})}else l.push({symbolInstanceStart:0,symbolInstanceEnd:V.symbolInstances.length,parameters:Lt})}attemptAnchorPlacement(l,m,T,P,V,W,te,se,fe,ye,Re,Me,je,tt,yt,At,vt,Lt,Kt,It){let Xt=o.aQ[l.textAnchor],Rt=[l.textOffset0,l.textOffset1],zt=Tc(Xt,T,P,Rt,V),jt=this.collisionIndex.placeCollisionBox(m,Me,se,fe,ye,te,W,At,Re.predicate,Kt,zt,It);if((!Lt||this.collisionIndex.placeCollisionBox(Lt,Me,se,fe,ye,te,W,vt,Re.predicate,Kt,zt,It).placeable)&&jt.placeable){let br;if(this.prevPlacement&&this.prevPlacement.variableOffsets[je.crossTileID]&&this.prevPlacement.placements[je.crossTileID]&&this.prevPlacement.placements[je.crossTileID].text&&(br=this.prevPlacement.variableOffsets[je.crossTileID].anchor),je.crossTileID===0)throw new Error("symbolInstance.crossTileID can't be 0");return this.variableOffsets[je.crossTileID]={textOffset:Rt,width:T,height:P,anchor:Xt,textBoxScale:V,prevAnchor:br},this.markUsedJustification(tt,Xt,je,yt),tt.allowVerticalPlacement&&(this.markUsedOrientation(tt,yt,je),this.placedOrientations[je.crossTileID]=yt),{shift:zt,placedGlyphBoxes:jt}}}placeLayerBucketPart(l,m,T){let{bucket:P,layout:V,translationText:W,translationIcon:te,unwrappedTileID:se,pitchedLabelPlaneMatrix:fe,textPixelRatio:ye,holdingForFade:Re,collisionBoxArray:Me,partiallyEvaluatedTextSize:je,collisionGroup:tt}=l.parameters,yt=V.get("text-optional"),At=V.get("icon-optional"),vt=o.aR(V,"text-overlap","text-allow-overlap"),Lt=vt==="always",Kt=o.aR(V,"icon-overlap","icon-allow-overlap"),It=Kt==="always",Xt=V.get("text-rotation-alignment")==="map",Rt=V.get("text-pitch-alignment")==="map",zt=V.get("icon-text-fit")!=="none",jt=V.get("symbol-z-order")==="viewport-y",br=Lt&&(It||!P.hasIconData()||At),Cr=It&&(Lt||!P.hasTextData()||yt);!P.collisionArrays&&Me&&P.deserializeCollisionBoxes(Me);let Rr=this.retainedQueryData[P.bucketInstanceId].tileID,Pr=this._getTerrainElevationFunc(Rr),Ai=this.transform.getFastPathSimpleProjectionMatrix(Rr),_i=(hi,hn,fo)=>{var $r,di;if(m[hi.crossTileID])return;if(Re)return void(this.placements[hi.crossTileID]=new Dl(!1,!1,!1));let oa=!1,Ja=!1,ya=!0,jl=null,qs={box:null,placeable:!1,offscreen:null,occluded:!1},Wa={placeable:!1},Hl=null,Ea=null,v=null,x=0,E=0,B=0;hn.textFeatureIndex?x=hn.textFeatureIndex:hi.useRuntimeCollisionCircles&&(x=hi.featureIndex),hn.verticalTextFeatureIndex&&(E=hn.verticalTextFeatureIndex);let N=hn.textBox;if(N){let ue=bt=>{let wt=o.aA.horizontal;if(P.allowVerticalPlacement&&!bt&&this.prevPlacement){let Tt=this.prevPlacement.placedOrientations[hi.crossTileID];Tt&&(this.placedOrientations[hi.crossTileID]=Tt,wt=Tt,this.markUsedOrientation(P,wt,hi))}return wt},Ae=(bt,wt)=>{if(P.allowVerticalPlacement&&hi.numVerticalGlyphVertices>0&&hn.verticalTextBox){for(let Tt of P.writingModes)if(Tt===o.aA.vertical?(qs=wt(),Wa=qs):qs=bt(),qs&&qs.placeable)break}else qs=bt()},Te=hi.textAnchorOffsetStartIndex,at=hi.textAnchorOffsetEndIndex;if(at===Te){let bt=(wt,Tt)=>{let er=this.collisionIndex.placeCollisionBox(wt,vt,ye,Rr,se,Rt,Xt,W,tt.predicate,Pr,void 0,Ai);return er&&er.placeable&&(this.markUsedOrientation(P,Tt,hi),this.placedOrientations[hi.crossTileID]=Tt),er};Ae(()=>bt(N,o.aA.horizontal),()=>{let wt=hn.verticalTextBox;return P.allowVerticalPlacement&&hi.numVerticalGlyphVertices>0&&wt?bt(wt,o.aA.vertical):{box:null,offscreen:null}}),ue(qs&&qs.placeable)}else{let bt=o.aQ[(di=($r=this.prevPlacement)===null||$r===void 0?void 0:$r.variableOffsets[hi.crossTileID])===null||di===void 0?void 0:di.anchor],wt=(er,Ar,qr)=>{let _r=er.x2-er.x1,Sr=er.y2-er.y1,or=hi.textBoxScale,Pi=zt&&Kt==="never"?Ar:null,En=null,wn=vt==="never"?1:2,vo="never";bt&&wn++;for(let Ro=0;Rowt(N,hn.iconBox,o.aA.horizontal),()=>{let er=hn.verticalTextBox;return P.allowVerticalPlacement&&(!qs||!qs.placeable)&&hi.numVerticalGlyphVertices>0&&er?wt(er,hn.verticalIconBox,o.aA.vertical):{box:null,occluded:!0,offscreen:null}}),qs&&(oa=qs.placeable,ya=qs.offscreen);let Tt=ue(qs&&qs.placeable);if(!oa&&this.prevPlacement){let er=this.prevPlacement.variableOffsets[hi.crossTileID];er&&(this.variableOffsets[hi.crossTileID]=er,this.markUsedJustification(P,er.anchor,hi,Tt))}}}if(Hl=qs,oa=Hl&&Hl.placeable,ya=Hl&&Hl.offscreen,hi.useRuntimeCollisionCircles&&hi.centerJustifiedTextSymbolIndex>=0){let ue=P.text.placedSymbolArray.get(hi.centerJustifiedTextSymbolIndex),Ae=o.aB(P.textSizeData,je,ue),Te=V.get("text-padding");Ea=this.collisionIndex.placeCollisionCircles(vt,ue,P.lineVertexArray,P.glyphOffsetArray,Ae,se,fe,T,Rt,tt.predicate,hi.collisionCircleDiameter,Te,W,Pr),Ea.circles.length&&Ea.collisionDetected&&!T&&o.w("Collisions detected, but collision boxes are not shown"),oa=Lt||Ea.circles.length>0&&!Ea.collisionDetected,ya=ya&&Ea.offscreen}if(hn.iconFeatureIndex&&(B=hn.iconFeatureIndex),hn.iconBox){let ue=Ae=>this.collisionIndex.placeCollisionBox(Ae,Kt,ye,Rr,se,Rt,Xt,te,tt.predicate,Pr,zt&&jl?jl:void 0,Ai);Wa&&Wa.placeable&&hn.verticalIconBox?(v=ue(hn.verticalIconBox),Ja=v.placeable):(v=ue(hn.iconBox),Ja=v.placeable),ya=ya&&v.offscreen}let G=yt||hi.numHorizontalGlyphVertices===0&&hi.numVerticalGlyphVertices===0,X=At||hi.numIconVertices===0;G||X?X?G||(Ja=Ja&&oa):oa=Ja&&oa:Ja=oa=Ja&&oa;let Q=Ja&&v.placeable;if(oa&&Hl.placeable&&this.collisionIndex.insertCollisionBox(Hl.box,vt,V.get("text-ignore-placement"),P.bucketInstanceId,Wa&&Wa.placeable&&E?E:x,tt.ID),Q&&this.collisionIndex.insertCollisionBox(v.box,Kt,V.get("icon-ignore-placement"),P.bucketInstanceId,B,tt.ID),Ea&&oa&&this.collisionIndex.insertCollisionCircles(Ea.circles,vt,V.get("text-ignore-placement"),P.bucketInstanceId,x,tt.ID),T&&this.storeCollisionData(P.bucketInstanceId,fo,hn,Hl,v,Ea),hi.crossTileID===0)throw new Error("symbolInstance.crossTileID can't be 0");if(P.bucketInstanceId===0)throw new Error("bucket.bucketInstanceId can't be 0");this.placements[hi.crossTileID]=new Dl((oa||br)&&!Hl?.occluded,(Ja||Cr)&&!v?.occluded,ya||P.justReloaded),m[hi.crossTileID]=!0};if(jt){if(l.symbolInstanceStart!==0)throw new Error("bucket.bucketInstanceId should be 0");let hi=P.getSortedSymbolIndexes(-this.transform.bearingInRadians);for(let hn=hi.length-1;hn>=0;--hn){let fo=hi[hn];_i(P.symbolInstances.get(fo),P.collisionArrays[fo],fo)}}else for(let hi=l.symbolInstanceStart;hi=0&&(l.text.placedSymbolArray.get(te).crossTileID=V>=0&&te!==V?0:T.crossTileID)}markUsedOrientation(l,m,T){let P=m===o.aA.horizontal||m===o.aA.horizontalOnly?m:0,V=m===o.aA.vertical?m:0,W=[T.leftJustifiedTextSymbolIndex,T.centerJustifiedTextSymbolIndex,T.rightJustifiedTextSymbolIndex];for(let te of W)l.text.placedSymbolArray.get(te).placedOrientation=P;T.verticalPlacedTextSymbolIndex&&(l.text.placedSymbolArray.get(T.verticalPlacedTextSymbolIndex).placedOrientation=V)}commit(l){this.commitTime=l,this.zoomAtLastRecencyCheck=this.transform.zoom;let m=this.prevPlacement,T=!1;this.prevZoomAdjustment=m?m.zoomAdjustment(this.transform.zoom):0;let P=m?m.symbolFadeChange(l):1,V=m?m.opacities:{},W=m?m.variableOffsets:{},te=m?m.placedOrientations:{};for(let se in this.placements){let fe=this.placements[se],ye=V[se];ye?(this.opacities[se]=new Ll(ye,P,fe.text,fe.icon),T=T||fe.text!==ye.text.placed||fe.icon!==ye.icon.placed):(this.opacities[se]=new Ll(null,P,fe.text,fe.icon,fe.skipFade),T=T||fe.text||fe.icon)}for(let se in V){let fe=V[se];if(!this.opacities[se]){let ye=new Ll(fe,P,!1,!1);ye.isHidden()||(this.opacities[se]=ye,T=T||fe.text.placed||fe.icon.placed)}}for(let se in W)this.variableOffsets[se]||!this.opacities[se]||this.opacities[se].isHidden()||(this.variableOffsets[se]=W[se]);for(let se in te)this.placedOrientations[se]||!this.opacities[se]||this.opacities[se].isHidden()||(this.placedOrientations[se]=te[se]);if(m&&m.lastPlacementChangeTime===void 0)throw new Error("Last placement time for previous placement is not defined");T?this.lastPlacementChangeTime=l:typeof this.lastPlacementChangeTime!="number"&&(this.lastPlacementChangeTime=m?m.lastPlacementChangeTime:l)}updateLayerOpacities(l,m){let T={};for(let P of m){let V=P.getBucket(l);V&&P.latestFeatureIndex&&l.id===V.layerIds[0]&&this.updateBucketOpacities(V,P.tileID,T,P.collisionBoxArray)}}updateBucketOpacities(l,m,T,P){l.hasTextData()&&(l.text.opacityVertexArray.clear(),l.text.hasVisibleVertices=!1),l.hasIconData()&&(l.icon.opacityVertexArray.clear(),l.icon.hasVisibleVertices=!1),l.hasIconCollisionBoxData()&&l.iconCollisionBox.collisionVertexArray.clear(),l.hasTextCollisionBoxData()&&l.textCollisionBox.collisionVertexArray.clear();let V=l.layers[0],W=V.layout,te=new Ll(null,0,!1,!1,!0),se=W.get("text-allow-overlap"),fe=W.get("icon-allow-overlap"),ye=V._unevaluatedLayout.hasValue("text-variable-anchor")||V._unevaluatedLayout.hasValue("text-variable-anchor-offset"),Re=W.get("text-rotation-alignment")==="map",Me=W.get("text-pitch-alignment")==="map",je=W.get("icon-text-fit")!=="none",tt=new Ll(null,0,se&&(fe||!l.hasIconData()||W.get("icon-optional")),fe&&(se||!l.hasTextData()||W.get("text-optional")),!0);!l.collisionArrays&&P&&(l.hasIconCollisionBoxData()||l.hasTextCollisionBoxData())&&l.deserializeCollisionBoxes(P);let yt=(vt,Lt,Kt)=>{for(let It=0;It0,jt=this.placedOrientations[Lt.crossTileID],br=jt===o.aA.vertical,Cr=jt===o.aA.horizontal||jt===o.aA.horizontalOnly;if(Kt>0||It>0){let Pr=gf(Rt.text);yt(l.text,Kt,br?gd:Pr),yt(l.text,It,Cr?gd:Pr);let Ai=Rt.text.isHidden();[Lt.rightJustifiedTextSymbolIndex,Lt.centerJustifiedTextSymbolIndex,Lt.leftJustifiedTextSymbolIndex].forEach(hn=>{hn>=0&&(l.text.placedSymbolArray.get(hn).hidden=Ai||br?1:0)}),Lt.verticalPlacedTextSymbolIndex>=0&&(l.text.placedSymbolArray.get(Lt.verticalPlacedTextSymbolIndex).hidden=Ai||Cr?1:0);let _i=this.variableOffsets[Lt.crossTileID];_i&&this.markUsedJustification(l,_i.anchor,Lt,jt);let hi=this.placedOrientations[Lt.crossTileID];hi&&(this.markUsedJustification(l,"left",Lt,hi),this.markUsedOrientation(l,hi,Lt))}if(zt){let Pr=gf(Rt.icon),Ai=!(je&&Lt.verticalPlacedIconSymbolIndex&&br);Lt.placedIconSymbolIndex>=0&&(yt(l.icon,Lt.numIconVertices,Ai?Pr:gd),l.icon.placedSymbolArray.get(Lt.placedIconSymbolIndex).hidden=Rt.icon.isHidden()),Lt.verticalPlacedIconSymbolIndex>=0&&(yt(l.icon,Lt.numVerticalIconVertices,Ai?gd:Pr),l.icon.placedSymbolArray.get(Lt.verticalPlacedIconSymbolIndex).hidden=Rt.icon.isHidden())}let Rr=At&&At.has(vt)?At.get(vt):{text:null,icon:null};if(l.hasIconCollisionBoxData()||l.hasTextCollisionBoxData()){let Pr=l.collisionArrays[vt];if(Pr){let Ai=new o.P(0,0);if(Pr.textBox||Pr.verticalTextBox){let _i=!0;if(ye){let hi=this.variableOffsets[Xt];hi?(Ai=Tc(hi.anchor,hi.width,hi.height,hi.textOffset,hi.textBoxScale),Re&&Ai._rotate(Me?-this.transform.bearingInRadians:this.transform.bearingInRadians)):_i=!1}if(Pr.textBox||Pr.verticalTextBox){let hi;Pr.textBox&&(hi=br),Pr.verticalTextBox&&(hi=Cr),pm(l.textCollisionBox.collisionVertexArray,Rt.text.placed,!_i||hi,Rr.text,Ai.x,Ai.y)}}if(Pr.iconBox||Pr.verticalIconBox){let _i=Boolean(!Cr&&Pr.verticalIconBox),hi;Pr.iconBox&&(hi=_i),Pr.verticalIconBox&&(hi=!_i),pm(l.iconCollisionBox.collisionVertexArray,Rt.icon.placed,hi,Rr.icon,je?Ai.x:0,je?Ai.y:0)}}}}if(l.sortFeatures(-this.transform.bearingInRadians),this.retainedQueryData[l.bucketInstanceId]&&(this.retainedQueryData[l.bucketInstanceId].featureSortOrder=l.featureSortOrder),l.hasTextData()&&l.text.opacityVertexBuffer&&l.text.opacityVertexBuffer.updateData(l.text.opacityVertexArray),l.hasIconData()&&l.icon.opacityVertexBuffer&&l.icon.opacityVertexBuffer.updateData(l.icon.opacityVertexArray),l.hasIconCollisionBoxData()&&l.iconCollisionBox.collisionVertexBuffer&&l.iconCollisionBox.collisionVertexBuffer.updateData(l.iconCollisionBox.collisionVertexArray),l.hasTextCollisionBoxData()&&l.textCollisionBox.collisionVertexBuffer&&l.textCollisionBox.collisionVertexBuffer.updateData(l.textCollisionBox.collisionVertexArray),l.text.opacityVertexArray.length!==l.text.layoutVertexArray.length/4)throw new Error(`bucket.text.opacityVertexArray.length (= ${l.text.opacityVertexArray.length}) !== bucket.text.layoutVertexArray.length (= ${l.text.layoutVertexArray.length}) / 4`);if(l.icon.opacityVertexArray.length!==l.icon.layoutVertexArray.length/4)throw new Error(`bucket.icon.opacityVertexArray.length (= ${l.icon.opacityVertexArray.length}) !== bucket.icon.layoutVertexArray.length (= ${l.icon.layoutVertexArray.length}) / 4`);l.bucketInstanceId in this.collisionCircleArrays&&(l.collisionCircleArray=this.collisionCircleArrays[l.bucketInstanceId],delete this.collisionCircleArrays[l.bucketInstanceId])}symbolFadeChange(l){return this.fadeDuration===0?1:(l-this.commitTime)/this.fadeDuration+this.prevZoomAdjustment}zoomAdjustment(l){return Math.max(0,(this.transform.zoom-l)/1.5)}hasTransitions(l){return this.stale||l-this.lastPlacementChangeTimel}setStale(){this.stale=!0}}function pm(z,l,m,T,P,V){T&&T.length!==0||(T=[0,0,0,0]);let W=T[0]-os,te=T[1]-os,se=T[2]-os,fe=T[3]-os;z.emplaceBack(l?1:0,m?1:0,P||0,V||0,W,te),z.emplaceBack(l?1:0,m?1:0,P||0,V||0,se,te),z.emplaceBack(l?1:0,m?1:0,P||0,V||0,se,fe),z.emplaceBack(l?1:0,m?1:0,P||0,V||0,W,fe)}let pu=Math.pow(2,25),Iu=Math.pow(2,24),Vh=Math.pow(2,17),Ma=Math.pow(2,16),Mu=Math.pow(2,9),Sc=Math.pow(2,8),pc=Math.pow(2,1);function gf(z){if(z.opacity===0&&!z.placed)return 0;if(z.opacity===1&&z.placed)return 4294967295;let l=z.placed?1:0,m=Math.floor(127*z.opacity);return m*pu+l*Iu+m*Vh+l*Ma+m*Mu+l*Sc+m*pc+l}let gd=0;class jh{constructor(l){this._sortAcrossTiles=l.layout.get("symbol-z-order")!=="viewport-y"&&!l.layout.get("symbol-sort-key").isConstant(),this._currentTileIndex=0,this._currentPartIndex=0,this._seenCrossTileIDs={},this._bucketParts=[]}continuePlacement(l,m,T,P,V){let W=this._bucketParts;for(;this._currentTileIndexte.sortKey-se.sortKey));this._currentPartIndex!this._forceFullPlacement&&k()-P>2;for(;this._currentPlacementIndex>=0;){let W=m[l[this._currentPlacementIndex]],te=this.placement.collisionIndex.transform.zoom;if(W.type==="symbol"&&(!W.minzoom||W.minzoom<=te)&&(!W.maxzoom||W.maxzoom>te)){if(this._inProgressLayer||(this._inProgressLayer=new jh(W)),this._inProgressLayer.continuePlacement(T[W.source],this.placement,this._showCollisionBoxes,W,V))return;delete this._inProgressLayer}this._currentPlacementIndex--}this._done=!0}commit(l){return this.placement.commit(l),this.placement}}let Io=512/o.a5/2;class Sp{constructor(l,m,T){this.tileID=l,this.bucketInstanceId=T,this._symbolsByKey={};let P=new Map;for(let V=0;V({x:Math.floor(se.anchorX*Io),y:Math.floor(se.anchorY*Io)})),crossTileIDs:W.map(se=>se.crossTileID)};if(te.positions.length>128){let se=new o.aU(te.positions.length,16,Uint16Array);for(let{x:fe,y:ye}of te.positions)se.add(fe,ye);se.finish(),delete te.positions,te.index=se}this._symbolsByKey[V]=te}}getScaledCoordinates(l,m){let{x:T,y:P,z:V}=this.tileID.canonical,{x:W,y:te,z:se}=m.canonical,fe=Io/Math.pow(2,se-V),ye=(te*o.a5+l.anchorY)*fe,Re=P*o.a5*Io;return{x:Math.floor((W*o.a5+l.anchorX)*fe-T*o.a5*Io),y:Math.floor(ye-Re)}}findMatches(l,m,T){let P=this.tileID.canonical.zl)}}class eg{constructor(){this.maxCrossTileID=0}generate(){return++this.maxCrossTileID}}class Ep{constructor(){this.indexes={},this.usedCrossTileIDs={},this.lng=0}handleWrapJump(l){let m=Math.round((l-this.lng)/360);if(m!==0)for(let T in this.indexes){let P=this.indexes[T],V={};for(let W in P){let te=P[W];te.tileID=te.tileID.unwrapTo(te.tileID.wrap+m),V[te.tileID.key]=te}this.indexes[T]=V}this.lng=l}addBucket(l,m,T){if(this.indexes[l.overscaledZ]&&this.indexes[l.overscaledZ][l.key]){if(this.indexes[l.overscaledZ][l.key].bucketInstanceId===m.bucketInstanceId)return!1;this.removeBucketCrossTileIDs(l.overscaledZ,this.indexes[l.overscaledZ][l.key])}for(let V=0;Vl.overscaledZ)for(let te in W){let se=W[te];se.tileID.isChildOf(l)&&se.findMatches(m.symbolInstances,l,P)}else{let te=W[l.scaledTo(Number(V)).key];te&&te.findMatches(m.symbolInstances,l,P)}}for(let V=0;V{m[T]=!0});for(let T in this.layerIndexes)m[T]||delete this.layerIndexes[T]}}var Jl="void main() {fragColor=vec4(1.0);}";let _a={prelude:Zn(`#ifdef GL_ES +precision mediump float; +#else +#if !defined(lowp) +#define lowp +#endif +#if !defined(mediump) +#define mediump +#endif +#if !defined(highp) +#define highp +#endif +#endif +out highp vec4 fragColor;`,`#ifdef GL_ES +precision highp float; +#else +#if !defined(lowp) +#define lowp +#endif +#if !defined(mediump) +#define mediump +#endif +#if !defined(highp) +#define highp +#endif +#endif +vec2 unpack_float(const float packedValue) {int packedIntValue=int(packedValue);int v0=packedIntValue/256;return vec2(v0,packedIntValue-v0*256);}vec2 unpack_opacity(const float packedOpacity) {int intOpacity=int(packedOpacity)/2;return vec2(float(intOpacity)/127.0,mod(packedOpacity,2.0));}vec4 decode_color(const vec2 encodedColor) {return vec4(unpack_float(encodedColor[0])/255.0,unpack_float(encodedColor[1])/255.0 +);}float unpack_mix_vec2(const vec2 packedValue,const float t) {return mix(packedValue[0],packedValue[1],t);}vec4 unpack_mix_color(const vec4 packedColors,const float t) {vec4 minColor=decode_color(vec2(packedColors[0],packedColors[1]));vec4 maxColor=decode_color(vec2(packedColors[2],packedColors[3]));return mix(minColor,maxColor,t);}vec2 get_pattern_pos(const vec2 pixel_coord_upper,const vec2 pixel_coord_lower,const vec2 pattern_size,const float tile_units_to_pixels,const vec2 pos) {vec2 offset=mod(mod(mod(pixel_coord_upper,pattern_size)*256.0,pattern_size)*256.0+pixel_coord_lower,pattern_size);return (tile_units_to_pixels*pos+offset)/pattern_size;}mat3 rotationMatrixFromAxisAngle(vec3 u,float angle) {float c=cos(angle);float s=sin(angle);float c2=1.0-c;return mat3(u.x*u.x*c2+ c,u.x*u.y*c2-u.z*s,u.x*u.z*c2+u.y*s,u.y*u.x*c2+u.z*s,u.y*u.y*c2+ c,u.y*u.z*c2-u.x*s,u.z*u.x*c2-u.y*s,u.z*u.y*c2+u.x*s,u.z*u.z*c2+ c +);} +#ifdef TERRAIN3D +uniform sampler2D u_terrain;uniform float u_terrain_dim;uniform mat4 u_terrain_matrix;uniform vec4 u_terrain_unpack;uniform float u_terrain_exaggeration;uniform highp sampler2D u_depth; +#endif +const highp vec4 bitSh=vec4(256.*256.*256.,256.*256.,256.,1.);const highp vec4 bitShifts=vec4(1.)/bitSh;highp float unpack(highp vec4 color) {return dot(color,bitShifts);}highp float depthOpacity(vec3 frag) { +#ifdef TERRAIN3D +highp float d=unpack(texture(u_depth,frag.xy*0.5+0.5))+0.0001-frag.z;return 1.0-max(0.0,min(1.0,-d*500.0)); +#else +return 1.0; +#endif +}float calculate_visibility(vec4 pos) { +#ifdef TERRAIN3D +vec3 frag=pos.xyz/pos.w;highp float d=depthOpacity(frag);if (d > 0.95) return 1.0;return (d+depthOpacity(frag+vec3(0.0,0.01,0.0)))/2.0; +#else +return 1.0; +#endif +}float ele(vec2 pos) { +#ifdef TERRAIN3D +vec4 rgb=(texture(u_terrain,pos)*255.0)*u_terrain_unpack;return rgb.r+rgb.g+rgb.b-u_terrain_unpack.a; +#else +return 0.0; +#endif +}float get_elevation(vec2 pos) { +#ifdef TERRAIN3D +#ifdef GLOBE +if ((pos.y <-32767.5) || (pos.y > 32766.5)) {return 0.0;} +#endif +vec2 coord=(u_terrain_matrix*vec4(pos,0.0,1.0)).xy*u_terrain_dim+1.0;vec2 f=fract(coord);vec2 c=(floor(coord)+0.5)/(u_terrain_dim+2.0);float d=1.0/(u_terrain_dim+2.0);float tl=ele(c);float tr=ele(c+vec2(d,0.0));float bl=ele(c+vec2(0.0,d));float br=ele(c+vec2(d,d));float elevation=mix(mix(tl,tr,f.x),mix(bl,br,f.x),f.y);return elevation*u_terrain_exaggeration; +#else +return 0.0; +#endif +}const float PI=3.141592653589793;uniform mat4 u_projection_matrix;`),projectionMercator:Zn("","float projectLineThickness(float tileY) {return 1.0;}float projectCircleRadius(float tileY) {return 1.0;}vec4 projectTile(vec2 p) {vec4 result=u_projection_matrix*vec4(p,0.0,1.0);return result;}vec4 projectTile(vec2 p,vec2 rawPos) {vec4 result=u_projection_matrix*vec4(p,0.0,1.0);if (rawPos.y <-32767.5 || rawPos.y > 32766.5) {result.z=-10000000.0;}return result;}vec4 projectTileWithElevation(vec2 posInTile,float elevation) {return u_projection_matrix*vec4(posInTile,elevation,1.0);}vec4 projectTileFor3D(vec2 posInTile,float elevation) {return projectTileWithElevation(posInTile,elevation);}"),projectionGlobe:Zn("",`#define GLOBE_RADIUS 6371008.8 +uniform highp vec4 u_projection_tile_mercator_coords;uniform highp vec4 u_projection_clipping_plane;uniform highp float u_projection_transition;uniform mat4 u_projection_fallback_matrix;vec3 globeRotateVector(vec3 vec,vec2 angles) {vec3 axisRight=vec3(vec.z,0.0,-vec.x);vec3 axisUp=cross(axisRight,vec);axisRight=normalize(axisRight);axisUp=normalize(axisUp);vec2 t=tan(angles);return normalize(vec+axisRight*t.x+axisUp*t.y);}mat3 globeGetRotationMatrix(vec3 spherePos) {vec3 axisRight=vec3(spherePos.z,0.0,-spherePos.x);vec3 axisDown=cross(axisRight,spherePos);axisRight=normalize(axisRight);axisDown=normalize(axisDown);return mat3(axisRight,axisDown,spherePos +);}float circumferenceRatioAtTileY(float tileY) {float mercator_pos_y=u_projection_tile_mercator_coords.y+u_projection_tile_mercator_coords.w*tileY;float spherical_y=2.0*atan(exp(PI-(mercator_pos_y*PI*2.0)))-PI*0.5;return cos(spherical_y);}float projectLineThickness(float tileY) {float thickness=1.0/circumferenceRatioAtTileY(tileY); +if (u_projection_transition < 0.999) {return mix(1.0,thickness,u_projection_transition);} else {return thickness;}}vec3 projectToSphere(vec2 translatedPos,vec2 rawPos) {vec2 mercator_pos=u_projection_tile_mercator_coords.xy+u_projection_tile_mercator_coords.zw*translatedPos;vec2 spherical;spherical.x=mercator_pos.x*PI*2.0+PI;spherical.y=2.0*atan(exp(PI-(mercator_pos.y*PI*2.0)))-PI*0.5;float len=cos(spherical.y);vec3 pos=vec3(sin(spherical.x)*len,sin(spherical.y),cos(spherical.x)*len +);if (rawPos.y <-32767.5) {pos=vec3(0.0,1.0,0.0);}if (rawPos.y > 32766.5) {pos=vec3(0.0,-1.0,0.0);}return pos;}vec3 projectToSphere(vec2 posInTile) {return projectToSphere(posInTile,vec2(0.0,0.0));}float globeComputeClippingZ(vec3 spherePos) {return (1.0-(dot(spherePos,u_projection_clipping_plane.xyz)+u_projection_clipping_plane.w));}vec4 interpolateProjection(vec2 posInTile,vec3 spherePos,float elevation) {vec3 elevatedPos=spherePos*(1.0+elevation/GLOBE_RADIUS);vec4 globePosition=u_projection_matrix*vec4(elevatedPos,1.0);globePosition.z=globeComputeClippingZ(elevatedPos)*globePosition.w;if (u_projection_transition > 0.999) {return globePosition;}vec4 flatPosition=u_projection_fallback_matrix*vec4(posInTile,elevation,1.0);const float z_globeness_threshold=0.2;vec4 result=globePosition;result.z=mix(0.0,globePosition.z,clamp((u_projection_transition-z_globeness_threshold)/(1.0-z_globeness_threshold),0.0,1.0));result.xyw=mix(flatPosition.xyw,globePosition.xyw,u_projection_transition);if ((posInTile.y <-32767.5) || (posInTile.y > 32766.5)) {result=globePosition;const float poles_hidden_anim_percentage=0.02;result.z=mix(globePosition.z,100.0,pow(max((1.0-u_projection_transition)/poles_hidden_anim_percentage,0.0),8.0));}return result;}vec4 interpolateProjectionFor3D(vec2 posInTile,vec3 spherePos,float elevation) {vec3 elevatedPos=spherePos*(1.0+elevation/GLOBE_RADIUS);vec4 globePosition=u_projection_matrix*vec4(elevatedPos,1.0);if (u_projection_transition > 0.999) {return globePosition;}vec4 fallbackPosition=u_projection_fallback_matrix*vec4(posInTile,elevation,1.0);return mix(fallbackPosition,globePosition,u_projection_transition);}vec4 projectTile(vec2 posInTile) {return interpolateProjection(posInTile,projectToSphere(posInTile),0.0);}vec4 projectTile(vec2 posInTile,vec2 rawPos) {return interpolateProjection(posInTile,projectToSphere(posInTile,rawPos),0.0);}vec4 projectTileWithElevation(vec2 posInTile,float elevation) {return interpolateProjection(posInTile,projectToSphere(posInTile),elevation);}vec4 projectTileFor3D(vec2 posInTile,float elevation) {vec3 spherePos=projectToSphere(posInTile,posInTile);return interpolateProjectionFor3D(posInTile,spherePos,elevation);}`),background:Zn(`uniform vec4 u_color;uniform float u_opacity;void main() {fragColor=u_color*u_opacity; +#ifdef OVERDRAW_INSPECTOR +fragColor=vec4(1.0); +#endif +}`,"in vec2 a_pos;void main() {gl_Position=projectTile(a_pos);}"),backgroundPattern:Zn(`uniform vec2 u_pattern_tl_a;uniform vec2 u_pattern_br_a;uniform vec2 u_pattern_tl_b;uniform vec2 u_pattern_br_b;uniform vec2 u_texsize;uniform float u_mix;uniform float u_opacity;uniform sampler2D u_image;in vec2 v_pos_a;in vec2 v_pos_b;void main() {vec2 imagecoord=mod(v_pos_a,1.0);vec2 pos=mix(u_pattern_tl_a/u_texsize,u_pattern_br_a/u_texsize,imagecoord);vec4 color1=texture(u_image,pos);vec2 imagecoord_b=mod(v_pos_b,1.0);vec2 pos2=mix(u_pattern_tl_b/u_texsize,u_pattern_br_b/u_texsize,imagecoord_b);vec4 color2=texture(u_image,pos2);fragColor=mix(color1,color2,u_mix)*u_opacity; +#ifdef OVERDRAW_INSPECTOR +fragColor=vec4(1.0); +#endif +}`,"uniform vec2 u_pattern_size_a;uniform vec2 u_pattern_size_b;uniform vec2 u_pixel_coord_upper;uniform vec2 u_pixel_coord_lower;uniform float u_scale_a;uniform float u_scale_b;uniform float u_tile_units_to_pixels;in vec2 a_pos;out vec2 v_pos_a;out vec2 v_pos_b;void main() {gl_Position=projectTile(a_pos);v_pos_a=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,u_scale_a*u_pattern_size_a,u_tile_units_to_pixels,a_pos);v_pos_b=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,u_scale_b*u_pattern_size_b,u_tile_units_to_pixels,a_pos);}"),circle:Zn(`in vec3 v_data;in float v_visibility; +#pragma mapbox: define highp vec4 color +#pragma mapbox: define mediump float radius +#pragma mapbox: define lowp float blur +#pragma mapbox: define lowp float opacity +#pragma mapbox: define highp vec4 stroke_color +#pragma mapbox: define mediump float stroke_width +#pragma mapbox: define lowp float stroke_opacity +void main() { +#pragma mapbox: initialize highp vec4 color +#pragma mapbox: initialize mediump float radius +#pragma mapbox: initialize lowp float blur +#pragma mapbox: initialize lowp float opacity +#pragma mapbox: initialize highp vec4 stroke_color +#pragma mapbox: initialize mediump float stroke_width +#pragma mapbox: initialize lowp float stroke_opacity +vec2 extrude=v_data.xy;float extrude_length=length(extrude);float antialiased_blur=v_data.z;float opacity_t=smoothstep(0.0,antialiased_blur,extrude_length-1.0);float color_t=stroke_width < 0.01 ? 0.0 : smoothstep(antialiased_blur,0.0,extrude_length-radius/(radius+stroke_width));fragColor=v_visibility*opacity_t*mix(color*opacity,stroke_color*stroke_opacity,color_t);const float epsilon=0.5/255.0;if (fragColor.r < epsilon && fragColor.g < epsilon && fragColor.b < epsilon && fragColor.a < epsilon) {discard;} +#ifdef OVERDRAW_INSPECTOR +fragColor=vec4(1.0); +#endif +}`,`uniform bool u_scale_with_map;uniform bool u_pitch_with_map;uniform vec2 u_extrude_scale;uniform highp float u_globe_extrude_scale;uniform lowp float u_device_pixel_ratio;uniform highp float u_camera_to_center_distance;uniform vec2 u_translate;in vec2 a_pos;out vec3 v_data;out float v_visibility; +#pragma mapbox: define highp vec4 color +#pragma mapbox: define mediump float radius +#pragma mapbox: define lowp float blur +#pragma mapbox: define lowp float opacity +#pragma mapbox: define highp vec4 stroke_color +#pragma mapbox: define mediump float stroke_width +#pragma mapbox: define lowp float stroke_opacity +void main(void) { +#pragma mapbox: initialize highp vec4 color +#pragma mapbox: initialize mediump float radius +#pragma mapbox: initialize lowp float blur +#pragma mapbox: initialize lowp float opacity +#pragma mapbox: initialize highp vec4 stroke_color +#pragma mapbox: initialize mediump float stroke_width +#pragma mapbox: initialize lowp float stroke_opacity +vec2 pos_raw=a_pos+32768.0;vec2 extrude=vec2(mod(pos_raw,8.0)/7.0*2.0-1.0);vec2 circle_center=floor(pos_raw/8.0)+u_translate;float ele=get_elevation(circle_center);v_visibility=calculate_visibility(projectTileWithElevation(circle_center,ele));if (u_pitch_with_map) { +#ifdef GLOBE +vec3 center_vector=projectToSphere(circle_center); +#endif +float angle_scale=u_globe_extrude_scale;vec2 corner_position=circle_center;if (u_scale_with_map) {angle_scale*=(radius+stroke_width);corner_position+=extrude*u_extrude_scale*(radius+stroke_width);} else { +#ifdef GLOBE +vec4 projected_center=interpolateProjection(circle_center,center_vector,ele); +#else +vec4 projected_center=projectTileWithElevation(circle_center,ele); +#endif +corner_position+=extrude*u_extrude_scale*(radius+stroke_width)*(projected_center.w/u_camera_to_center_distance);angle_scale*=(radius+stroke_width)*(projected_center.w/u_camera_to_center_distance);} +#ifdef GLOBE +vec2 angles=extrude*angle_scale;vec3 corner_vector=globeRotateVector(center_vector,angles);gl_Position=interpolateProjection(corner_position,corner_vector,ele); +#else +gl_Position=projectTileWithElevation(corner_position,ele); +#endif +} else {gl_Position=projectTileWithElevation(circle_center,ele);if (gl_Position.z/gl_Position.w > 1.0) {gl_Position.xy=vec2(10000.0);}if (u_scale_with_map) {gl_Position.xy+=extrude*(radius+stroke_width)*u_extrude_scale*u_camera_to_center_distance;} else {gl_Position.xy+=extrude*(radius+stroke_width)*u_extrude_scale*gl_Position.w;}}float antialiasblur=-max(1.0/u_device_pixel_ratio/(radius+stroke_width),blur);v_data=vec3(extrude.x,extrude.y,antialiasblur);}`),clippingMask:Zn(Jl,"in vec2 a_pos;void main() {gl_Position=projectTile(a_pos);}"),heatmap:Zn(`uniform highp float u_intensity;in vec2 v_extrude; +#pragma mapbox: define highp float weight +#define GAUSS_COEF 0.3989422804014327 +void main() { +#pragma mapbox: initialize highp float weight +float d=-0.5*3.0*3.0*dot(v_extrude,v_extrude);float val=weight*u_intensity*GAUSS_COEF*exp(d);fragColor=vec4(val,1.0,1.0,1.0); +#ifdef OVERDRAW_INSPECTOR +fragColor=vec4(1.0); +#endif +}`,`uniform float u_extrude_scale;uniform float u_opacity;uniform float u_intensity;uniform highp float u_globe_extrude_scale;in vec2 a_pos;out vec2 v_extrude; +#pragma mapbox: define highp float weight +#pragma mapbox: define mediump float radius +const highp float ZERO=1.0/255.0/16.0; +#define GAUSS_COEF 0.3989422804014327 +void main(void) { +#pragma mapbox: initialize highp float weight +#pragma mapbox: initialize mediump float radius +vec2 pos_raw=a_pos+32768.0;vec2 unscaled_extrude=vec2(mod(pos_raw,8.0)/7.0*2.0-1.0);float S=sqrt(-2.0*log(ZERO/weight/u_intensity/GAUSS_COEF))/3.0;v_extrude=S*unscaled_extrude;vec2 extrude=v_extrude*radius*u_extrude_scale;vec2 circle_center=floor(pos_raw/8.0); +#ifdef GLOBE +vec2 angles=v_extrude*radius*u_globe_extrude_scale;vec3 center_vector=projectToSphere(circle_center);vec3 corner_vector=globeRotateVector(center_vector,angles);gl_Position=interpolateProjection(circle_center+extrude,corner_vector,0.0); +#else +gl_Position=projectTileFor3D(circle_center+extrude,get_elevation(circle_center)); +#endif +}`),heatmapTexture:Zn(`uniform sampler2D u_image;uniform sampler2D u_color_ramp;uniform float u_opacity;in vec2 v_pos;void main() {float t=texture(u_image,v_pos).r;vec4 color=texture(u_color_ramp,vec2(t,0.5));fragColor=color*u_opacity; +#ifdef OVERDRAW_INSPECTOR +fragColor=vec4(0.0); +#endif +}`,"uniform mat4 u_matrix;uniform vec2 u_world;in vec2 a_pos;out vec2 v_pos;void main() {gl_Position=u_matrix*vec4(a_pos*u_world,0,1);v_pos.x=a_pos.x;v_pos.y=1.0-a_pos.y;}"),collisionBox:Zn("in float v_placed;in float v_notUsed;void main() {float alpha=0.5;fragColor=vec4(1.0,0.0,0.0,1.0)*alpha;if (v_placed > 0.5) {fragColor=vec4(0.0,0.0,1.0,0.5)*alpha;}if (v_notUsed > 0.5) {fragColor*=.1;}}","in vec2 a_anchor_pos;in vec2 a_placed;in vec2 a_box_real;uniform vec2 u_pixel_extrude_scale;out float v_placed;out float v_notUsed;void main() {gl_Position=projectTileWithElevation(a_anchor_pos,get_elevation(a_anchor_pos));gl_Position.xy=((a_box_real+0.5)*u_pixel_extrude_scale*2.0-1.0)*vec2(1.0,-1.0)*gl_Position.w;if (gl_Position.z/gl_Position.w < 1.1) {gl_Position.z=0.5;}v_placed=a_placed.x;v_notUsed=a_placed.y;}"),collisionCircle:Zn("in float v_radius;in vec2 v_extrude;in float v_collision;void main() {float alpha=0.5;float stroke_radius=0.9;float distance_to_center=length(v_extrude);float distance_to_edge=abs(distance_to_center-v_radius);float opacity_t=smoothstep(-stroke_radius,0.0,-distance_to_edge);vec4 color=mix(vec4(0.0,0.0,1.0,0.5),vec4(1.0,0.0,0.0,1.0),v_collision);fragColor=color*alpha*opacity_t;}","in vec2 a_pos;in float a_radius;in vec2 a_flags;uniform vec2 u_viewport_size;out float v_radius;out vec2 v_extrude;out float v_collision;void main() {float radius=a_radius;float collision=a_flags.x;float vertexIdx=a_flags.y;vec2 quadVertexOffset=vec2(mix(-1.0,1.0,float(vertexIdx >=2.0)),mix(-1.0,1.0,float(vertexIdx >=1.0 && vertexIdx <=2.0)));vec2 quadVertexExtent=quadVertexOffset*radius;float padding_factor=1.2;v_radius=radius;v_extrude=quadVertexExtent*padding_factor;v_collision=collision;gl_Position=vec4((a_pos/u_viewport_size*2.0-1.0)*vec2(1.0,-1.0),0.0,1.0)+vec4(quadVertexExtent*padding_factor/u_viewport_size*2.0,0.0,0.0);}"),colorRelief:Zn(`#ifdef GL_ES +precision highp float; +#endif +uniform sampler2D u_image;uniform vec4 u_unpack;uniform sampler2D u_elevation_stops;uniform sampler2D u_color_stops;uniform int u_color_ramp_size;uniform float u_opacity;in vec2 v_pos;float getElevation(vec2 coord) {vec4 data=texture(u_image,coord)*255.0;data.a=-1.0;return dot(data,u_unpack);}float getElevationStop(int stop) {float x=(float(stop)+0.5)/float(u_color_ramp_size);vec4 data=texture(u_elevation_stops,vec2(x,0))*255.0;data.a=-1.0;return dot(data,u_unpack);}void main() {float el=getElevation(v_pos);int r=(u_color_ramp_size-1);int l=0;float el_l=getElevationStop(l);float el_r=getElevationStop(r);while(r-l > 1){int m=(r+l)/2;float el_m=getElevationStop(m);if(el < el_m){r=m;el_r=el_m;}else +{l=m;el_l=el_m;}}float x=(float(l)+(el-el_l)/(el_r-el_l)+0.5)/float(u_color_ramp_size);fragColor=u_opacity*texture(u_color_stops,vec2(x,0)); +#ifdef OVERDRAW_INSPECTOR +fragColor=vec4(1.0); +#endif +}`,"uniform vec2 u_dimension;in vec2 a_pos;out vec2 v_pos;void main() {gl_Position=projectTile(a_pos,a_pos);highp vec2 epsilon=1.0/u_dimension;float scale=(u_dimension.x-2.0)/u_dimension.x;v_pos=(a_pos/8192.0)*scale+epsilon;if (a_pos.y <-32767.5) {v_pos.y=0.0;}if (a_pos.y > 32766.5) {v_pos.y=1.0;}}"),debug:Zn("uniform highp vec4 u_color;uniform sampler2D u_overlay;in vec2 v_uv;void main() {vec4 overlay_color=texture(u_overlay,v_uv);fragColor=mix(u_color,overlay_color,overlay_color.a);}","in vec2 a_pos;out vec2 v_uv;uniform float u_overlay_scale;void main() {v_uv=a_pos/8192.0;gl_Position=projectTileWithElevation(a_pos*u_overlay_scale,get_elevation(a_pos));}"),depth:Zn(Jl,`in vec2 a_pos;void main() { +#ifdef GLOBE +gl_Position=projectTileFor3D(a_pos,0.0); +#else +gl_Position=u_projection_matrix*vec4(a_pos,0.0,1.0); +#endif +}`),fill:Zn(`#pragma mapbox: define highp vec4 color +#pragma mapbox: define lowp float opacity +void main() { +#pragma mapbox: initialize highp vec4 color +#pragma mapbox: initialize lowp float opacity +fragColor=color*opacity; +#ifdef OVERDRAW_INSPECTOR +fragColor=vec4(1.0); +#endif +}`,`uniform vec2 u_fill_translate;in vec2 a_pos; +#pragma mapbox: define highp vec4 color +#pragma mapbox: define lowp float opacity +void main() { +#pragma mapbox: initialize highp vec4 color +#pragma mapbox: initialize lowp float opacity +gl_Position=projectTile(a_pos+u_fill_translate,a_pos);}`),fillOutline:Zn(`in vec2 v_pos; +#ifdef GLOBE +in float v_depth; +#endif +#pragma mapbox: define highp vec4 outline_color +#pragma mapbox: define lowp float opacity +void main() { +#pragma mapbox: initialize highp vec4 outline_color +#pragma mapbox: initialize lowp float opacity +float dist=length(v_pos-gl_FragCoord.xy);float alpha=1.0-smoothstep(0.0,1.0,dist);fragColor=outline_color*(alpha*opacity); +#ifdef GLOBE +if (v_depth > 1.0) {discard;} +#endif +#ifdef OVERDRAW_INSPECTOR +fragColor=vec4(1.0); +#endif +}`,`uniform vec2 u_world;uniform vec2 u_fill_translate;in vec2 a_pos;out vec2 v_pos; +#ifdef GLOBE +out float v_depth; +#endif +#pragma mapbox: define highp vec4 outline_color +#pragma mapbox: define lowp float opacity +void main() { +#pragma mapbox: initialize highp vec4 outline_color +#pragma mapbox: initialize lowp float opacity +gl_Position=projectTile(a_pos+u_fill_translate,a_pos);v_pos=(gl_Position.xy/gl_Position.w+1.0)/2.0*u_world; +#ifdef GLOBE +v_depth=gl_Position.z/gl_Position.w; +#endif +}`),fillOutlinePattern:Zn(`uniform vec2 u_texsize;uniform sampler2D u_image;uniform float u_fade;in vec2 v_pos_a;in vec2 v_pos_b;in vec2 v_pos; +#ifdef GLOBE +in float v_depth; +#endif +#pragma mapbox: define lowp float opacity +#pragma mapbox: define lowp vec4 pattern_from +#pragma mapbox: define lowp vec4 pattern_to +void main() { +#pragma mapbox: initialize lowp float opacity +#pragma mapbox: initialize mediump vec4 pattern_from +#pragma mapbox: initialize mediump vec4 pattern_to +vec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;vec2 imagecoord=mod(v_pos_a,1.0);vec2 pos=mix(pattern_tl_a/u_texsize,pattern_br_a/u_texsize,imagecoord);vec4 color1=texture(u_image,pos);vec2 imagecoord_b=mod(v_pos_b,1.0);vec2 pos2=mix(pattern_tl_b/u_texsize,pattern_br_b/u_texsize,imagecoord_b);vec4 color2=texture(u_image,pos2);float dist=length(v_pos-gl_FragCoord.xy);float alpha=1.0-smoothstep(0.0,1.0,dist);fragColor=mix(color1,color2,u_fade)*alpha*opacity; +#ifdef GLOBE +if (v_depth > 1.0) {discard;} +#endif +#ifdef OVERDRAW_INSPECTOR +fragColor=vec4(1.0); +#endif +}`,`uniform vec2 u_world;uniform vec2 u_pixel_coord_upper;uniform vec2 u_pixel_coord_lower;uniform vec3 u_scale;uniform vec2 u_fill_translate;in vec2 a_pos;out vec2 v_pos_a;out vec2 v_pos_b;out vec2 v_pos; +#ifdef GLOBE +out float v_depth; +#endif +#pragma mapbox: define lowp float opacity +#pragma mapbox: define lowp vec4 pattern_from +#pragma mapbox: define lowp vec4 pattern_to +#pragma mapbox: define lowp float pixel_ratio_from +#pragma mapbox: define lowp float pixel_ratio_to +void main() { +#pragma mapbox: initialize lowp float opacity +#pragma mapbox: initialize mediump vec4 pattern_from +#pragma mapbox: initialize mediump vec4 pattern_to +#pragma mapbox: initialize lowp float pixel_ratio_from +#pragma mapbox: initialize lowp float pixel_ratio_to +vec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;float tileRatio=u_scale.x;float fromScale=u_scale.y;float toScale=u_scale.z;gl_Position=projectTile(a_pos+u_fill_translate,a_pos);vec2 display_size_a=(pattern_br_a-pattern_tl_a)/pixel_ratio_from;vec2 display_size_b=(pattern_br_b-pattern_tl_b)/pixel_ratio_to;v_pos_a=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,fromScale*display_size_a,tileRatio,a_pos);v_pos_b=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,toScale*display_size_b,tileRatio,a_pos);v_pos=(gl_Position.xy/gl_Position.w+1.0)/2.0*u_world; +#ifdef GLOBE +v_depth=gl_Position.z/gl_Position.w; +#endif +}`),fillPattern:Zn(`#ifdef GL_ES +precision highp float; +#endif +uniform vec2 u_texsize;uniform float u_fade;uniform sampler2D u_image;in vec2 v_pos_a;in vec2 v_pos_b; +#pragma mapbox: define lowp float opacity +#pragma mapbox: define lowp vec4 pattern_from +#pragma mapbox: define lowp vec4 pattern_to +void main() { +#pragma mapbox: initialize lowp float opacity +#pragma mapbox: initialize mediump vec4 pattern_from +#pragma mapbox: initialize mediump vec4 pattern_to +vec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;vec2 imagecoord=mod(v_pos_a,1.0);vec2 pos=mix(pattern_tl_a/u_texsize,pattern_br_a/u_texsize,imagecoord);vec4 color1=texture(u_image,pos);vec2 imagecoord_b=mod(v_pos_b,1.0);vec2 pos2=mix(pattern_tl_b/u_texsize,pattern_br_b/u_texsize,imagecoord_b);vec4 color2=texture(u_image,pos2);fragColor=mix(color1,color2,u_fade)*opacity; +#ifdef OVERDRAW_INSPECTOR +fragColor=vec4(1.0); +#endif +}`,`uniform vec2 u_pixel_coord_upper;uniform vec2 u_pixel_coord_lower;uniform vec3 u_scale;uniform vec2 u_fill_translate;in vec2 a_pos;out vec2 v_pos_a;out vec2 v_pos_b; +#pragma mapbox: define lowp float opacity +#pragma mapbox: define lowp vec4 pattern_from +#pragma mapbox: define lowp vec4 pattern_to +#pragma mapbox: define lowp float pixel_ratio_from +#pragma mapbox: define lowp float pixel_ratio_to +void main() { +#pragma mapbox: initialize lowp float opacity +#pragma mapbox: initialize mediump vec4 pattern_from +#pragma mapbox: initialize mediump vec4 pattern_to +#pragma mapbox: initialize lowp float pixel_ratio_from +#pragma mapbox: initialize lowp float pixel_ratio_to +vec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;float tileZoomRatio=u_scale.x;float fromScale=u_scale.y;float toScale=u_scale.z;vec2 display_size_a=(pattern_br_a-pattern_tl_a)/pixel_ratio_from;vec2 display_size_b=(pattern_br_b-pattern_tl_b)/pixel_ratio_to;gl_Position=projectTile(a_pos+u_fill_translate,a_pos);v_pos_a=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,fromScale*display_size_a,tileZoomRatio,a_pos);v_pos_b=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,toScale*display_size_b,tileZoomRatio,a_pos);}`),fillExtrusion:Zn(`in vec4 v_color;void main() {fragColor=v_color; +#ifdef OVERDRAW_INSPECTOR +fragColor=vec4(1.0); +#endif +}`,`uniform vec3 u_lightcolor;uniform lowp vec3 u_lightpos;uniform lowp vec3 u_lightpos_globe;uniform lowp float u_lightintensity;uniform float u_vertical_gradient;uniform lowp float u_opacity;uniform vec2 u_fill_translate;in vec2 a_pos;in vec4 a_normal_ed; +#ifdef TERRAIN3D +in vec2 a_centroid; +#endif +out vec4 v_color; +#pragma mapbox: define highp float base +#pragma mapbox: define highp float height +#pragma mapbox: define highp vec4 color +void main() { +#pragma mapbox: initialize highp float base +#pragma mapbox: initialize highp float height +#pragma mapbox: initialize highp vec4 color +vec3 normal=a_normal_ed.xyz; +#ifdef TERRAIN3D +float height_terrain3d_offset=get_elevation(a_centroid);float base_terrain3d_offset=height_terrain3d_offset-(base > 0.0 ? 0.0 : 10.0); +#else +float height_terrain3d_offset=0.0;float base_terrain3d_offset=0.0; +#endif +base=max(0.0,base)+base_terrain3d_offset;height=max(0.0,height)+height_terrain3d_offset;float t=mod(normal.x,2.0);float elevation=t > 0.0 ? height : base;vec2 posInTile=a_pos+u_fill_translate; +#ifdef GLOBE +vec3 spherePos=projectToSphere(posInTile,a_pos);gl_Position=interpolateProjectionFor3D(posInTile,spherePos,elevation); +#else +gl_Position=u_projection_matrix*vec4(posInTile,elevation,1.0); +#endif +float colorvalue=color.r*0.2126+color.g*0.7152+color.b*0.0722;v_color=vec4(0.0,0.0,0.0,1.0);vec4 ambientlight=vec4(0.03,0.03,0.03,1.0);color+=ambientlight;vec3 normalForLighting=normal/16384.0;float directional=clamp(dot(normalForLighting,u_lightpos),0.0,1.0); +#ifdef GLOBE +mat3 rotMatrix=globeGetRotationMatrix(spherePos);normalForLighting=rotMatrix*normalForLighting;directional=mix(directional,clamp(dot(normalForLighting,u_lightpos_globe),0.0,1.0),u_projection_transition); +#endif +directional=mix((1.0-u_lightintensity),max((1.0-colorvalue+u_lightintensity),1.0),directional);if (normal.y !=0.0) {directional*=((1.0-u_vertical_gradient)+(u_vertical_gradient*clamp((t+base)*pow(height/150.0,0.5),mix(0.7,0.98,1.0-u_lightintensity),1.0)));}v_color.r+=clamp(color.r*directional*u_lightcolor.r,mix(0.0,0.3,1.0-u_lightcolor.r),1.0);v_color.g+=clamp(color.g*directional*u_lightcolor.g,mix(0.0,0.3,1.0-u_lightcolor.g),1.0);v_color.b+=clamp(color.b*directional*u_lightcolor.b,mix(0.0,0.3,1.0-u_lightcolor.b),1.0);v_color*=u_opacity;}`),fillExtrusionPattern:Zn(`uniform vec2 u_texsize;uniform float u_fade;uniform sampler2D u_image;in vec2 v_pos_a;in vec2 v_pos_b;in vec4 v_lighting; +#pragma mapbox: define lowp float base +#pragma mapbox: define lowp float height +#pragma mapbox: define lowp vec4 pattern_from +#pragma mapbox: define lowp vec4 pattern_to +#pragma mapbox: define lowp float pixel_ratio_from +#pragma mapbox: define lowp float pixel_ratio_to +void main() { +#pragma mapbox: initialize lowp float base +#pragma mapbox: initialize lowp float height +#pragma mapbox: initialize mediump vec4 pattern_from +#pragma mapbox: initialize mediump vec4 pattern_to +#pragma mapbox: initialize lowp float pixel_ratio_from +#pragma mapbox: initialize lowp float pixel_ratio_to +vec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;vec2 imagecoord=mod(v_pos_a,1.0);vec2 pos=mix(pattern_tl_a/u_texsize,pattern_br_a/u_texsize,imagecoord);vec4 color1=texture(u_image,pos);vec2 imagecoord_b=mod(v_pos_b,1.0);vec2 pos2=mix(pattern_tl_b/u_texsize,pattern_br_b/u_texsize,imagecoord_b);vec4 color2=texture(u_image,pos2);vec4 mixedColor=mix(color1,color2,u_fade);fragColor=mixedColor*v_lighting; +#ifdef OVERDRAW_INSPECTOR +fragColor=vec4(1.0); +#endif +}`,`uniform vec2 u_pixel_coord_upper;uniform vec2 u_pixel_coord_lower;uniform float u_height_factor;uniform vec3 u_scale;uniform float u_vertical_gradient;uniform lowp float u_opacity;uniform vec2 u_fill_translate;uniform vec3 u_lightcolor;uniform lowp vec3 u_lightpos;uniform lowp vec3 u_lightpos_globe;uniform lowp float u_lightintensity;in vec2 a_pos;in vec4 a_normal_ed; +#ifdef TERRAIN3D +in vec2 a_centroid; +#endif +#ifdef GLOBE +out vec3 v_sphere_pos; +#endif +out vec2 v_pos_a;out vec2 v_pos_b;out vec4 v_lighting; +#pragma mapbox: define lowp float base +#pragma mapbox: define lowp float height +#pragma mapbox: define lowp vec4 pattern_from +#pragma mapbox: define lowp vec4 pattern_to +#pragma mapbox: define lowp float pixel_ratio_from +#pragma mapbox: define lowp float pixel_ratio_to +void main() { +#pragma mapbox: initialize lowp float base +#pragma mapbox: initialize lowp float height +#pragma mapbox: initialize mediump vec4 pattern_from +#pragma mapbox: initialize mediump vec4 pattern_to +#pragma mapbox: initialize lowp float pixel_ratio_from +#pragma mapbox: initialize lowp float pixel_ratio_to +vec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;float tileRatio=u_scale.x;float fromScale=u_scale.y;float toScale=u_scale.z;vec3 normal=a_normal_ed.xyz;float edgedistance=a_normal_ed.w;vec2 display_size_a=(pattern_br_a-pattern_tl_a)/pixel_ratio_from;vec2 display_size_b=(pattern_br_b-pattern_tl_b)/pixel_ratio_to; +#ifdef TERRAIN3D +float height_terrain3d_offset=get_elevation(a_centroid);float base_terrain3d_offset=height_terrain3d_offset-(base > 0.0 ? 0.0 : 10.0); +#else +float height_terrain3d_offset=0.0;float base_terrain3d_offset=0.0; +#endif +base=max(0.0,base)+base_terrain3d_offset;height=max(0.0,height)+height_terrain3d_offset;float t=mod(normal.x,2.0);float elevation=t > 0.0 ? height : base;vec2 posInTile=a_pos+u_fill_translate; +#ifdef GLOBE +vec3 spherePos=projectToSphere(posInTile,a_pos);vec3 elevatedPos=spherePos*(1.0+elevation/GLOBE_RADIUS);v_sphere_pos=elevatedPos;gl_Position=interpolateProjectionFor3D(posInTile,spherePos,elevation); +#else +gl_Position=u_projection_matrix*vec4(posInTile,elevation,1.0); +#endif +vec2 pos=normal.x==1.0 && normal.y==0.0 && normal.z==16384.0 +? a_pos +: vec2(edgedistance,elevation*u_height_factor);v_pos_a=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,fromScale*display_size_a,tileRatio,pos);v_pos_b=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,toScale*display_size_b,tileRatio,pos);v_lighting=vec4(0.0,0.0,0.0,1.0);float directional=clamp(dot(normal/16383.0,u_lightpos),0.0,1.0);directional=mix((1.0-u_lightintensity),max((0.5+u_lightintensity),1.0),directional);if (normal.y !=0.0) {directional*=((1.0-u_vertical_gradient)+(u_vertical_gradient*clamp((t+base)*pow(height/150.0,0.5),mix(0.7,0.98,1.0-u_lightintensity),1.0)));}v_lighting.rgb+=clamp(directional*u_lightcolor,mix(vec3(0.0),vec3(0.3),1.0-u_lightcolor),vec3(1.0));v_lighting*=u_opacity;}`),hillshadePrepare:Zn(`#ifdef GL_ES +precision highp float; +#endif +uniform sampler2D u_image;in vec2 v_pos;uniform vec2 u_dimension;uniform float u_zoom;uniform vec4 u_unpack;float getElevation(vec2 coord,float bias) {vec4 data=texture(u_image,coord)*255.0;data.a=-1.0;return dot(data,u_unpack);}void main() {vec2 epsilon=1.0/u_dimension;float tileSize=u_dimension.x-2.0;float a=getElevation(v_pos+vec2(-epsilon.x,-epsilon.y),0.0);float b=getElevation(v_pos+vec2(0,-epsilon.y),0.0);float c=getElevation(v_pos+vec2(epsilon.x,-epsilon.y),0.0);float d=getElevation(v_pos+vec2(-epsilon.x,0),0.0);float e=getElevation(v_pos,0.0);float f=getElevation(v_pos+vec2(epsilon.x,0),0.0);float g=getElevation(v_pos+vec2(-epsilon.x,epsilon.y),0.0);float h=getElevation(v_pos+vec2(0,epsilon.y),0.0);float i=getElevation(v_pos+vec2(epsilon.x,epsilon.y),0.0);float exaggerationFactor=u_zoom < 2.0 ? 0.4 : u_zoom < 4.5 ? 0.35 : 0.3;float exaggeration=u_zoom < 15.0 ? (u_zoom-15.0)*exaggerationFactor : 0.0;vec2 deriv=vec2((c+f+f+i)-(a+d+d+g),(g+h+h+i)-(a+b+b+c))*tileSize/pow(2.0,exaggeration+(28.2562-u_zoom));fragColor=clamp(vec4(deriv.x/8.0+0.5,deriv.y/8.0+0.5,1.0,1.0),0.0,1.0); +#ifdef OVERDRAW_INSPECTOR +fragColor=vec4(1.0); +#endif +}`,"uniform mat4 u_matrix;uniform vec2 u_dimension;in vec2 a_pos;in vec2 a_texture_pos;out vec2 v_pos;void main() {gl_Position=u_matrix*vec4(a_pos,0,1);highp vec2 epsilon=1.0/u_dimension;float scale=(u_dimension.x-2.0)/u_dimension.x;v_pos=(a_texture_pos/8192.0)*scale+epsilon;}"),hillshade:Zn(`uniform sampler2D u_image;in vec2 v_pos;uniform vec2 u_latrange;uniform float u_exaggeration;uniform vec4 u_accent;uniform int u_method;uniform float u_altitudes[NUM_ILLUMINATION_SOURCES];uniform float u_azimuths[NUM_ILLUMINATION_SOURCES];uniform vec4 u_shadows[NUM_ILLUMINATION_SOURCES];uniform vec4 u_highlights[NUM_ILLUMINATION_SOURCES]; +#define PI 3.141592653589793 +#define STANDARD 0 +#define COMBINED 1 +#define IGOR 2 +#define MULTIDIRECTIONAL 3 +#define BASIC 4 +float get_aspect(vec2 deriv){return deriv.x !=0.0 ? atan(deriv.y,-deriv.x) : PI/2.0*(deriv.y > 0.0 ? 1.0 :-1.0);}void igor_hillshade(vec2 deriv){deriv=deriv*u_exaggeration*2.0;float aspect=get_aspect(deriv);float azimuth=u_azimuths[0]+PI;float slope_stength=atan(length(deriv))*2.0/PI;float aspect_strength=1.0-abs(mod((aspect+azimuth)/PI+0.5,2.0)-1.0);float shadow_strength=slope_stength*aspect_strength;float highlight_strength=slope_stength*(1.0-aspect_strength);fragColor=u_shadows[0]*shadow_strength+u_highlights[0]*highlight_strength;}void standard_hillshade(vec2 deriv){float azimuth=u_azimuths[0]+PI;float slope=atan(0.625*length(deriv));float aspect=get_aspect(deriv);float intensity=u_exaggeration;float base=1.875-intensity*1.75;float maxValue=0.5*PI;float scaledSlope=intensity !=0.5 ? ((pow(base,slope)-1.0)/(pow(base,maxValue)-1.0))*maxValue : slope;float accent=cos(scaledSlope);vec4 accent_color=(1.0-accent)*u_accent*clamp(intensity*2.0,0.0,1.0);float shade=abs(mod((aspect+azimuth)/PI+0.5,2.0)-1.0);vec4 shade_color=mix(u_shadows[0],u_highlights[0],shade)*sin(scaledSlope)*clamp(intensity*2.0,0.0,1.0);fragColor=accent_color*(1.0-shade_color.a)+shade_color;}void basic_hillshade(vec2 deriv){deriv=deriv*u_exaggeration*2.0;float azimuth=u_azimuths[0]+PI;float cos_az=cos(azimuth);float sin_az=sin(azimuth);float cos_alt=cos(u_altitudes[0]);float sin_alt=sin(u_altitudes[0]);float cang=(sin_alt-(deriv.y*cos_az*cos_alt-deriv.x*sin_az*cos_alt))/sqrt(1.0+dot(deriv,deriv));float shade=clamp(cang,0.0,1.0);if(shade > 0.5){fragColor=u_highlights[0]*(2.0*shade-1.0);}else +{fragColor=u_shadows[0]*(1.0-2.0*shade);}}void multidirectional_hillshade(vec2 deriv){deriv=deriv*u_exaggeration*2.0;fragColor=vec4(0,0,0,0);for(int i=0; i < NUM_ILLUMINATION_SOURCES; i++){float cos_alt=cos(u_altitudes[i]);float sin_alt=sin(u_altitudes[i]);float cos_az=-cos(u_azimuths[i]);float sin_az=-sin(u_azimuths[i]);float cang=(sin_alt-(deriv.y*cos_az*cos_alt-deriv.x*sin_az*cos_alt))/sqrt(1.0+dot(deriv,deriv));float shade=clamp(cang,0.0,1.0);if(shade > 0.5){fragColor+=u_highlights[i]*(2.0*shade-1.0)/float(NUM_ILLUMINATION_SOURCES);}else +{fragColor+=u_shadows[i]*(1.0-2.0*shade)/float(NUM_ILLUMINATION_SOURCES);}}}void combined_hillshade(vec2 deriv){deriv=deriv*u_exaggeration*2.0;float azimuth=u_azimuths[0]+PI;float cos_az=cos(azimuth);float sin_az=sin(azimuth);float cos_alt=cos(u_altitudes[0]);float sin_alt=sin(u_altitudes[0]);float cang=acos((sin_alt-(deriv.y*cos_az*cos_alt-deriv.x*sin_az*cos_alt))/sqrt(1.0+dot(deriv,deriv)));cang=clamp(cang,0.0,PI/2.0);float shade=cang*atan(length(deriv))*4.0/PI/PI;float highlight=(PI/2.0-cang)*atan(length(deriv))*4.0/PI/PI;fragColor=u_shadows[0]*shade+u_highlights[0]*highlight;}void main() {vec4 pixel=texture(u_image,v_pos);float scaleFactor=cos(radians((u_latrange[0]-u_latrange[1])*(1.0-v_pos.y)+u_latrange[1]));vec2 deriv=((pixel.rg*8.0)-4.0)/scaleFactor;if (u_method==BASIC) {basic_hillshade(deriv);} else if (u_method==COMBINED) {combined_hillshade(deriv);} else if (u_method==IGOR) {igor_hillshade(deriv);} else if (u_method==MULTIDIRECTIONAL) {multidirectional_hillshade(deriv);} else if (u_method==STANDARD) {standard_hillshade(deriv);} else {standard_hillshade(deriv);} +#ifdef OVERDRAW_INSPECTOR +fragColor=vec4(1.0); +#endif +}`,"uniform mat4 u_matrix;in vec2 a_pos;out vec2 v_pos;void main() {gl_Position=projectTile(a_pos,a_pos);v_pos=a_pos/8192.0;if (a_pos.y <-32767.5) {v_pos.y=0.0;}if (a_pos.y > 32766.5) {v_pos.y=1.0;}}"),line:Zn(`uniform lowp float u_device_pixel_ratio;in vec2 v_width2;in vec2 v_normal;in float v_gamma_scale; +#ifdef GLOBE +in float v_depth; +#endif +#pragma mapbox: define highp vec4 color +#pragma mapbox: define lowp float blur +#pragma mapbox: define lowp float opacity +void main() { +#pragma mapbox: initialize highp vec4 color +#pragma mapbox: initialize lowp float blur +#pragma mapbox: initialize lowp float opacity +float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);fragColor=color*(alpha*opacity); +#ifdef GLOBE +if (v_depth > 1.0) {discard;} +#endif +#ifdef OVERDRAW_INSPECTOR +fragColor=vec4(1.0); +#endif +}`,` +#define scale 0.015873016 +in vec2 a_pos_normal;in vec4 a_data;uniform vec2 u_translation;uniform mediump float u_ratio;uniform vec2 u_units_to_pixels;uniform lowp float u_device_pixel_ratio;out vec2 v_normal;out vec2 v_width2;out float v_gamma_scale;out highp float v_linesofar; +#ifdef GLOBE +out float v_depth; +#endif +#pragma mapbox: define highp vec4 color +#pragma mapbox: define lowp float blur +#pragma mapbox: define lowp float opacity +#pragma mapbox: define mediump float gapwidth +#pragma mapbox: define lowp float offset +#pragma mapbox: define mediump float width +void main() { +#pragma mapbox: initialize highp vec4 color +#pragma mapbox: initialize lowp float blur +#pragma mapbox: initialize lowp float opacity +#pragma mapbox: initialize mediump float gapwidth +#pragma mapbox: initialize lowp float offset +#pragma mapbox: initialize mediump float width +float ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=a_data.xy-128.0;float a_direction=mod(a_data.z,4.0)-1.0;v_linesofar=(floor(a_data.z/4.0)+a_data.w*64.0)*2.0;vec2 pos=floor(a_pos_normal*0.5);mediump vec2 normal=a_pos_normal-2.0*pos;normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);float adjustedThickness=projectLineThickness(pos.y);vec4 projected_no_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation);vec4 projected_with_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation+dist/u_ratio*adjustedThickness);gl_Position=projected_with_extrude; +#ifdef GLOBE +v_depth=gl_Position.z/gl_Position.w; +#endif +#ifdef TERRAIN3D +v_gamma_scale=1.0; +#else +float extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length((projected_with_extrude.xy-projected_no_extrude.xy)/projected_with_extrude.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective; +#endif +v_width2=vec2(outset,inset);}`),lineGradient:Zn(`uniform lowp float u_device_pixel_ratio;uniform sampler2D u_image;in vec2 v_width2;in vec2 v_normal;in float v_gamma_scale;in highp vec2 v_uv; +#ifdef GLOBE +in float v_depth; +#endif +#pragma mapbox: define lowp float blur +#pragma mapbox: define lowp float opacity +void main() { +#pragma mapbox: initialize lowp float blur +#pragma mapbox: initialize lowp float opacity +float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);vec4 color=texture(u_image,v_uv);fragColor=color*(alpha*opacity); +#ifdef GLOBE +if (v_depth > 1.0) {discard;} +#endif +#ifdef OVERDRAW_INSPECTOR +fragColor=vec4(1.0); +#endif +}`,` +#define scale 0.015873016 +in vec2 a_pos_normal;in vec4 a_data;in float a_uv_x;in float a_split_index;uniform vec2 u_translation;uniform mediump float u_ratio;uniform lowp float u_device_pixel_ratio;uniform vec2 u_units_to_pixels;uniform float u_image_height;out vec2 v_normal;out vec2 v_width2;out float v_gamma_scale;out highp vec2 v_uv; +#ifdef GLOBE +out float v_depth; +#endif +#pragma mapbox: define lowp float blur +#pragma mapbox: define lowp float opacity +#pragma mapbox: define mediump float gapwidth +#pragma mapbox: define lowp float offset +#pragma mapbox: define mediump float width +void main() { +#pragma mapbox: initialize lowp float blur +#pragma mapbox: initialize lowp float opacity +#pragma mapbox: initialize mediump float gapwidth +#pragma mapbox: initialize lowp float offset +#pragma mapbox: initialize mediump float width +float ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=a_data.xy-128.0;float a_direction=mod(a_data.z,4.0)-1.0;highp float texel_height=1.0/u_image_height;highp float half_texel_height=0.5*texel_height;v_uv=vec2(a_uv_x,a_split_index*texel_height-half_texel_height);vec2 pos=floor(a_pos_normal*0.5);mediump vec2 normal=a_pos_normal-2.0*pos;normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);float adjustedThickness=projectLineThickness(pos.y);vec4 projected_no_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation);vec4 projected_with_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation+dist/u_ratio*adjustedThickness);gl_Position=projected_with_extrude; +#ifdef GLOBE +v_depth=gl_Position.z/gl_Position.w; +#endif +#ifdef TERRAIN3D +v_gamma_scale=1.0; +#else +float extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length((projected_with_extrude.xy-projected_no_extrude.xy)/projected_with_extrude.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective; +#endif +v_width2=vec2(outset,inset);}`),linePattern:Zn(`#ifdef GL_ES +precision highp float; +#endif +uniform lowp float u_device_pixel_ratio;uniform vec2 u_texsize;uniform float u_fade;uniform mediump vec3 u_scale;uniform sampler2D u_image;in vec2 v_normal;in vec2 v_width2;in float v_linesofar;in float v_gamma_scale;in float v_width; +#ifdef GLOBE +in float v_depth; +#endif +#pragma mapbox: define lowp vec4 pattern_from +#pragma mapbox: define lowp vec4 pattern_to +#pragma mapbox: define lowp float pixel_ratio_from +#pragma mapbox: define lowp float pixel_ratio_to +#pragma mapbox: define lowp float blur +#pragma mapbox: define lowp float opacity +void main() { +#pragma mapbox: initialize mediump vec4 pattern_from +#pragma mapbox: initialize mediump vec4 pattern_to +#pragma mapbox: initialize lowp float pixel_ratio_from +#pragma mapbox: initialize lowp float pixel_ratio_to +#pragma mapbox: initialize lowp float blur +#pragma mapbox: initialize lowp float opacity +vec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;float tileZoomRatio=u_scale.x;float fromScale=u_scale.y;float toScale=u_scale.z;vec2 display_size_a=(pattern_br_a-pattern_tl_a)/pixel_ratio_from;vec2 display_size_b=(pattern_br_b-pattern_tl_b)/pixel_ratio_to;vec2 pattern_size_a=vec2(display_size_a.x*fromScale/tileZoomRatio,display_size_a.y);vec2 pattern_size_b=vec2(display_size_b.x*toScale/tileZoomRatio,display_size_b.y);float aspect_a=display_size_a.y/v_width;float aspect_b=display_size_b.y/v_width;float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);float x_a=mod(v_linesofar/pattern_size_a.x*aspect_a,1.0);float x_b=mod(v_linesofar/pattern_size_b.x*aspect_b,1.0);float y=0.5*v_normal.y+0.5;vec2 texel_size=1.0/u_texsize;vec2 pos_a=mix(pattern_tl_a*texel_size-texel_size,pattern_br_a*texel_size+texel_size,vec2(x_a,y));vec2 pos_b=mix(pattern_tl_b*texel_size-texel_size,pattern_br_b*texel_size+texel_size,vec2(x_b,y));vec4 color=mix(texture(u_image,pos_a),texture(u_image,pos_b),u_fade);fragColor=color*alpha*opacity; +#ifdef GLOBE +if (v_depth > 1.0) {discard;} +#endif +#ifdef OVERDRAW_INSPECTOR +fragColor=vec4(1.0); +#endif +}`,` +#define scale 0.015873016 +#define LINE_DISTANCE_SCALE 2.0 +in vec2 a_pos_normal;in vec4 a_data;uniform vec2 u_translation;uniform vec2 u_units_to_pixels;uniform mediump float u_ratio;uniform lowp float u_device_pixel_ratio;out vec2 v_normal;out vec2 v_width2;out float v_linesofar;out float v_gamma_scale;out float v_width; +#ifdef GLOBE +out float v_depth; +#endif +#pragma mapbox: define lowp float blur +#pragma mapbox: define lowp float opacity +#pragma mapbox: define lowp float offset +#pragma mapbox: define mediump float gapwidth +#pragma mapbox: define mediump float width +#pragma mapbox: define lowp float floorwidth +#pragma mapbox: define lowp vec4 pattern_from +#pragma mapbox: define lowp vec4 pattern_to +#pragma mapbox: define lowp float pixel_ratio_from +#pragma mapbox: define lowp float pixel_ratio_to +void main() { +#pragma mapbox: initialize lowp float blur +#pragma mapbox: initialize lowp float opacity +#pragma mapbox: initialize lowp float offset +#pragma mapbox: initialize mediump float gapwidth +#pragma mapbox: initialize mediump float width +#pragma mapbox: initialize lowp float floorwidth +#pragma mapbox: initialize mediump vec4 pattern_from +#pragma mapbox: initialize mediump vec4 pattern_to +#pragma mapbox: initialize lowp float pixel_ratio_from +#pragma mapbox: initialize lowp float pixel_ratio_to +float ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=a_data.xy-128.0;float a_direction=mod(a_data.z,4.0)-1.0;float a_linesofar=(floor(a_data.z/4.0)+a_data.w*64.0)*LINE_DISTANCE_SCALE;vec2 pos=floor(a_pos_normal*0.5);mediump vec2 normal=a_pos_normal-2.0*pos;normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);float adjustedThickness=projectLineThickness(pos.y);vec4 projected_no_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation);vec4 projected_with_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation+dist/u_ratio*adjustedThickness);gl_Position=projected_with_extrude; +#ifdef GLOBE +v_depth=gl_Position.z/gl_Position.w; +#endif +#ifdef TERRAIN3D +v_gamma_scale=1.0; +#else +float extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length((projected_with_extrude.xy-projected_no_extrude.xy)/projected_with_extrude.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective; +#endif +v_linesofar=a_linesofar;v_width2=vec2(outset,inset);v_width=floorwidth;}`),lineSDF:Zn(`uniform lowp float u_device_pixel_ratio;uniform lowp float u_lineatlas_width;uniform sampler2D u_image;uniform float u_mix;in vec2 v_normal;in vec2 v_width2;in vec2 v_tex_a;in vec2 v_tex_b;in float v_gamma_scale; +#ifdef GLOBE +in float v_depth; +#endif +#pragma mapbox: define highp vec4 color +#pragma mapbox: define lowp float blur +#pragma mapbox: define lowp float opacity +#pragma mapbox: define mediump float width +#pragma mapbox: define lowp float floorwidth +#pragma mapbox: define mediump vec4 dasharray_from +#pragma mapbox: define mediump vec4 dasharray_to +void main() { +#pragma mapbox: initialize highp vec4 color +#pragma mapbox: initialize lowp float blur +#pragma mapbox: initialize lowp float opacity +#pragma mapbox: initialize mediump float width +#pragma mapbox: initialize lowp float floorwidth +#pragma mapbox: initialize mediump vec4 dasharray_from +#pragma mapbox: initialize mediump vec4 dasharray_to +float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);float sdfdist_a=texture(u_image,v_tex_a).a;float sdfdist_b=texture(u_image,v_tex_b).a;float sdfdist=mix(sdfdist_a,sdfdist_b,u_mix);float sdfgamma=(u_lineatlas_width/256.0/u_device_pixel_ratio)/min(dasharray_from.w,dasharray_to.w);alpha*=smoothstep(0.5-sdfgamma/floorwidth,0.5+sdfgamma/floorwidth,sdfdist);fragColor=color*(alpha*opacity); +#ifdef GLOBE +if (v_depth > 1.0) {discard;} +#endif +#ifdef OVERDRAW_INSPECTOR +fragColor=vec4(1.0); +#endif +}`,` +#define scale 0.015873016 +#define LINE_DISTANCE_SCALE 2.0 +in vec2 a_pos_normal;in vec4 a_data;uniform vec2 u_translation;uniform mediump float u_ratio;uniform lowp float u_device_pixel_ratio;uniform vec2 u_units_to_pixels;uniform float u_tileratio;uniform float u_crossfade_from;uniform float u_crossfade_to;uniform float u_lineatlas_height;out vec2 v_normal;out vec2 v_width2;out vec2 v_tex_a;out vec2 v_tex_b;out float v_gamma_scale; +#ifdef GLOBE +out float v_depth; +#endif +#pragma mapbox: define highp vec4 color +#pragma mapbox: define lowp float blur +#pragma mapbox: define lowp float opacity +#pragma mapbox: define mediump float gapwidth +#pragma mapbox: define lowp float offset +#pragma mapbox: define mediump float width +#pragma mapbox: define lowp float floorwidth +#pragma mapbox: define mediump vec4 dasharray_from +#pragma mapbox: define mediump vec4 dasharray_to +void main() { +#pragma mapbox: initialize highp vec4 color +#pragma mapbox: initialize lowp float blur +#pragma mapbox: initialize lowp float opacity +#pragma mapbox: initialize mediump float gapwidth +#pragma mapbox: initialize lowp float offset +#pragma mapbox: initialize mediump float width +#pragma mapbox: initialize lowp float floorwidth +#pragma mapbox: initialize mediump vec4 dasharray_from +#pragma mapbox: initialize mediump vec4 dasharray_to +float ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=a_data.xy-128.0;float a_direction=mod(a_data.z,4.0)-1.0;float a_linesofar=(floor(a_data.z/4.0)+a_data.w*64.0)*LINE_DISTANCE_SCALE;vec2 pos=floor(a_pos_normal*0.5);mediump vec2 normal=a_pos_normal-2.0*pos;normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);float adjustedThickness=projectLineThickness(pos.y);vec4 projected_no_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation);vec4 projected_with_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation+dist/u_ratio*adjustedThickness);gl_Position=projected_with_extrude; +#ifdef GLOBE +v_depth=gl_Position.z/gl_Position.w; +#endif +#ifdef TERRAIN3D +v_gamma_scale=1.0; +#else +float extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length((projected_with_extrude.xy-projected_no_extrude.xy)/projected_with_extrude.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective; +#endif +float u_patternscale_a_x=u_tileratio/dasharray_from.w/u_crossfade_from;float u_patternscale_a_y=-dasharray_from.z/2.0/u_lineatlas_height;float u_patternscale_b_x=u_tileratio/dasharray_to.w/u_crossfade_to;float u_patternscale_b_y=-dasharray_to.z/2.0/u_lineatlas_height;v_tex_a=vec2(a_linesofar*u_patternscale_a_x/floorwidth,normal.y*u_patternscale_a_y+(float(dasharray_from.y)+0.5)/u_lineatlas_height);v_tex_b=vec2(a_linesofar*u_patternscale_b_x/floorwidth,normal.y*u_patternscale_b_y+(float(dasharray_to.y)+0.5)/u_lineatlas_height);v_width2=vec2(outset,inset);}`),lineGradientSDF:Zn(`uniform lowp float u_device_pixel_ratio;uniform sampler2D u_image;uniform sampler2D u_image_dash;uniform float u_mix;uniform lowp float u_lineatlas_width;in vec2 v_normal;in vec2 v_width2;in vec2 v_tex_a;in vec2 v_tex_b;in float v_gamma_scale;in highp vec2 v_uv; +#ifdef GLOBE +in float v_depth; +#endif +#pragma mapbox: define lowp float blur +#pragma mapbox: define lowp float opacity +#pragma mapbox: define mediump float width +#pragma mapbox: define lowp float floorwidth +#pragma mapbox: define mediump vec4 dasharray_from +#pragma mapbox: define mediump vec4 dasharray_to +void main() { +#pragma mapbox: initialize lowp float blur +#pragma mapbox: initialize lowp float opacity +#pragma mapbox: initialize mediump float width +#pragma mapbox: initialize lowp float floorwidth +#pragma mapbox: initialize mediump vec4 dasharray_from +#pragma mapbox: initialize mediump vec4 dasharray_to +float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);vec4 color=texture(u_image,v_uv);float sdfdist_a=texture(u_image_dash,v_tex_a).a;float sdfdist_b=texture(u_image_dash,v_tex_b).a;float sdfdist=mix(sdfdist_a,sdfdist_b,u_mix);float sdfgamma=(u_lineatlas_width/256.0)/min(dasharray_from.w,dasharray_to.w);float dash_alpha=smoothstep(0.5-sdfgamma/floorwidth,0.5+sdfgamma/floorwidth,sdfdist);fragColor=color*(alpha*dash_alpha*opacity); +#ifdef GLOBE +if (v_depth > 1.0) {discard;} +#endif +#ifdef OVERDRAW_INSPECTOR +fragColor=vec4(1.0); +#endif +}`,` +#define scale 0.015873016 +#define LINE_DISTANCE_SCALE 2.0 +in vec2 a_pos_normal;in vec4 a_data;in float a_uv_x;in float a_split_index;uniform vec2 u_translation;uniform mediump float u_ratio;uniform lowp float u_device_pixel_ratio;uniform vec2 u_units_to_pixels;uniform float u_image_height;uniform float u_tileratio;uniform float u_crossfade_from;uniform float u_crossfade_to;uniform float u_lineatlas_height;out vec2 v_normal;out vec2 v_width2;out float v_gamma_scale;out highp vec2 v_uv;out vec2 v_tex_a;out vec2 v_tex_b; +#ifdef GLOBE +out float v_depth; +#endif +#pragma mapbox: define lowp float blur +#pragma mapbox: define lowp float opacity +#pragma mapbox: define mediump float gapwidth +#pragma mapbox: define lowp float offset +#pragma mapbox: define mediump float width +#pragma mapbox: define lowp float floorwidth +#pragma mapbox: define mediump vec4 dasharray_from +#pragma mapbox: define mediump vec4 dasharray_to +void main() { +#pragma mapbox: initialize lowp float blur +#pragma mapbox: initialize lowp float opacity +#pragma mapbox: initialize mediump float gapwidth +#pragma mapbox: initialize lowp float offset +#pragma mapbox: initialize mediump float width +#pragma mapbox: initialize lowp float floorwidth +#pragma mapbox: initialize mediump vec4 dasharray_from +#pragma mapbox: initialize mediump vec4 dasharray_to +float ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=a_data.xy-128.0;float a_direction=mod(a_data.z,4.0)-1.0;float a_linesofar=(floor(a_data.z/4.0)+a_data.w*64.0)*LINE_DISTANCE_SCALE;float texel_height=1.0/u_image_height;float half_texel_height=0.5*texel_height;v_uv=vec2(a_uv_x,a_split_index*texel_height-half_texel_height);vec2 pos=floor(a_pos_normal*0.5);mediump vec2 normal=a_pos_normal-2.0*pos;normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);float adjustedThickness=projectLineThickness(pos.y);vec4 projected_no_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation);vec4 projected_with_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation+dist/u_ratio*adjustedThickness);gl_Position=projected_with_extrude; +#ifdef GLOBE +v_depth=gl_Position.z/gl_Position.w; +#endif +#ifdef TERRAIN3D +v_gamma_scale=1.0; +#else +float extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length((projected_with_extrude.xy-projected_no_extrude.xy)/projected_with_extrude.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective; +#endif +float u_patternscale_a_x=u_tileratio/dasharray_from.w/u_crossfade_from;float u_patternscale_a_y=-dasharray_from.z/2.0/u_lineatlas_height;float u_patternscale_b_x=u_tileratio/dasharray_to.w/u_crossfade_to;float u_patternscale_b_y=-dasharray_to.z/2.0/u_lineatlas_height;v_tex_a=vec2(a_linesofar*u_patternscale_a_x/floorwidth,normal.y*u_patternscale_a_y+(float(dasharray_from.y)+0.5)/u_lineatlas_height);v_tex_b=vec2(a_linesofar*u_patternscale_b_x/floorwidth,normal.y*u_patternscale_b_y+(float(dasharray_to.y)+0.5)/u_lineatlas_height);v_width2=vec2(outset,inset);}`),raster:Zn(`uniform float u_fade_t;uniform float u_opacity;uniform sampler2D u_image0;uniform sampler2D u_image1;in vec2 v_pos0;in vec2 v_pos1;uniform float u_brightness_low;uniform float u_brightness_high;uniform float u_saturation_factor;uniform float u_contrast_factor;uniform vec3 u_spin_weights;void main() {vec4 color0=texture(u_image0,v_pos0);vec4 color1=texture(u_image1,v_pos1);if (color0.a > 0.0) {color0.rgb=color0.rgb/color0.a;}if (color1.a > 0.0) {color1.rgb=color1.rgb/color1.a;}vec4 color=mix(color0,color1,u_fade_t);color.a*=u_opacity;vec3 rgb=color.rgb;rgb=vec3(dot(rgb,u_spin_weights.xyz),dot(rgb,u_spin_weights.zxy),dot(rgb,u_spin_weights.yzx));float average=(color.r+color.g+color.b)/3.0;rgb+=(average-rgb)*u_saturation_factor;rgb=(rgb-0.5)*u_contrast_factor+0.5;vec3 u_high_vec=vec3(u_brightness_low,u_brightness_low,u_brightness_low);vec3 u_low_vec=vec3(u_brightness_high,u_brightness_high,u_brightness_high);fragColor=vec4(mix(u_high_vec,u_low_vec,rgb)*color.a,color.a); +#ifdef OVERDRAW_INSPECTOR +fragColor=vec4(1.0); +#endif +}`,`uniform vec2 u_tl_parent;uniform float u_scale_parent;uniform float u_buffer_scale;uniform vec4 u_coords_top;uniform vec4 u_coords_bottom;in vec2 a_pos;out vec2 v_pos0;out vec2 v_pos1;void main() {vec2 fractionalPos=a_pos/8192.0;vec2 position=mix(mix(u_coords_top.xy,u_coords_top.zw,fractionalPos.x),mix(u_coords_bottom.xy,u_coords_bottom.zw,fractionalPos.x),fractionalPos.y);gl_Position=projectTile(position,position);v_pos0=((fractionalPos-0.5)/u_buffer_scale)+0.5; +#ifdef GLOBE +if (a_pos.y <-32767.5) {v_pos0.y=0.0;}if (a_pos.y > 32766.5) {v_pos0.y=1.0;} +#endif +v_pos1=(v_pos0*u_scale_parent)+u_tl_parent;}`),symbolIcon:Zn(`uniform sampler2D u_texture;in vec2 v_tex;in float v_fade_opacity; +#pragma mapbox: define lowp float opacity +void main() { +#pragma mapbox: initialize lowp float opacity +lowp float alpha=opacity*v_fade_opacity;fragColor=texture(u_texture,v_tex)*alpha; +#ifdef OVERDRAW_INSPECTOR +fragColor=vec4(1.0); +#endif +}`,`in vec4 a_pos_offset;in vec4 a_data;in vec4 a_pixeloffset;in vec3 a_projected_pos;in float a_fade_opacity;uniform bool u_is_size_zoom_constant;uniform bool u_is_size_feature_constant;uniform highp float u_size_t;uniform highp float u_size;uniform highp float u_camera_to_center_distance;uniform highp float u_pitch;uniform bool u_rotate_symbol;uniform highp float u_aspect_ratio;uniform float u_fade_change;uniform mat4 u_label_plane_matrix;uniform mat4 u_coord_matrix;uniform bool u_is_text;uniform bool u_pitch_with_map;uniform vec2 u_texsize;uniform bool u_is_along_line;uniform bool u_is_variable_anchor;uniform vec2 u_translation;uniform float u_pitched_scale;out vec2 v_tex;out float v_fade_opacity; +#pragma mapbox: define lowp float opacity +void main() { +#pragma mapbox: initialize lowp float opacity +vec2 a_pos=a_pos_offset.xy;vec2 a_offset=a_pos_offset.zw;vec2 a_tex=a_data.xy;vec2 a_size=a_data.zw;float a_size_min=floor(a_size[0]*0.5);vec2 a_pxoffset=a_pixeloffset.xy;vec2 a_minFontScale=a_pixeloffset.zw/256.0;float ele=get_elevation(a_pos);highp float segment_angle=-a_projected_pos[2];float size;if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {size=mix(a_size_min,a_size[1],u_size_t)/128.0;} else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {size=a_size_min/128.0;} else {size=u_size;}vec2 translated_a_pos=a_pos+u_translation;vec4 projectedPoint=projectTileWithElevation(translated_a_pos,ele);highp float camera_to_anchor_distance=projectedPoint.w;highp float distance_ratio=u_pitch_with_map ? +camera_to_anchor_distance/u_camera_to_center_distance : +u_camera_to_center_distance/camera_to_anchor_distance;highp float perspective_ratio=clamp(0.5+0.5*distance_ratio,0.0,4.0);size*=perspective_ratio;float fontScale=u_is_text ? size/24.0 : size;highp float symbol_rotation=0.0;if (u_rotate_symbol) {vec4 offsetProjectedPoint=projectTileWithElevation(translated_a_pos+vec2(1,0),ele);vec2 a=projectedPoint.xy/projectedPoint.w;vec2 b=offsetProjectedPoint.xy/offsetProjectedPoint.w;symbol_rotation=atan((b.y-a.y)/u_aspect_ratio,b.x-a.x);}highp float angle_sin=sin(segment_angle+symbol_rotation);highp float angle_cos=cos(segment_angle+symbol_rotation);mat2 rotation_matrix=mat2(angle_cos,-1.0*angle_sin,angle_sin,angle_cos);vec4 projected_pos;if (u_is_along_line || u_is_variable_anchor) {projected_pos=vec4(a_projected_pos.xy,ele,1.0);} else if (u_pitch_with_map) {projected_pos=u_label_plane_matrix*vec4(a_projected_pos.xy+u_translation,ele,1.0);} else {projected_pos=u_label_plane_matrix*projectTileWithElevation(a_projected_pos.xy+u_translation,ele);}float z=float(u_pitch_with_map)*projected_pos.z/projected_pos.w;float projectionScaling=1.0; +#ifdef GLOBE +if(u_pitch_with_map) {float anchor_pos_tile_y=(u_coord_matrix*vec4(projected_pos.xy/projected_pos.w,z,1.0)).y;projectionScaling=mix(projectionScaling,1.0/circumferenceRatioAtTileY(anchor_pos_tile_y)*u_pitched_scale,u_projection_transition);} +#endif +vec4 finalPos=u_coord_matrix*vec4(projected_pos.xy/projected_pos.w+rotation_matrix*(a_offset/32.0*max(a_minFontScale,fontScale)+a_pxoffset/16.0)*projectionScaling,z,1.0);if(u_pitch_with_map) {finalPos=projectTileWithElevation(finalPos.xy,finalPos.z);}gl_Position=finalPos;v_tex=a_tex/u_texsize;vec2 fade_opacity=unpack_opacity(a_fade_opacity);float fade_change=fade_opacity[1] > 0.5 ? u_fade_change :-u_fade_change;float visibility=calculate_visibility(projectedPoint);v_fade_opacity=max(0.0,min(visibility,fade_opacity[0]+fade_change));}`),symbolSDF:Zn(`#define SDF_PX 8.0 +uniform bool u_is_halo;uniform sampler2D u_texture;uniform highp float u_gamma_scale;uniform lowp float u_device_pixel_ratio;uniform bool u_is_text;in vec2 v_data0;in vec3 v_data1; +#pragma mapbox: define highp vec4 fill_color +#pragma mapbox: define highp vec4 halo_color +#pragma mapbox: define lowp float opacity +#pragma mapbox: define lowp float halo_width +#pragma mapbox: define lowp float halo_blur +void main() { +#pragma mapbox: initialize highp vec4 fill_color +#pragma mapbox: initialize highp vec4 halo_color +#pragma mapbox: initialize lowp float opacity +#pragma mapbox: initialize lowp float halo_width +#pragma mapbox: initialize lowp float halo_blur +float EDGE_GAMMA=0.105/u_device_pixel_ratio;vec2 tex=v_data0.xy;float gamma_scale=v_data1.x;float size=v_data1.y;float fade_opacity=v_data1[2];float fontScale=u_is_text ? size/24.0 : size;lowp vec4 color=fill_color;highp float gamma=EDGE_GAMMA/(fontScale*u_gamma_scale);lowp float inner_edge=(256.0-64.0)/256.0;if (u_is_halo) {color=halo_color;gamma=(halo_blur*1.19/SDF_PX+EDGE_GAMMA)/(fontScale*u_gamma_scale);inner_edge=inner_edge+gamma*gamma_scale;}lowp float dist=texture(u_texture,tex).a;highp float gamma_scaled=gamma*gamma_scale;highp float alpha=smoothstep(inner_edge-gamma_scaled,inner_edge+gamma_scaled,dist);if (u_is_halo) {lowp float halo_edge=(6.0-halo_width/fontScale)/SDF_PX;alpha=min(smoothstep(halo_edge-gamma_scaled,halo_edge+gamma_scaled,dist),1.0-alpha);}fragColor=color*(alpha*opacity*fade_opacity); +#ifdef OVERDRAW_INSPECTOR +fragColor=vec4(1.0); +#endif +}`,`in vec4 a_pos_offset;in vec4 a_data;in vec4 a_pixeloffset;in vec3 a_projected_pos;in float a_fade_opacity;uniform bool u_is_size_zoom_constant;uniform bool u_is_size_feature_constant;uniform highp float u_size_t;uniform highp float u_size;uniform mat4 u_label_plane_matrix;uniform mat4 u_coord_matrix;uniform bool u_is_text;uniform bool u_pitch_with_map;uniform bool u_is_along_line;uniform bool u_is_variable_anchor;uniform highp float u_pitch;uniform bool u_rotate_symbol;uniform highp float u_aspect_ratio;uniform highp float u_camera_to_center_distance;uniform float u_fade_change;uniform vec2 u_texsize;uniform vec2 u_translation;uniform float u_pitched_scale;out vec2 v_data0;out vec3 v_data1; +#pragma mapbox: define highp vec4 fill_color +#pragma mapbox: define highp vec4 halo_color +#pragma mapbox: define lowp float opacity +#pragma mapbox: define lowp float halo_width +#pragma mapbox: define lowp float halo_blur +void main() { +#pragma mapbox: initialize highp vec4 fill_color +#pragma mapbox: initialize highp vec4 halo_color +#pragma mapbox: initialize lowp float opacity +#pragma mapbox: initialize lowp float halo_width +#pragma mapbox: initialize lowp float halo_blur +vec2 a_pos=a_pos_offset.xy;vec2 a_offset=a_pos_offset.zw;vec2 a_tex=a_data.xy;vec2 a_size=a_data.zw;float a_size_min=floor(a_size[0]*0.5);vec2 a_pxoffset=a_pixeloffset.xy;float ele=get_elevation(a_pos);highp float segment_angle=-a_projected_pos[2];float size;if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {size=mix(a_size_min,a_size[1],u_size_t)/128.0;} else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {size=a_size_min/128.0;} else {size=u_size;}vec2 translated_a_pos=a_pos+u_translation;vec4 projectedPoint=projectTileWithElevation(translated_a_pos,ele);highp float camera_to_anchor_distance=projectedPoint.w;highp float distance_ratio=u_pitch_with_map ? +camera_to_anchor_distance/u_camera_to_center_distance : +u_camera_to_center_distance/camera_to_anchor_distance;highp float perspective_ratio=clamp(0.5+0.5*distance_ratio,0.0,4.0);size*=perspective_ratio;float fontScale=u_is_text ? size/24.0 : size;highp float symbol_rotation=0.0;if (u_rotate_symbol) {vec4 offsetProjectedPoint=projectTileWithElevation(translated_a_pos+vec2(1,0),ele);vec2 a=projectedPoint.xy/projectedPoint.w;vec2 b=offsetProjectedPoint.xy/offsetProjectedPoint.w;symbol_rotation=atan((b.y-a.y)/u_aspect_ratio,b.x-a.x);}highp float angle_sin=sin(segment_angle+symbol_rotation);highp float angle_cos=cos(segment_angle+symbol_rotation);mat2 rotation_matrix=mat2(angle_cos,-1.0*angle_sin,angle_sin,angle_cos);vec4 projected_pos;if (u_is_along_line || u_is_variable_anchor) {projected_pos=vec4(a_projected_pos.xy,ele,1.0);} else if (u_pitch_with_map) {projected_pos=u_label_plane_matrix*vec4(a_projected_pos.xy+u_translation,ele,1.0);} else {projected_pos=u_label_plane_matrix*projectTileWithElevation(a_projected_pos.xy+u_translation,ele);}float z=float(u_pitch_with_map)*projected_pos.z/projected_pos.w;float projectionScaling=1.0; +#ifdef GLOBE +if(u_pitch_with_map) {float anchor_pos_tile_y=(u_coord_matrix*vec4(projected_pos.xy/projected_pos.w,z,1.0)).y;projectionScaling=mix(projectionScaling,1.0/circumferenceRatioAtTileY(anchor_pos_tile_y)*u_pitched_scale,u_projection_transition);} +#endif +vec4 finalPos=u_coord_matrix*vec4(projected_pos.xy/projected_pos.w+rotation_matrix*(a_offset/32.0*fontScale+a_pxoffset)*projectionScaling,z,1.0);if(u_pitch_with_map) {finalPos=projectTileWithElevation(finalPos.xy,finalPos.z);}float gamma_scale=finalPos.w;gl_Position=finalPos;vec2 fade_opacity=unpack_opacity(a_fade_opacity);float visibility=calculate_visibility(projectedPoint);float fade_change=fade_opacity[1] > 0.5 ? u_fade_change :-u_fade_change;float interpolated_fade_opacity=max(0.0,min(visibility,fade_opacity[0]+fade_change));v_data0=a_tex/u_texsize;v_data1=vec3(gamma_scale,size,interpolated_fade_opacity);}`),symbolTextAndIcon:Zn(`#define SDF_PX 8.0 +#define SDF 1.0 +#define ICON 0.0 +uniform bool u_is_halo;uniform sampler2D u_texture;uniform sampler2D u_texture_icon;uniform highp float u_gamma_scale;uniform lowp float u_device_pixel_ratio;in vec4 v_data0;in vec4 v_data1; +#pragma mapbox: define highp vec4 fill_color +#pragma mapbox: define highp vec4 halo_color +#pragma mapbox: define lowp float opacity +#pragma mapbox: define lowp float halo_width +#pragma mapbox: define lowp float halo_blur +void main() { +#pragma mapbox: initialize highp vec4 fill_color +#pragma mapbox: initialize highp vec4 halo_color +#pragma mapbox: initialize lowp float opacity +#pragma mapbox: initialize lowp float halo_width +#pragma mapbox: initialize lowp float halo_blur +float fade_opacity=v_data1[2];if (v_data1.w==ICON) {vec2 tex_icon=v_data0.zw;lowp float alpha=opacity*fade_opacity;fragColor=texture(u_texture_icon,tex_icon)*alpha; +#ifdef OVERDRAW_INSPECTOR +fragColor=vec4(1.0); +#endif +return;}vec2 tex=v_data0.xy;float EDGE_GAMMA=0.105/u_device_pixel_ratio;float gamma_scale=v_data1.x;float size=v_data1.y;float fontScale=size/24.0;lowp vec4 color=fill_color;highp float gamma=EDGE_GAMMA/(fontScale*u_gamma_scale);lowp float buff=(256.0-64.0)/256.0;if (u_is_halo) {color=halo_color;gamma=(halo_blur*1.19/SDF_PX+EDGE_GAMMA)/(fontScale*u_gamma_scale);buff=(6.0-halo_width/fontScale)/SDF_PX;}lowp float dist=texture(u_texture,tex).a;highp float gamma_scaled=gamma*gamma_scale;highp float alpha=smoothstep(buff-gamma_scaled,buff+gamma_scaled,dist);fragColor=color*(alpha*opacity*fade_opacity); +#ifdef OVERDRAW_INSPECTOR +fragColor=vec4(1.0); +#endif +}`,`in vec4 a_pos_offset;in vec4 a_data;in vec3 a_projected_pos;in float a_fade_opacity;uniform bool u_is_size_zoom_constant;uniform bool u_is_size_feature_constant;uniform highp float u_size_t;uniform highp float u_size;uniform mat4 u_label_plane_matrix;uniform mat4 u_coord_matrix;uniform bool u_is_text;uniform bool u_pitch_with_map;uniform highp float u_pitch;uniform bool u_rotate_symbol;uniform highp float u_aspect_ratio;uniform highp float u_camera_to_center_distance;uniform float u_fade_change;uniform vec2 u_texsize;uniform vec2 u_texsize_icon;uniform bool u_is_along_line;uniform bool u_is_variable_anchor;uniform vec2 u_translation;uniform float u_pitched_scale;out vec4 v_data0;out vec4 v_data1; +#pragma mapbox: define highp vec4 fill_color +#pragma mapbox: define highp vec4 halo_color +#pragma mapbox: define lowp float opacity +#pragma mapbox: define lowp float halo_width +#pragma mapbox: define lowp float halo_blur +void main() { +#pragma mapbox: initialize highp vec4 fill_color +#pragma mapbox: initialize highp vec4 halo_color +#pragma mapbox: initialize lowp float opacity +#pragma mapbox: initialize lowp float halo_width +#pragma mapbox: initialize lowp float halo_blur +vec2 a_pos=a_pos_offset.xy;vec2 a_offset=a_pos_offset.zw;vec2 a_tex=a_data.xy;vec2 a_size=a_data.zw;float a_size_min=floor(a_size[0]*0.5);float is_sdf=a_size[0]-2.0*a_size_min;float ele=get_elevation(a_pos);highp float segment_angle=-a_projected_pos[2];float size;if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {size=mix(a_size_min,a_size[1],u_size_t)/128.0;} else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {size=a_size_min/128.0;} else {size=u_size;}vec2 translated_a_pos=a_pos+u_translation;vec4 projectedPoint=projectTileWithElevation(translated_a_pos,ele);highp float camera_to_anchor_distance=projectedPoint.w;highp float distance_ratio=u_pitch_with_map ? +camera_to_anchor_distance/u_camera_to_center_distance : +u_camera_to_center_distance/camera_to_anchor_distance;highp float perspective_ratio=clamp(0.5+0.5*distance_ratio,0.0,4.0);size*=perspective_ratio;float fontScale=size/24.0;highp float symbol_rotation=0.0;if (u_rotate_symbol) {vec4 offsetProjectedPoint=projectTileWithElevation(translated_a_pos+vec2(1,0),ele);vec2 a=projectedPoint.xy/projectedPoint.w;vec2 b=offsetProjectedPoint.xy/offsetProjectedPoint.w;symbol_rotation=atan((b.y-a.y)/u_aspect_ratio,b.x-a.x);}highp float angle_sin=sin(segment_angle+symbol_rotation);highp float angle_cos=cos(segment_angle+symbol_rotation);mat2 rotation_matrix=mat2(angle_cos,-1.0*angle_sin,angle_sin,angle_cos);vec4 projected_pos;if (u_is_along_line || u_is_variable_anchor) {projected_pos=vec4(a_projected_pos.xy,ele,1.0);} else if (u_pitch_with_map) {projected_pos=u_label_plane_matrix*vec4(a_projected_pos.xy+u_translation,ele,1.0);} else {projected_pos=u_label_plane_matrix*projectTileWithElevation(a_projected_pos.xy+u_translation,ele);}float z=float(u_pitch_with_map)*projected_pos.z/projected_pos.w;float projectionScaling=1.0; +#ifdef GLOBE +if(u_pitch_with_map && !u_is_along_line) {float anchor_pos_tile_y=(u_coord_matrix*vec4(projected_pos.xy/projected_pos.w,z,1.0)).y;projectionScaling=mix(projectionScaling,1.0/circumferenceRatioAtTileY(anchor_pos_tile_y)*u_pitched_scale,u_projection_transition);} +#endif +vec4 finalPos=u_coord_matrix*vec4(projected_pos.xy/projected_pos.w+rotation_matrix*(a_offset/32.0*fontScale)*projectionScaling,z,1.0);if(u_pitch_with_map) {finalPos=projectTileWithElevation(finalPos.xy,finalPos.z);}float gamma_scale=finalPos.w;gl_Position=finalPos;vec2 fade_opacity=unpack_opacity(a_fade_opacity);float visibility=calculate_visibility(projectedPoint);float fade_change=fade_opacity[1] > 0.5 ? u_fade_change :-u_fade_change;float interpolated_fade_opacity=max(0.0,min(visibility,fade_opacity[0]+fade_change));v_data0.xy=a_tex/u_texsize;v_data0.zw=a_tex/u_texsize_icon;v_data1=vec4(gamma_scale,size,interpolated_fade_opacity,is_sdf);}`),terrain:Zn("uniform sampler2D u_texture;uniform vec4 u_fog_color;uniform vec4 u_horizon_color;uniform float u_fog_ground_blend;uniform float u_fog_ground_blend_opacity;uniform float u_horizon_fog_blend;uniform bool u_is_globe_mode;in vec2 v_texture_pos;in float v_fog_depth;const float gamma=2.2;vec4 gammaToLinear(vec4 color) {return pow(color,vec4(gamma));}vec4 linearToGamma(vec4 color) {return pow(color,vec4(1.0/gamma));}void main() {vec4 surface_color=texture(u_texture,vec2(v_texture_pos.x,1.0-v_texture_pos.y));if (!u_is_globe_mode && v_fog_depth > u_fog_ground_blend) {vec4 surface_color_linear=gammaToLinear(surface_color);float blend_color=smoothstep(0.0,1.0,max((v_fog_depth-u_horizon_fog_blend)/(1.0-u_horizon_fog_blend),0.0));vec4 fog_horizon_color_linear=mix(gammaToLinear(u_fog_color),gammaToLinear(u_horizon_color),blend_color);float factor_fog=max(v_fog_depth-u_fog_ground_blend,0.0)/(1.0-u_fog_ground_blend);fragColor=linearToGamma(mix(surface_color_linear,fog_horizon_color_linear,pow(factor_fog,2.0)*u_fog_ground_blend_opacity));} else {fragColor=surface_color;}}","in vec3 a_pos3d;uniform mat4 u_fog_matrix;uniform float u_ele_delta;out vec2 v_texture_pos;out float v_fog_depth;void main() {float ele=get_elevation(a_pos3d.xy);float ele_delta=a_pos3d.z==1.0 ? u_ele_delta : 0.0;v_texture_pos=a_pos3d.xy/8192.0;gl_Position=projectTileFor3D(a_pos3d.xy,get_elevation(a_pos3d.xy)-ele_delta);vec4 pos=u_fog_matrix*vec4(a_pos3d.xy,ele,1.0);v_fog_depth=pos.z/pos.w*0.5+0.5;}"),terrainDepth:Zn("in float v_depth;const highp vec4 bitSh=vec4(256.*256.*256.,256.*256.,256.,1.);const highp vec4 bitMsk=vec4(0.,vec3(1./256.0));highp vec4 pack(highp float value) {highp vec4 comp=fract(value*bitSh);comp-=comp.xxyz*bitMsk;return comp;}void main() {fragColor=pack(v_depth);}","in vec3 a_pos3d;uniform float u_ele_delta;out float v_depth;void main() {float ele=get_elevation(a_pos3d.xy);float ele_delta=a_pos3d.z==1.0 ? u_ele_delta : 0.0;gl_Position=projectTileFor3D(a_pos3d.xy,ele-ele_delta);v_depth=gl_Position.z/gl_Position.w;}"),terrainCoords:Zn("precision mediump float;uniform sampler2D u_texture;uniform float u_terrain_coords_id;in vec2 v_texture_pos;void main() {vec4 rgba=texture(u_texture,v_texture_pos);fragColor=vec4(rgba.r,rgba.g,rgba.b,u_terrain_coords_id);}","in vec3 a_pos3d;uniform float u_ele_delta;out vec2 v_texture_pos;void main() {float ele=get_elevation(a_pos3d.xy);float ele_delta=a_pos3d.z==1.0 ? u_ele_delta : 0.0;v_texture_pos=a_pos3d.xy/8192.0;gl_Position=projectTileFor3D(a_pos3d.xy,ele-ele_delta);}"),projectionErrorMeasurement:Zn("in vec4 v_output_error_encoded;void main() {fragColor=v_output_error_encoded;}","in vec2 a_pos;uniform highp float u_input;uniform highp float u_output_expected;out vec4 v_output_error_encoded;void main() {float real_output=2.0*atan(exp(PI-(u_input*PI*2.0)))-PI*0.5;float error=real_output-u_output_expected;float abs_error=abs(error)*128.0;v_output_error_encoded.x=min(floor(abs_error*256.0),255.0)/255.0;abs_error-=v_output_error_encoded.x;v_output_error_encoded.y=min(floor(abs_error*65536.0),255.0)/255.0;abs_error-=v_output_error_encoded.x/255.0;v_output_error_encoded.z=min(floor(abs_error*16777216.0),255.0)/255.0;v_output_error_encoded.w=error >=0.0 ? 1.0 : 0.0;gl_Position=vec4(a_pos,0.0,1.0);}"),atmosphere:Zn(`in vec3 view_direction;uniform vec3 u_sun_pos;uniform vec3 u_globe_position;uniform float u_globe_radius;uniform float u_atmosphere_blend;/**Shader use from https:*Made some change to adapt to MapLibre Globe geometry*/const float PI=3.141592653589793;const int iSteps=5;const int jSteps=3;/*radius of the planet*/const float EARTH_RADIUS=6371e3;/*radius of the atmosphere*/const float ATMOS_RADIUS=6471e3;vec2 rsi(vec3 r0,vec3 rd,float sr) {float a=dot(rd,rd);float b=2.0*dot(rd,r0);float c=dot(r0,r0)-(sr*sr);float d=(b*b)-4.0*a*c;if (d < 0.0) return vec2(1e5,-1e5);return vec2((-b-sqrt(d))/(2.0*a),(-b+sqrt(d))/(2.0*a));}vec4 atmosphere(vec3 r,vec3 r0,vec3 pSun,float iSun,float rPlanet,float rAtmos,vec3 kRlh,float kMie,float shRlh,float shMie,float g) {pSun=normalize(pSun);r=normalize(r);vec2 p=rsi(r0,r,rAtmos);if (p.x > p.y) {return vec4(0.0,0.0,0.0,1.0);}if (p.x < 0.0) {p.x=0.0;}vec3 pos=r0+r*p.x;vec2 p2=rsi(r0,r,rPlanet);if (p2.x <=p2.y && p2.x > 0.0) {p.y=min(p.y,p2.x);}float iStepSize=(p.y-p.x)/float(iSteps);float iTime=p.x+iStepSize*0.5;vec3 totalRlh=vec3(0,0,0);vec3 totalMie=vec3(0,0,0);float iOdRlh=0.0;float iOdMie=0.0;float mu=dot(r,pSun);float mumu=mu*mu;float gg=g*g;float pRlh=3.0/(16.0*PI)*(1.0+mumu);float pMie=3.0/(8.0*PI)*((1.0-gg)*(mumu+1.0))/(pow(1.0+gg-2.0*mu*g,1.5)*(2.0+gg));for (int i=0; i < iSteps; i++) {vec3 iPos=r0+r*iTime;float iHeight=length(iPos)-rPlanet;float odStepRlh=exp(-iHeight/shRlh)*iStepSize;float odStepMie=exp(-iHeight/shMie)*iStepSize;iOdRlh+=odStepRlh;iOdMie+=odStepMie;float jStepSize=rsi(iPos,pSun,rAtmos).y/float(jSteps);float jTime=jStepSize*0.5;float jOdRlh=0.0;float jOdMie=0.0;for (int j=0; j < jSteps; j++) {vec3 jPos=iPos+pSun*jTime;float jHeight=length(jPos)-rPlanet;jOdRlh+=exp(-jHeight/shRlh)*jStepSize;jOdMie+=exp(-jHeight/shMie)*jStepSize;jTime+=jStepSize;}vec3 attn=exp(-(kMie*(iOdMie+jOdMie)+kRlh*(iOdRlh+jOdRlh)));totalRlh+=odStepRlh*attn;totalMie+=odStepMie*attn;iTime+=iStepSize;}float opacity=exp(-(length(kRlh)*length(totalRlh)+kMie*length(totalMie)));vec3 color=iSun*(pRlh*kRlh*totalRlh+pMie*kMie*totalMie);return vec4(color,opacity);}void main() {vec3 scale_camera_pos=-u_globe_position*EARTH_RADIUS/u_globe_radius;vec4 color=atmosphere(normalize(view_direction),scale_camera_pos,u_sun_pos,22.0,EARTH_RADIUS,ATMOS_RADIUS,vec3(5.5e-6,13.0e-6,22.4e-6),21e-6,8e3,1.2e3,0.758 +);color.rgb=1.0-exp(-1.0*color.rgb);color=pow(color,vec4(1.0/2.2));fragColor=vec4(color.rgb,1.0-color.a)*u_atmosphere_blend;}`,"in vec2 a_pos;uniform mat4 u_inv_proj_matrix;out vec3 view_direction;void main() {view_direction=(u_inv_proj_matrix*vec4(a_pos,0.0,1.0)).xyz;gl_Position=vec4(a_pos,0.0,1.0);}"),sky:Zn("uniform vec4 u_sky_color;uniform vec4 u_horizon_color;uniform vec2 u_horizon;uniform vec2 u_horizon_normal;uniform float u_sky_horizon_blend;uniform float u_sky_blend;void main() {float x=gl_FragCoord.x;float y=gl_FragCoord.y;float blend=(y-u_horizon.y)*u_horizon_normal.y+(x-u_horizon.x)*u_horizon_normal.x;if (blend > 0.0) {if (blend < u_sky_horizon_blend) {fragColor=mix(u_sky_color,u_horizon_color,pow(1.0-blend/u_sky_horizon_blend,2.0));} else {fragColor=u_sky_color;}}fragColor=mix(fragColor,vec4(vec3(0.0),0.0),u_sky_blend);}","in vec2 a_pos;void main() {gl_Position=vec4(a_pos,1.0,1.0);}")};function Zn(z,l){let m=/#pragma mapbox: ([\w]+) ([\w]+) ([\w]+) ([\w]+)/g,T=l.match(/in ([\w]+) ([\w]+)/g),P=z.match(/uniform ([\w]+) ([\w]+)([\s]*)([\w]*)/g),V=l.match(/uniform ([\w]+) ([\w]+)([\s]*)([\w]*)/g),W=V?V.concat(P):P,te={};return{fragmentSource:z=z.replace(m,(se,fe,ye,Re,Me)=>(te[Me]=!0,fe==="define"?` +#ifndef HAS_UNIFORM_u_${Me} +in ${ye} ${Re} ${Me}; +#else +uniform ${ye} ${Re} u_${Me}; +#endif +`:` +#ifdef HAS_UNIFORM_u_${Me} + ${ye} ${Re} ${Me} = u_${Me}; +#endif +`)),vertexSource:l=l.replace(m,(se,fe,ye,Re,Me)=>{let je=Re==="float"?"vec2":"vec4",tt=Me.match(/color/)?"color":je;return te[Me]?fe==="define"?` +#ifndef HAS_UNIFORM_u_${Me} +uniform lowp float u_${Me}_t; +in ${ye} ${je} a_${Me}; +out ${ye} ${Re} ${Me}; +#else +uniform ${ye} ${Re} u_${Me}; +#endif +`:tt==="vec4"?` +#ifndef HAS_UNIFORM_u_${Me} + ${Me} = a_${Me}; +#else + ${ye} ${Re} ${Me} = u_${Me}; +#endif +`:` +#ifndef HAS_UNIFORM_u_${Me} + ${Me} = unpack_mix_${tt}(a_${Me}, u_${Me}_t); +#else + ${ye} ${Re} ${Me} = u_${Me}; +#endif +`:fe==="define"?` +#ifndef HAS_UNIFORM_u_${Me} +uniform lowp float u_${Me}_t; +in ${ye} ${je} a_${Me}; +#else +uniform ${ye} ${Re} u_${Me}; +#endif +`:tt==="vec4"?` +#ifndef HAS_UNIFORM_u_${Me} + ${ye} ${Re} ${Me} = a_${Me}; +#else + ${ye} ${Re} ${Me} = u_${Me}; +#endif +`:` +#ifndef HAS_UNIFORM_u_${Me} + ${ye} ${Re} ${Me} = unpack_mix_${tt}(a_${Me}, u_${Me}_t); +#else + ${ye} ${Re} ${Me} = u_${Me}; +#endif +`}),staticAttributes:T,staticUniforms:W}}class Gs{constructor(l,m,T){this.vertexBuffer=l,this.indexBuffer=m,this.segments=T}destroy(){this.vertexBuffer.destroy(),this.indexBuffer.destroy(),this.segments.destroy(),this.vertexBuffer=null,this.indexBuffer=null,this.segments=null}}var ec=o.aV([{name:"a_pos",type:"Int16",components:2}]);let sl="#define PROJECTION_MERCATOR",Ol="mercator";class vl{constructor(){this._cachedMesh=null}get name(){return"mercator"}get useSubdivision(){return!1}get shaderVariantName(){return Ol}get shaderDefine(){return sl}get shaderPreludeCode(){return _a.projectionMercator}get vertexShaderPreludeCode(){return _a.projectionMercator.vertexSource}get subdivisionGranularity(){return o.aW.noSubdivision}get useGlobeControls(){return!1}get transitionState(){return 0}get latitudeErrorCorrectionRadians(){return 0}destroy(){}updateGPUdependent(l){}getMeshFromTileID(l,m,T,P,V){if(this._cachedMesh)return this._cachedMesh;let W=new o.aX;W.emplaceBack(0,0),W.emplaceBack(o.a5,0),W.emplaceBack(0,o.a5),W.emplaceBack(o.a5,o.a5);let te=l.createVertexBuffer(W,ec.members),se=o.aY.simpleSegment(0,0,4,2),fe=new o.aZ;fe.emplaceBack(1,0,2),fe.emplaceBack(1,2,3);let ye=l.createIndexBuffer(fe);return this._cachedMesh=new Gs(te,ye,se),this._cachedMesh}recalculate(){}hasTransition(){return!1}setErrorQueryLatitudeDegrees(l){}}class Pu{constructor(l=0,m=0,T=0,P=0){if(isNaN(l)||l<0||isNaN(m)||m<0||isNaN(T)||T<0||isNaN(P)||P<0)throw new Error("Invalid value for edge-insets, top, bottom, left and right must all be numbers");this.top=l,this.bottom=m,this.left=T,this.right=P}interpolate(l,m,T){return m.top!=null&&l.top!=null&&(this.top=o.G.number(l.top,m.top,T)),m.bottom!=null&&l.bottom!=null&&(this.bottom=o.G.number(l.bottom,m.bottom,T)),m.left!=null&&l.left!=null&&(this.left=o.G.number(l.left,m.left,T)),m.right!=null&&l.right!=null&&(this.right=o.G.number(l.right,m.right,T)),this}getCenter(l,m){let T=o.ao((this.left+l-this.right)/2,0,l),P=o.ao((this.top+m-this.bottom)/2,0,m);return new o.P(T,P)}equals(l){return this.top===l.top&&this.bottom===l.bottom&&this.left===l.left&&this.right===l.right}clone(){return new Pu(this.top,this.bottom,this.left,this.right)}toJSON(){return{top:this.top,bottom:this.bottom,left:this.left,right:this.right}}}function tu(z,l){if(!z.renderWorldCopies||z.lngRange)return;let m=l.lng-z.center.lng;l.lng+=m>180?-360:m<-180?360:0}function La(z){return Math.max(0,Math.floor(z))}class xl{constructor(l,m){var T;this.applyConstrain=(P,V)=>this._constrainOverride!==null?this._constrainOverride(P,V):this._callbacks.defaultConstrain(P,V),this._callbacks=l,this._tileSize=512,this._renderWorldCopies=m?.renderWorldCopies===void 0||!!m?.renderWorldCopies,this._minZoom=m?.minZoom||0,this._maxZoom=m?.maxZoom||22,this._minPitch=m?.minPitch==null?0:m?.minPitch,this._maxPitch=m?.maxPitch==null?60:m?.maxPitch,this._constrainOverride=(T=m?.constrainOverride)!==null&&T!==void 0?T:null,this.setMaxBounds(),this._width=0,this._height=0,this._center=new o.V(0,0),this._elevation=0,this._zoom=0,this._tileZoom=La(this._zoom),this._scale=o.ar(this._zoom),this._bearingInRadians=0,this._fovInRadians=.6435011087932844,this._pitchInRadians=0,this._rollInRadians=0,this._unmodified=!0,this._edgeInsets=new Pu,this._minElevationForCurrentTile=0,this._autoCalculateNearFarZ=!0}apply(l,m,T){this._constrainOverride=l.constrainOverride,this._latRange=l.latRange,this._lngRange=l.lngRange,this._width=l.width,this._height=l.height,this._center=l.center,this._elevation=l.elevation,this._minElevationForCurrentTile=l.minElevationForCurrentTile,this._zoom=l.zoom,this._tileZoom=La(this._zoom),this._scale=o.ar(this._zoom),this._bearingInRadians=l.bearingInRadians,this._fovInRadians=l.fovInRadians,this._pitchInRadians=l.pitchInRadians,this._rollInRadians=l.rollInRadians,this._unmodified=l.unmodified,this._edgeInsets=new Pu(l.padding.top,l.padding.bottom,l.padding.left,l.padding.right),this._minZoom=l.minZoom,this._maxZoom=l.maxZoom,this._minPitch=l.minPitch,this._maxPitch=l.maxPitch,this._renderWorldCopies=l.renderWorldCopies,this._cameraToCenterDistance=l.cameraToCenterDistance,this._nearZ=l.nearZ,this._farZ=l.farZ,this._autoCalculateNearFarZ=!T&&l.autoCalculateNearFarZ,m&&this.constrainInternal(),this._calcMatrices()}get pixelsToClipSpaceMatrix(){return this._pixelsToClipSpaceMatrix}get clipSpaceToPixelsMatrix(){return this._clipSpaceToPixelsMatrix}get minElevationForCurrentTile(){return this._minElevationForCurrentTile}setMinElevationForCurrentTile(l){this._minElevationForCurrentTile=l}get tileSize(){return this._tileSize}get tileZoom(){return this._tileZoom}get scale(){return this._scale}get width(){return this._width}get height(){return this._height}get bearingInRadians(){return this._bearingInRadians}get lngRange(){return this._lngRange}get latRange(){return this._latRange}get pixelsToGLUnits(){return this._pixelsToGLUnits}get minZoom(){return this._minZoom}setMinZoom(l){this._minZoom!==l&&(this._minZoom=l,this.setZoom(this.applyConstrain(this._center,this.zoom).zoom))}get maxZoom(){return this._maxZoom}setMaxZoom(l){this._maxZoom!==l&&(this._maxZoom=l,this.setZoom(this.applyConstrain(this._center,this.zoom).zoom))}get minPitch(){return this._minPitch}setMinPitch(l){this._minPitch!==l&&(this._minPitch=l,this.setPitch(Math.max(this.pitch,l)))}get maxPitch(){return this._maxPitch}setMaxPitch(l){this._maxPitch!==l&&(this._maxPitch=l,this.setPitch(Math.min(this.pitch,l)))}get renderWorldCopies(){return this._renderWorldCopies}setRenderWorldCopies(l){l===void 0?l=!0:l===null&&(l=!1),this._renderWorldCopies=l}get constrainOverride(){return this._constrainOverride}setConstrainOverride(l){l===void 0&&(l=null),this._constrainOverride!==l&&(this._constrainOverride=l,this.constrainInternal(),this._calcMatrices())}get worldSize(){return this._tileSize*this._scale}get centerOffset(){return this.centerPoint._sub(this.size._div(2))}get size(){return new o.P(this._width,this._height)}get bearing(){return this._bearingInRadians/Math.PI*180}setBearing(l){let m=o.W(l,-180,180)*Math.PI/180;var T,P,V,W,te,se,fe,ye,Re;this._bearingInRadians!==m&&(this._unmodified=!1,this._bearingInRadians=m,this._calcMatrices(),this._rotationMatrix=c(),T=this._rotationMatrix,V=-this._bearingInRadians,W=(P=this._rotationMatrix)[0],te=P[1],se=P[2],fe=P[3],ye=Math.sin(V),Re=Math.cos(V),T[0]=W*Re+se*ye,T[1]=te*Re+fe*ye,T[2]=W*-ye+se*Re,T[3]=te*-ye+fe*Re)}get rotationMatrix(){return this._rotationMatrix}get pitchInRadians(){return this._pitchInRadians}get pitch(){return this._pitchInRadians/Math.PI*180}setPitch(l){let m=o.ao(l,this.minPitch,this.maxPitch)/180*Math.PI;this._pitchInRadians!==m&&(this._unmodified=!1,this._pitchInRadians=m,this._calcMatrices())}get rollInRadians(){return this._rollInRadians}get roll(){return this._rollInRadians/Math.PI*180}setRoll(l){let m=l/180*Math.PI;this._rollInRadians!==m&&(this._unmodified=!1,this._rollInRadians=m,this._calcMatrices())}get fovInRadians(){return this._fovInRadians}get fov(){return o.a_(this._fovInRadians)}setFov(l){l=o.ao(l,.1,150),this.fov!==l&&(this._unmodified=!1,this._fovInRadians=o.aq(l),this._calcMatrices())}get zoom(){return this._zoom}setZoom(l){let m=this.applyConstrain(this._center,l).zoom;this._zoom!==m&&(this._unmodified=!1,this._zoom=m,this._tileZoom=Math.max(0,Math.floor(m)),this._scale=o.ar(m),this.constrainInternal(),this._calcMatrices())}get center(){return this._center}setCenter(l){l.lat===this._center.lat&&l.lng===this._center.lng||(this._unmodified=!1,this._center=l,this.constrainInternal(),this._calcMatrices())}get elevation(){return this._elevation}setElevation(l){l!==this._elevation&&(this._elevation=l,this.constrainInternal(),this._calcMatrices())}get padding(){return this._edgeInsets.toJSON()}setPadding(l){this._edgeInsets.equals(l)||(this._unmodified=!1,this._edgeInsets.interpolate(this._edgeInsets,l,1),this._calcMatrices())}get centerPoint(){return this._edgeInsets.getCenter(this._width,this._height)}get pixelsPerMeter(){return this._pixelPerMeter}get unmodified(){return this._unmodified}get cameraToCenterDistance(){return this._cameraToCenterDistance}get nearZ(){return this._nearZ}get farZ(){return this._farZ}get autoCalculateNearFarZ(){return this._autoCalculateNearFarZ}overrideNearFarZ(l,m){this._autoCalculateNearFarZ=!1,this._nearZ=l,this._farZ=m,this._calcMatrices()}clearNearFarZOverride(){this._autoCalculateNearFarZ=!0,this._calcMatrices()}isPaddingEqual(l){return this._edgeInsets.equals(l)}interpolatePadding(l,m,T){this._unmodified=!1,this._edgeInsets.interpolate(l,m,T),this.constrainInternal(),this._calcMatrices()}resize(l,m,T=!0){this._width=l,this._height=m,T&&this.constrainInternal(),this._calcMatrices()}getMaxBounds(){return this._latRange&&this._latRange.length===2&&this._lngRange&&this._lngRange.length===2?new Ho([this._lngRange[0],this._latRange[0]],[this._lngRange[1],this._latRange[1]]):null}setMaxBounds(l){l?(this._lngRange=[l.getWest(),l.getEast()],this._latRange=[l.getSouth(),l.getNorth()],this.constrainInternal()):(this._lngRange=null,this._latRange=[-o.ap,o.ap])}getCameraQueryGeometry(l,m){if(m.length===1)return[m[0],l];{let{minX:T,minY:P,maxX:V,maxY:W}=o.ac.fromPoints(m).extend(l);return[new o.P(T,P),new o.P(V,P),new o.P(V,W),new o.P(T,W),new o.P(T,P)]}}constrainInternal(){if(!this.center||!this._width||!this._height||this._constraining)return;this._constraining=!0;let l=this._unmodified,{center:m,zoom:T}=this.applyConstrain(this.center,this.zoom);this.setCenter(m),this.setZoom(T),this._unmodified=l,this._constraining=!1}_calcMatrices(){if(this._width&&this._height){this._pixelsToGLUnits=[2/this._width,-2/this._height];let l=o.as(new Float64Array(16));o.Q(l,l,[this._width/2,-this._height/2,1]),o.O(l,l,[1,-1,0]),this._clipSpaceToPixelsMatrix=l,l=o.as(new Float64Array(16)),o.Q(l,l,[1,-1,1]),o.O(l,l,[-1,-1,0]),o.Q(l,l,[2/this._width,2/this._height,1]),this._pixelsToClipSpaceMatrix=l,this._cameraToCenterDistance=.5/Math.tan(this.fovInRadians/2)*this._height}this._callbacks.calcMatrices()}calculateCenterFromCameraLngLatAlt(l,m,T,P){let V=T!==void 0?T:this.bearing,W=P=P!==void 0?P:this.pitch,{distanceToCenter:te,clampedElevation:se}=this._distanceToCenterFromAltElevationPitch(m,this.elevation,W),{x:fe,y:ye}=Us(W,V),Re=o.ab.fromLngLat(l,m),Me,je,tt=o.a$(1,Re.y),yt=0;do{if(yt+=1,yt>10)break;je=te/tt,Me=new o.ab(Re.x+fe*je,Re.y+ye*je),tt=1/Me.meterInMercatorCoordinateUnits()}while(Math.abs(te-je*tt)>1e-12);return{center:Me.toLngLat(),elevation:se,zoom:o.au(this.height/2/Math.tan(this.fovInRadians/2)/je/this.tileSize)}}recalculateZoomAndCenter(l){if(this.elevation-l==0)return;let m=1/this.worldSize,T=o.at(1,this.center.lat)*this.worldSize,P=o.ab.fromLngLat(this.center,this.elevation),V=P.x/m,W=P.y/m,te=P.z/m,se=this.pitch,fe=this.bearing,{x:ye,y:Re,z:Me}=Us(se,fe),je=this.cameraToCenterDistance,tt=V+je*-ye,yt=W+je*-Re,At=te+je*Me,{distanceToCenter:vt,clampedElevation:Lt}=this._distanceToCenterFromAltElevationPitch(At/T,l,se),Kt=vt*T,It=new o.ab((tt+ye*Kt)*m,(yt+Re*Kt)*m,0).toLngLat(),Xt=o.at(1,It.lat),Rt=o.au(this.height/2/Math.tan(this.fovInRadians/2)/vt/Xt/this.tileSize);this._elevation=Lt,this._center=It,this.setZoom(Rt)}_distanceToCenterFromAltElevationPitch(l,m,T){let P=-Math.cos(o.aq(T)),V=l-m,W,te=m;return P*V>=0||Math.abs(P)<.1?(W=1e4,te=l+W*P):W=-V/P,{distanceToCenter:W,clampedElevation:te}}getCameraPoint(){let l=Math.tan(this.pitchInRadians)*(this.cameraToCenterDistance||1);return this.centerPoint.add(new o.P(l*Math.sin(this.rollInRadians),l*Math.cos(this.rollInRadians)))}getCameraAltitude(){return Math.cos(this.pitchInRadians)*this._cameraToCenterDistance/this._pixelPerMeter+this.elevation}getCameraLngLat(){let l=o.at(1,this.center.lat)*this.worldSize;return wr(this.center,this.elevation,this.pitch,this.bearing,this.cameraToCenterDistance/l).toLngLat()}getMercatorTileCoordinates(l){if(!l)return[0,0,1,1];let m=l.canonical.z>=0?1<this.max[0]||l.aabb.min[1]>this.max[1]||l.aabb.min[2]>this.max[2]||l.aabb.max[0]0?(m+=l[P]*this.min[P],T+=l[P]*this.max[P]):(T+=l[P]*this.min[P],m+=l[P]*this.max[P]);return m>=0?2:T<0?0:1}}class Gh{distanceToTile2d(l,m,T,P){let V=P.distanceX([l,m]),W=P.distanceY([l,m]);return Math.hypot(V,W)}getWrap(l,m,T){return T}getTileBoundingVolume(l,m,T,P){var V,W;let te=0,se=0;if(P?.terrain){let ye=new o.a2(l.z,m,l.z,l.x,l.y),Re=P.terrain.getMinMaxElevation(ye);te=(V=Re.minElevation)!==null&&V!==void 0?V:Math.min(0,T),se=(W=Re.maxElevation)!==null&&W!==void 0?W:Math.max(0,T)}let fe=1<P}allowWorldCopies(){return!0}prepareNextFrame(){}}class Ec{constructor(l,m,T){this.points=l,this.planes=m,this.aabb=T}static fromInvProjectionMatrix(l,m=1,T=0,P,V){let W=V?[[6,5,4],[0,1,2],[0,3,7],[2,1,5],[3,2,6],[0,4,5]]:[[0,1,2],[6,5,4],[0,3,7],[2,1,5],[3,2,6],[0,4,5]],te=Math.pow(2,T),se=[[-1,1,-1,1],[1,1,-1,1],[1,-1,-1,1],[-1,-1,-1,1],[-1,1,1,1],[1,1,1,1],[1,-1,1,1],[-1,-1,1,1]].map(Me=>function(je,tt,yt,At){let vt=o.aI([],je,tt),Lt=1/vt[3]/yt*At;return o.b7(vt,vt,[Lt,Lt,1/vt[3],Lt])}(Me,l,m,te));P&&function(Me,je,tt,yt){let At=yt?4:0,vt=yt?0:4,Lt=0,Kt=[],It=[];for(let zt=0;zt<4;zt++){let jt=o.b3([],Me[zt+vt],Me[zt+At]),br=o.b8(jt);o.b0(jt,jt,1/br),Kt.push(br),It.push(jt)}for(let zt=0;zt<4;zt++){let jt=o.b9(Me[zt+At],It[zt],tt);Lt=jt!==null&&jt>=0?Math.max(Lt,jt):Math.max(Lt,Kt[zt])}let Xt=function(zt,jt){let br=o.b3([],zt[jt[0]],zt[jt[1]]),Cr=o.b3([],zt[jt[2]],zt[jt[1]]),Rr=[0,0,0,0];return o.b4(Rr,o.b5([],br,Cr)),Rr[3]=-o.b6(Rr,zt[jt[0]]),Rr}(Me,je),Rt=function(zt,jt){let br=o.ba(zt),Cr=o.bb([],zt,1/br),Rr=o.b3([],jt,o.b0([],Cr,o.b6(jt,Cr))),Pr=o.ba(Rr);if(Pr>0){let Ai=Math.sqrt(1-Cr[3]*Cr[3]),_i=o.b0([],Cr,-Cr[3]),hi=o.b1([],_i,o.b0([],Rr,Ai/Pr));return o.bc(jt,hi)}return null}(tt,Xt);if(Rt!==null){let zt=Rt/o.b6(It[0],Xt);Lt=Math.min(Lt,zt)}for(let zt=0;zt<4;zt++){let jt=Math.min(Lt,Kt[zt]);Me[zt+vt]=[Me[zt+At][0]+It[zt][0]*jt,Me[zt+At][1]+It[zt][1]*jt,Me[zt+At][2]+It[zt][2]*jt,1]}}(se,W[0],P,V);let fe=W.map(Me=>{let je=o.b3([],se[Me[0]],se[Me[1]]),tt=o.b3([],se[Me[2]],se[Me[1]]),yt=o.b4([],o.b5([],je,tt)),At=-o.b6(yt,se[Me[1]]);return yt.concat(At)}),ye=[Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY],Re=[Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY];for(let Me of se)for(let je=0;je<3;je++)ye[je]=Math.min(ye[je],Me[je]),Re[je]=Math.max(Re[je],Me[je]);return new Ec(se,fe,new Ws(ye,Re))}}class Gf{get pixelsToClipSpaceMatrix(){return this._helper.pixelsToClipSpaceMatrix}get clipSpaceToPixelsMatrix(){return this._helper.clipSpaceToPixelsMatrix}get pixelsToGLUnits(){return this._helper.pixelsToGLUnits}get centerOffset(){return this._helper.centerOffset}get size(){return this._helper.size}get rotationMatrix(){return this._helper.rotationMatrix}get centerPoint(){return this._helper.centerPoint}get pixelsPerMeter(){return this._helper.pixelsPerMeter}setMinZoom(l){this._helper.setMinZoom(l)}setMaxZoom(l){this._helper.setMaxZoom(l)}setMinPitch(l){this._helper.setMinPitch(l)}setMaxPitch(l){this._helper.setMaxPitch(l)}setRenderWorldCopies(l){this._helper.setRenderWorldCopies(l)}setBearing(l){this._helper.setBearing(l)}setPitch(l){this._helper.setPitch(l)}setRoll(l){this._helper.setRoll(l)}setFov(l){this._helper.setFov(l)}setZoom(l){this._helper.setZoom(l)}setCenter(l){this._helper.setCenter(l)}setElevation(l){this._helper.setElevation(l)}setMinElevationForCurrentTile(l){this._helper.setMinElevationForCurrentTile(l)}setPadding(l){this._helper.setPadding(l)}interpolatePadding(l,m,T){return this._helper.interpolatePadding(l,m,T)}isPaddingEqual(l){return this._helper.isPaddingEqual(l)}resize(l,m,T=!0){this._helper.resize(l,m,T)}getMaxBounds(){return this._helper.getMaxBounds()}setMaxBounds(l){this._helper.setMaxBounds(l)}setConstrainOverride(l){this._helper.setConstrainOverride(l)}overrideNearFarZ(l,m){this._helper.overrideNearFarZ(l,m)}clearNearFarZOverride(){this._helper.clearNearFarZOverride()}getCameraQueryGeometry(l){return this._helper.getCameraQueryGeometry(this.getCameraPoint(),l)}get tileSize(){return this._helper.tileSize}get tileZoom(){return this._helper.tileZoom}get scale(){return this._helper.scale}get worldSize(){return this._helper.worldSize}get width(){return this._helper.width}get height(){return this._helper.height}get lngRange(){return this._helper.lngRange}get latRange(){return this._helper.latRange}get minZoom(){return this._helper.minZoom}get maxZoom(){return this._helper.maxZoom}get zoom(){return this._helper.zoom}get center(){return this._helper.center}get minPitch(){return this._helper.minPitch}get maxPitch(){return this._helper.maxPitch}get pitch(){return this._helper.pitch}get pitchInRadians(){return this._helper.pitchInRadians}get roll(){return this._helper.roll}get rollInRadians(){return this._helper.rollInRadians}get bearing(){return this._helper.bearing}get bearingInRadians(){return this._helper.bearingInRadians}get fov(){return this._helper.fov}get fovInRadians(){return this._helper.fovInRadians}get elevation(){return this._helper.elevation}get minElevationForCurrentTile(){return this._helper.minElevationForCurrentTile}get padding(){return this._helper.padding}get unmodified(){return this._helper.unmodified}get renderWorldCopies(){return this._helper.renderWorldCopies}get cameraToCenterDistance(){return this._helper.cameraToCenterDistance}get constrainOverride(){return this._helper.constrainOverride}get nearZ(){return this._helper.nearZ}get farZ(){return this._helper.farZ}get autoCalculateNearFarZ(){return this._helper.autoCalculateNearFarZ}setTransitionState(l,m){}constructor(l){this._posMatrixCache=new Map,this._alignedPosMatrixCache=new Map,this._fogMatrixCacheF32=new Map,this.defaultConstrain=(m,T)=>{T=o.ao(+T,this.minZoom,this.maxZoom);let P={center:new o.V(m.lng,m.lat),zoom:T},V=this._helper._lngRange;if(!this._helper._renderWorldCopies&&V===null){let It=179.9999999999;V=[-It,It]}let W=this.tileSize*o.ar(P.zoom),te=0,se=W,fe=0,ye=W,Re=0,Me=0,{x:je,y:tt}=this.size;if(this._helper._latRange){let It=this._helper._latRange;te=o.X(It[1])*W,se=o.X(It[0])*W,se-tese&&(Lt=se-It)}if(V){let It=(fe+ye)/2,Xt=yt;this._helper._renderWorldCopies&&(Xt=o.W(yt,It-W/2,It+W/2));let Rt=je/2;Xt-Rtye&&(vt=ye-Rt)}if(vt!==void 0||Lt!==void 0){let It=new o.P(vt??yt,Lt??At);P.center=Wn(W,It).wrap()}return P},this.applyConstrain=(m,T)=>this._helper.applyConstrain(m,T),this._helper=new xl({calcMatrices:()=>{this._calcMatrices()},defaultConstrain:(m,T)=>this.defaultConstrain(m,T)},l),this._coveringTilesDetailsProvider=new Gh}clone(){let l=new Gf;return l.apply(this),l}apply(l,m,T){this._helper.apply(l,m,T)}get cameraPosition(){return this._cameraPosition}get projectionMatrix(){return this._projectionMatrix}get modelViewProjectionMatrix(){return this._viewProjMatrix}get inverseProjectionMatrix(){return this._invProjMatrix}get mercatorMatrix(){return this._mercatorMatrix}getVisibleUnwrappedCoordinates(l){let m=[new o.bd(0,l)];if(this._helper._renderWorldCopies){let T=this.screenPointToMercatorCoordinate(new o.P(0,0)),P=this.screenPointToMercatorCoordinate(new o.P(this._helper._width,0)),V=this.screenPointToMercatorCoordinate(new o.P(this._helper._width,this._helper._height)),W=this.screenPointToMercatorCoordinate(new o.P(0,this._helper._height)),te=Math.floor(Math.min(T.x,P.x,V.x,W.x)),se=Math.floor(Math.max(T.x,P.x,V.x,W.x)),fe=1;for(let ye=te-fe;ye<=se+fe;ye++)ye!==0&&m.push(new o.bd(ye,l))}return m}getCameraFrustum(){return Ec.fromInvProjectionMatrix(this._invViewProjMatrix,this.worldSize)}getClippingPlane(){return null}getCoveringTilesDetailsProvider(){return this._coveringTilesDetailsProvider}recalculateZoomAndCenter(l){let m=this.screenPointToLocation(this.centerPoint,l),T=l?l.getElevationForLngLatZoom(m,this._helper._tileZoom):0;this._helper.recalculateZoomAndCenter(T)}setLocationAtPoint(l,m){let T=o.at(this.elevation,this.center.lat),P=this.screenPointToMercatorCoordinateAtZ(m,T),V=this.screenPointToMercatorCoordinateAtZ(this.centerPoint,T),W=o.ab.fromLngLat(l),te=new o.ab(W.x-(P.x-V.x),W.y-(P.y-V.y));this.setCenter(te?.toLngLat()),this._helper._renderWorldCopies&&this.setCenter(this.center.wrap())}locationToScreenPoint(l,m){return m?this.coordinatePoint(o.ab.fromLngLat(l),m.getElevationForLngLat(l),this._pixelMatrix3D):this.coordinatePoint(o.ab.fromLngLat(l))}screenPointToLocation(l,m){var T;return(T=this.screenPointToMercatorCoordinate(l,m))===null||T===void 0?void 0:T.toLngLat()}screenPointToMercatorCoordinate(l,m){if(m){let T=m.pointCoordinate(l);if(T!=null)return T}return this.screenPointToMercatorCoordinateAtZ(l)}screenPointToMercatorCoordinateAtZ(l,m){let T=m||0,P=[l.x,l.y,0,1],V=[l.x,l.y,1,1];o.aI(P,P,this._pixelMatrixInverse),o.aI(V,V,this._pixelMatrixInverse);let W=P[3],te=V[3],se=P[1]/W,fe=V[1]/te,ye=P[2]/W,Re=V[2]/te,Me=ye===Re?0:(T-ye)/(Re-ye);return new o.ab(o.G.number(P[0]/W,V[0]/te,Me)/this.worldSize,o.G.number(se,fe,Me)/this.worldSize,T)}coordinatePoint(l,m=0,T=this._pixelMatrix){let P=[l.x*this.worldSize,l.y*this.worldSize,m,1];return o.aI(P,P,T),new o.P(P[0]/P[3],P[1]/P[3])}getBounds(){let l=Math.max(0,this._helper._height/2-bs(this));return new Ho().extend(this.screenPointToLocation(new o.P(0,l))).extend(this.screenPointToLocation(new o.P(this._helper._width,l))).extend(this.screenPointToLocation(new o.P(this._helper._width,this._helper._height))).extend(this.screenPointToLocation(new o.P(0,this._helper._height)))}isPointOnMapSurface(l,m){return m?m.pointCoordinate(l)!=null:l.y>this.height/2-bs(this)}calculatePosMatrix(l,m=!1,T){var P;let V=(P=l.key)!==null&&P!==void 0?P:o.be(l.wrap,l.canonical.z,l.canonical.z,l.canonical.x,l.canonical.y),W=m?this._alignedPosMatrixCache:this._posMatrixCache;if(W.has(V)){let fe=W.get(V);return T?fe.f32:fe.f64}let te=go(l,this.worldSize);o.S(te,m?this._alignedProjMatrix:this._viewProjMatrix,te);let se={f64:te,f32:new Float32Array(te)};return W.set(V,se),T?se.f32:se.f64}calculateFogMatrix(l){let m=l.key,T=this._fogMatrixCacheF32;if(T.has(m))return T.get(m);let P=go(l,this.worldSize);return o.S(P,this._fogMatrix,P),T.set(m,new Float32Array(P)),T.get(m)}calculateCenterFromCameraLngLatAlt(l,m,T,P){return this._helper.calculateCenterFromCameraLngLatAlt(l,m,T,P)}_calculateNearFarZIfNeeded(l,m,T){if(!this._helper.autoCalculateNearFarZ)return;let P=Math.min(this.elevation,this.minElevationForCurrentTile,this.getCameraAltitude()-100),V=l-P*this._helper._pixelPerMeter/Math.cos(m),W=P<0?V:l,te=Math.PI/2+this.pitchInRadians,se=o.aq(this.fov)*(Math.abs(Math.cos(o.aq(this.roll)))*this.height+Math.abs(Math.sin(o.aq(this.roll)))*this.width)/this.height*(.5+T.y/this.height),fe=Math.sin(se)*W/Math.sin(o.ao(Math.PI-te-se,.01,Math.PI-.01)),ye=bs(this),Re=Math.atan(ye/this._helper.cameraToCenterDistance),Me=o.aq(.75),je=Re>Me?2*Re*(.5+T.y/(2*ye)):Me,tt=Math.sin(je)*W/Math.sin(o.ao(Math.PI-te-je,.01,Math.PI-.01)),yt=Math.min(fe,tt);this._helper._farZ=1.01*(Math.cos(Math.PI/2-m)*yt+W),this._helper._nearZ=this._helper._height/50}_calcMatrices(){if(!this._helper._height)return;let l=this.centerOffset,m=fn(this.worldSize,this.center),T=m.x,P=m.y;this._helper._pixelPerMeter=o.at(1,this.center.lat)*this.worldSize;let V=o.aq(Math.min(this.pitch,Wi)),W=Math.max(this._helper.cameraToCenterDistance/2,this._helper.cameraToCenterDistance+this._helper._elevation*this._helper._pixelPerMeter/Math.cos(V)),te;this._calculateNearFarZIfNeeded(W,V,l),te=new Float64Array(16),o.bf(te,this.fovInRadians,this._helper._width/this._helper._height,this._helper._nearZ,this._helper._farZ),this._invProjMatrix=new Float64Array(16),o.aC(this._invProjMatrix,te),te[8]=2*-l.x/this._helper._width,te[9]=2*l.y/this._helper._height,this._projectionMatrix=o.bg(te),o.Q(te,te,[1,-1,1]),o.O(te,te,[0,0,-this._helper.cameraToCenterDistance]),o.bh(te,te,-this.rollInRadians),o.bi(te,te,this.pitchInRadians),o.bh(te,te,-this.bearingInRadians),o.O(te,te,[-T,-P,0]),this._mercatorMatrix=o.Q([],te,[this.worldSize,this.worldSize,this.worldSize]),o.Q(te,te,[1,1,this._helper._pixelPerMeter]),this._pixelMatrix=o.S(new Float64Array(16),this.clipSpaceToPixelsMatrix,te),o.O(te,te,[0,0,-this.elevation]),this._viewProjMatrix=te,this._invViewProjMatrix=o.aC([],te);let se=[0,0,-1,1];o.aI(se,se,this._invViewProjMatrix),this._cameraPosition=[se[0]/se[3],se[1]/se[3],se[2]/se[3]],this._fogMatrix=new Float64Array(16),o.bf(this._fogMatrix,this.fovInRadians,this.width/this.height,W,this._helper._farZ),this._fogMatrix[8]=2*-l.x/this.width,this._fogMatrix[9]=2*l.y/this.height,o.Q(this._fogMatrix,this._fogMatrix,[1,-1,1]),o.O(this._fogMatrix,this._fogMatrix,[0,0,-this.cameraToCenterDistance]),o.bh(this._fogMatrix,this._fogMatrix,-this.rollInRadians),o.bi(this._fogMatrix,this._fogMatrix,this.pitchInRadians),o.bh(this._fogMatrix,this._fogMatrix,-this.bearingInRadians),o.O(this._fogMatrix,this._fogMatrix,[-T,-P,0]),o.Q(this._fogMatrix,this._fogMatrix,[1,1,this._helper._pixelPerMeter]),o.O(this._fogMatrix,this._fogMatrix,[0,0,-this.elevation]),this._pixelMatrix3D=o.S(new Float64Array(16),this.clipSpaceToPixelsMatrix,te);let fe=this._helper._width%2/2,ye=this._helper._height%2/2,Re=Math.cos(this.bearingInRadians),Me=Math.sin(-this.bearingInRadians),je=T-Math.round(T)+Re*fe+Me*ye,tt=P-Math.round(P)+Re*ye+Me*fe,yt=new Float64Array(te);if(o.O(yt,yt,[je>.5?je-1:je,tt>.5?tt-1:tt,0]),this._alignedProjMatrix=yt,te=o.aC(new Float64Array(16),this._pixelMatrix),!te)throw new Error("failed to invert matrix");this._pixelMatrixInverse=te,this._clearMatrixCaches()}_clearMatrixCaches(){this._posMatrixCache.clear(),this._alignedPosMatrixCache.clear(),this._fogMatrixCacheF32.clear()}maxPitchScaleFactor(){if(!this._pixelMatrixInverse)return 1;let l=this.screenPointToMercatorCoordinate(new o.P(0,0)),m=[l.x*this.worldSize,l.y*this.worldSize,0,1];return o.aI(m,m,this._pixelMatrix)[3]/this._helper.cameraToCenterDistance}getCameraPoint(){return this._helper.getCameraPoint()}getCameraAltitude(){return this._helper.getCameraAltitude()}getCameraLngLat(){let l=o.at(1,this.center.lat)*this.worldSize;return wr(this.center,this.elevation,this.pitch,this.bearing,this._helper.cameraToCenterDistance/l).toLngLat()}lngLatToCameraDepth(l,m){let T=o.ab.fromLngLat(l),P=[T.x*this.worldSize,T.y*this.worldSize,m,1];return o.aI(P,P,this._viewProjMatrix),P[2]/P[3]}getProjectionData(l){let{overscaledTileID:m,aligned:T,applyTerrainMatrix:P}=l,V=this._helper.getMercatorTileCoordinates(m),W=m?this.calculatePosMatrix(m,T,!0):null,te;return te=m&&m.terrainRttPosMatrix32f&&P?m.terrainRttPosMatrix32f:W||o.bj(),{mainMatrix:te,tileMercatorCoords:V,clippingPlane:[0,0,0,0],projectionTransition:0,fallbackMatrix:te}}isLocationOccluded(l){return!1}getPixelScale(){return 1}getCircleRadiusCorrection(){return 1}getPitchedTextCorrection(l,m,T){return 1}transformLightDirection(l){return o.b2(l)}getRayDirectionFromPixel(l){throw new Error("Not implemented.")}projectTileCoordinates(l,m,T,P){let V=this.calculatePosMatrix(T),W;P?(W=[l,m,P(l,m),1],o.aI(W,W,V)):(W=[l,m,0,1],md(W,W,V));let te=W[3];return{point:new o.P(W[0]/te,W[1]/te),signedDistanceFromCamera:te,isOccluded:!1}}populateCache(l){for(let m of l)this.calculatePosMatrix(m)}getMatrixForModel(l,m){let T=o.ab.fromLngLat(l,m),P=T.meterInMercatorCoordinateUnits(),V=o.bk();return o.O(V,V,[T.x,T.y,T.z]),o.bh(V,V,Math.PI),o.bi(V,V,Math.PI/2),o.Q(V,V,[-P,P,P]),V}getProjectionDataForCustomLayer(l=!0){let m=new o.a2(0,0,0,0,0),T=this.getProjectionData({overscaledTileID:m,applyGlobeMatrix:l}),P=go(m,this.worldSize);o.S(P,this._viewProjMatrix,P),T.tileMercatorCoords=[0,0,1,1];let V=[o.a5,o.a5,this.worldSize/this._helper.pixelsPerMeter],W=o.bl();return o.Q(W,P,V),T.fallbackMatrix=W,T.mainMatrix=W,T}getFastPathSimpleProjectionMatrix(l){return this.calculatePosMatrix(l)}}function Wh(){o.w("Map cannot fit within canvas with the given bounds, padding, and/or offset.")}function Hd(z){if(z.useSlerp)if(z.k<1){let l=o.bm(z.startEulerAngles.roll,z.startEulerAngles.pitch,z.startEulerAngles.bearing),m=o.bm(z.endEulerAngles.roll,z.endEulerAngles.pitch,z.endEulerAngles.bearing),T=new Float64Array(4);o.bn(T,l,m,z.k);let P=o.bo(T);z.tr.setRoll(P.roll),z.tr.setPitch(P.pitch),z.tr.setBearing(P.bearing)}else z.tr.setRoll(z.endEulerAngles.roll),z.tr.setPitch(z.endEulerAngles.pitch),z.tr.setBearing(z.endEulerAngles.bearing);else z.tr.setRoll(o.G.number(z.startEulerAngles.roll,z.endEulerAngles.roll,z.k)),z.tr.setPitch(o.G.number(z.startEulerAngles.pitch,z.endEulerAngles.pitch,z.k)),z.tr.setBearing(o.G.number(z.startEulerAngles.bearing,z.endEulerAngles.bearing,z.k))}function Cp(z,l,m,T,P){let V=P.padding,W=fn(P.worldSize,m.getNorthWest()),te=fn(P.worldSize,m.getNorthEast()),se=fn(P.worldSize,m.getSouthEast()),fe=fn(P.worldSize,m.getSouthWest()),ye=o.aq(-T),Re=W.rotate(ye),Me=te.rotate(ye),je=se.rotate(ye),tt=fe.rotate(ye),yt=new o.P(Math.max(Re.x,Me.x,tt.x,je.x),Math.max(Re.y,Me.y,tt.y,je.y)),At=new o.P(Math.min(Re.x,Me.x,tt.x,je.x),Math.min(Re.y,Me.y,tt.y,je.y)),vt=yt.sub(At),Lt=(P.width-(V.left+V.right+l.left+l.right))/vt.x,Kt=(P.height-(V.top+V.bottom+l.top+l.bottom))/vt.y;if(Kt<0||Lt<0)return void Wh();let It=Math.min(o.au(P.scale*Math.min(Lt,Kt)),z.maxZoom),Xt=o.P.convert(z.offset),Rt=new o.P((l.left-l.right)/2,(l.top-l.bottom)/2).rotate(o.aq(T)),zt=Xt.add(Rt).mult(P.scale/o.ar(It));return{center:Wn(P.worldSize,W.add(se).div(2).sub(zt)),zoom:It,bearing:T}}class Af{get useGlobeControls(){return!1}handlePanInertia(l,m){let T=l.mag(),P=Math.abs(bs(m));return{easingOffset:l.mult(Math.min(.75*P/T,1)),easingCenter:m.center}}handleMapControlsRollPitchBearingZoom(l,m){l.bearingDelta&&m.setBearing(m.bearing+l.bearingDelta),l.pitchDelta&&m.setPitch(m.pitch+l.pitchDelta),l.rollDelta&&m.setRoll(m.roll+l.rollDelta),l.zoomDelta&&m.setZoom(m.zoom+l.zoomDelta)}handleMapControlsPan(l,m,T){l.around.distSqr(m.centerPoint)<.01||m.setLocationAtPoint(T,l.around)}cameraForBoxAndBearing(l,m,T,P,V){return Cp(l,m,T,P,V)}handleJumpToCenterZoom(l,m){l.zoom!==(m.zoom!==void 0?+m.zoom:l.zoom)&&l.setZoom(+m.zoom),m.center!==void 0&&l.setCenter(o.V.convert(m.center))}handleEaseTo(l,m){let T=l.zoom,P=l.padding,V={roll:l.roll,pitch:l.pitch,bearing:l.bearing},W={roll:m.roll===void 0?l.roll:m.roll,pitch:m.pitch===void 0?l.pitch:m.pitch,bearing:m.bearing===void 0?l.bearing:m.bearing},te=m.zoom!==void 0,se=!l.isPaddingEqual(m.padding),fe=!1,ye=te?+m.zoom:l.zoom,Re=l.centerPoint.add(m.offsetAsPoint),Me=l.screenPointToLocation(Re),{center:je,zoom:tt}=l.applyConstrain(o.V.convert(m.center||Me),ye??T);tu(l,je);let yt=fn(l.worldSize,Me),At=fn(l.worldSize,je).sub(yt),vt=o.ar(tt-T);return fe=tt!==T,{easeFunc:Lt=>{if(fe&&l.setZoom(o.G.number(T,tt,Lt)),o.bp(V,W)||Hd({startEulerAngles:V,endEulerAngles:W,tr:l,k:Lt,useSlerp:V.roll!=W.roll}),se&&(l.interpolatePadding(P,m.padding,Lt),Re=l.centerPoint.add(m.offsetAsPoint)),m.around)l.setLocationAtPoint(m.around,m.aroundPoint);else{let Kt=o.ar(l.zoom-T),It=tt>T?Math.min(2,vt):Math.max(.5,vt),Xt=Math.pow(It,1-Lt),Rt=Wn(l.worldSize,yt.add(At.mult(Lt*Xt)).mult(Kt));l.setLocationAtPoint(l.renderWorldCopies?Rt.wrap():Rt,Re)}},isZooming:fe,elevationCenter:je}}handleFlyTo(l,m){let T=m.zoom!==void 0,P=l.zoom,V=l.applyConstrain(o.V.convert(m.center||m.locationAtOffset),T?+m.zoom:P),W=V.center,te=V.zoom;tu(l,W);let se=fn(l.worldSize,m.locationAtOffset),fe=fn(l.worldSize,W).sub(se),ye=fe.mag(),Re=o.ar(te-P),Me;if(m.minZoom!==void 0){let je=Math.min(+m.minZoom,P,te),tt=l.applyConstrain(W,je).zoom;Me=o.ar(tt-P)}return{easeFunc:(je,tt,yt,At)=>{l.setZoom(je===1?te:P+o.au(tt));let vt=je===1?W:Wn(l.worldSize,se.add(fe.mult(yt)).mult(tt));l.setLocationAtPoint(l.renderWorldCopies?vt.wrap():vt,At)},scaleOfZoom:Re,targetCenter:W,scaleOfMinZoom:Me,pixelPathLength:ye}}}class ia{constructor(l,m,T){this.blendFunction=l,this.blendColor=m,this.mask=T}}ia.Replace=[1,0],ia.disabled=new ia(ia.Replace,o.bq.transparent,[!1,!1,!1,!1]),ia.unblended=new ia(ia.Replace,o.bq.transparent,[!0,!0,!0,!0]),ia.alphaBlended=new ia([1,771],o.bq.transparent,[!0,!0,!0,!0]);let mh=2305;class ms{constructor(l,m,T){this.enable=l,this.mode=m,this.frontFace=T}}ms.disabled=new ms(!1,1029,mh),ms.backCCW=new ms(!0,1029,mh),ms.frontCCW=new ms(!0,1028,mh);class Ao{constructor(l,m,T){this.func=l,this.mask=m,this.range=T}}Ao.ReadOnly=!1,Ao.ReadWrite=!0,Ao.disabled=new Ao(519,Ao.ReadOnly,[0,1]);let qh=7680;class us{constructor(l,m,T,P,V,W){this.test=l,this.ref=m,this.mask=T,this.fail=P,this.depthFail=V,this.pass=W}}us.disabled=new us({func:519,mask:0},0,0,qh,qh,qh);let Gd=new WeakMap;function q(z){var l;if(Gd.has(z))return Gd.get(z);{let m=(l=z.getParameter(z.VERSION))===null||l===void 0?void 0:l.startsWith("WebGL 2.0");return Gd.set(z,m),m}}class oe{get awaitingQuery(){return!!this._readbackQueue}constructor(l){this._readbackWaitFrames=4,this._measureWaitFrames=6,this._texWidth=1,this._texHeight=1,this._measuredError=0,this._updateCount=0,this._lastReadbackFrame=-1e3,this._readbackQueue=null,this._cachedRenderContext=l;let m=l.context,T=m.gl;this._texFormat=T.RGBA,this._texType=T.UNSIGNED_BYTE;let P=new o.aX;P.emplaceBack(-1,-1),P.emplaceBack(2,-1),P.emplaceBack(-1,2);let V=new o.aZ;V.emplaceBack(0,1,2),this._fullscreenTriangle=new Gs(m.createVertexBuffer(P,ec.members),m.createIndexBuffer(V),o.aY.simpleSegment(0,0,P.length,V.length)),this._resultBuffer=new Uint8Array(4),m.activeTexture.set(T.TEXTURE1);let W=T.createTexture();T.bindTexture(T.TEXTURE_2D,W),T.texParameteri(T.TEXTURE_2D,T.TEXTURE_WRAP_S,T.CLAMP_TO_EDGE),T.texParameteri(T.TEXTURE_2D,T.TEXTURE_WRAP_T,T.CLAMP_TO_EDGE),T.texParameteri(T.TEXTURE_2D,T.TEXTURE_MIN_FILTER,T.NEAREST),T.texParameteri(T.TEXTURE_2D,T.TEXTURE_MAG_FILTER,T.NEAREST),T.texImage2D(T.TEXTURE_2D,0,this._texFormat,this._texWidth,this._texHeight,0,this._texFormat,this._texType,null),this._fbo=m.createFramebuffer(this._texWidth,this._texHeight,!1,!1),this._fbo.colorAttachment.set(W),q(T)&&(this._pbo=T.createBuffer(),T.bindBuffer(T.PIXEL_PACK_BUFFER,this._pbo),T.bufferData(T.PIXEL_PACK_BUFFER,4,T.STREAM_READ),T.bindBuffer(T.PIXEL_PACK_BUFFER,null))}destroy(){let l=this._cachedRenderContext.context.gl;this._fullscreenTriangle.destroy(),this._fbo.destroy(),l.deleteBuffer(this._pbo),this._fullscreenTriangle=null,this._fbo=null,this._pbo=null,this._resultBuffer=null}updateErrorLoop(l,m){let T=this._updateCount;return this._readbackQueue?T>=this._readbackQueue.frameNumberIssued+this._readbackWaitFrames&&this._tryReadback():T>=this._lastReadbackFrame+this._measureWaitFrames&&this._renderErrorTexture(l,m),this._updateCount++,this._measuredError}_bindFramebuffer(){let l=this._cachedRenderContext.context,m=l.gl;l.activeTexture.set(m.TEXTURE1),m.bindTexture(m.TEXTURE_2D,this._fbo.colorAttachment.get()),l.bindFramebuffer.set(this._fbo.framebuffer)}_renderErrorTexture(l,m){let T=this._cachedRenderContext.context,P=T.gl;if(this._bindFramebuffer(),T.viewport.set([0,0,this._texWidth,this._texHeight]),T.clear({color:o.bq.transparent}),this._cachedRenderContext.useProgram("projectionErrorMeasurement").draw(T,P.TRIANGLES,Ao.disabled,us.disabled,ia.unblended,ms.disabled,((V,W)=>({u_input:V,u_output_expected:W}))(l,m),null,null,"$clipping",this._fullscreenTriangle.vertexBuffer,this._fullscreenTriangle.indexBuffer,this._fullscreenTriangle.segments),this._pbo&&q(P)){P.bindBuffer(P.PIXEL_PACK_BUFFER,this._pbo),P.readBuffer(P.COLOR_ATTACHMENT0),P.readPixels(0,0,this._texWidth,this._texHeight,this._texFormat,this._texType,0),P.bindBuffer(P.PIXEL_PACK_BUFFER,null);let V=P.fenceSync(P.SYNC_GPU_COMMANDS_COMPLETE,0);P.flush(),this._readbackQueue={frameNumberIssued:this._updateCount,sync:V}}else this._readbackQueue={frameNumberIssued:this._updateCount,sync:null}}_tryReadback(){let l=this._cachedRenderContext.context.gl;if(this._pbo&&this._readbackQueue&&q(l)){let m=l.clientWaitSync(this._readbackQueue.sync,0,0);if(m===l.WAIT_FAILED)return o.w("WebGL2 clientWaitSync failed."),this._readbackQueue=null,void(this._lastReadbackFrame=this._updateCount);if(m===l.TIMEOUT_EXPIRED)return;l.bindBuffer(l.PIXEL_PACK_BUFFER,this._pbo),l.getBufferSubData(l.PIXEL_PACK_BUFFER,0,this._resultBuffer,0,4),l.bindBuffer(l.PIXEL_PACK_BUFFER,null)}else this._bindFramebuffer(),l.readPixels(0,0,this._texWidth,this._texHeight,this._texFormat,this._texType,this._resultBuffer);this._readbackQueue=null,this._measuredError=oe._parseRGBA8float(this._resultBuffer),this._lastReadbackFrame=this._updateCount}static _parseRGBA8float(l){let m=0;return m+=l[0]/256,m+=l[1]/65536,m+=l[2]/16777216,l[3]<127&&(m=-m),m/128}}let pe=o.a5/128;function be(z,l){let m=z.granularity!==void 0?Math.max(z.granularity,1):1,T=m+(z.generateBorders?2:0),P=m+(z.extendToNorthPole||z.generateBorders?1:0)+(z.extendToSouthPole||z.generateBorders?1:0),V=T+1,W=P+1,te=z.generateBorders?-1:0,se=z.generateBorders||z.extendToNorthPole?-1:0,fe=m+(z.generateBorders?1:0),ye=m+(z.generateBorders||z.extendToSouthPole?1:0),Re=V*W,Me=T*P*6,je=V*W>65536;if(je&&l==="16bit")throw new Error("Granularity is too large and meshes would not fit inside 16 bit vertex indices.");let tt=je||l==="32bit",yt=new Int16Array(2*Re),At=0;for(let Kt=se;Kt<=ye;Kt++)for(let It=te;It<=fe;It++){let Xt=It/m*o.a5;It===-1&&(Xt=-pe),It===m+1&&(Xt=o.a5+pe);let Rt=Kt/m*o.a5;Kt===-1&&(Rt=z.extendToNorthPole?o.bs:-pe),Kt===m+1&&(Rt=z.extendToSouthPole?o.bt:o.a5+pe),yt[At++]=Xt,yt[At++]=Rt}let vt=tt?new Uint32Array(Me):new Uint16Array(Me),Lt=0;for(let Kt=0;Kt0}get latitudeErrorCorrectionRadians(){return this._verticalPerspectiveProjection.latitudeErrorCorrectionRadians}get currentProjection(){return this.useGlobeRendering?this._verticalPerspectiveProjection:this._mercatorProjection}get name(){return"globe"}get useSubdivision(){return this.currentProjection.useSubdivision}get shaderVariantName(){return this.currentProjection.shaderVariantName}get shaderDefine(){return this.currentProjection.shaderDefine}get shaderPreludeCode(){return this.currentProjection.shaderPreludeCode}get vertexShaderPreludeCode(){return this.currentProjection.vertexShaderPreludeCode}get subdivisionGranularity(){return this.currentProjection.subdivisionGranularity}get useGlobeControls(){return this.transitionState>0}destroy(){this._mercatorProjection.destroy(),this._verticalPerspectiveProjection.destroy()}updateGPUdependent(l){this._mercatorProjection.updateGPUdependent(l),this._verticalPerspectiveProjection.updateGPUdependent(l)}getMeshFromTileID(l,m,T,P,V){return this.currentProjection.getMeshFromTileID(l,m,T,P,V)}setProjection(l){this._transitionable.setValue("type",l?.type||"mercator")}updateTransitions(l){this._transitioning=this._transitionable.transitioned(l,this._transitioning)}hasTransition(){return this._transitioning.hasTransition()||this.currentProjection.hasTransition()}recalculate(l){this.properties=this._transitioning.possiblyEvaluate(l)}setErrorQueryLatitudeDegrees(l){this._verticalPerspectiveProjection.setErrorQueryLatitudeDegrees(l),this._mercatorProjection.setErrorQueryLatitudeDegrees(l)}}function Ut(z){let l=li(z.worldSize,z.center.lat);return 2*Math.PI*l}function cr(z,l,m,T,P){let V=1/(1<1e-6){let T=z[0]/m,P=Math.acos(z[2]/m),V=(T>0?P:-P)/Math.PI*180;return new o.V(o.W(V,-180,180),l)}return new o.V(0,l)}function Bi(z){return Math.cos(z*Math.PI/180)}function gn(z,l){let m=Bi(z),T=Bi(l);return o.au(T/m)}function gs(z,l){let m=z.rotate(l.bearingInRadians),T=l.zoom+gn(l.center.lat,0),P=o.bv(1/Bi(l.center.lat),1/Bi(Math.min(Math.abs(l.center.lat),60)),o.by(T,7,3,0,1)),V=360/Ut({worldSize:l.worldSize,center:{lat:l.center.lat}});return new o.V(l.center.lng-m.x*V*P,o.ao(l.center.lat+m.y*V,-o.ap,o.ap))}function Mo(z){let l=.5*z,m=Math.sin(l),T=Math.cos(l);return Math.log(m+T)-Math.log(T-m)}function bl(z,l,m,T){let P=z.lat+m*T;if(Math.abs(m)>1){let V=(Math.sign(z.lat+m)!==Math.sign(z.lat)?-Math.abs(z.lat):Math.abs(z.lat))*Math.PI/180,W=Math.abs(z.lat+m)*Math.PI/180,te=Mo(V+T*(W-V)),se=Mo(V),fe=Mo(W);return new o.V(z.lng+l*((te-se)/(fe-se)),P)}return new o.V(z.lng+l*T,P)}class al{constructor(l){this._cachePrevious=new Map,this._cache=new Map,this._hadAnyChanges=!1,this._boundingVolumeFactory=l}swapBuffers(){if(!this._hadAnyChanges)return;let l=this._cachePrevious;this._cachePrevious=this._cache,this._cache=l,this._cache.clear(),this._hadAnyChanges=!1}getTileBoundingVolume(l,m,T,P){let V=`${l.z}_${l.x}_${l.y}_${P?.terrain?"t":""}`,W=this._cache.get(V);if(W)return W;let te=this._cachePrevious.get(V);if(te)return this._cache.set(V,te),te;let se=this._boundingVolumeFactory(l,m,T,P);return this._cache.set(V,se),this._hadAnyChanges=!0,se}}class Da{constructor(l,m,T,P){this.min=T,this.max=P,this.points=l,this.planes=m}static fromAabb(l,m){let T=[];for(let P=0;P<8;P++)T.push([1&~P?l[0]:m[0],(P>>1&1)==1?m[1]:l[1],(P>>2&1)==1?m[2]:l[2]]);return new Da(T,[[-1,0,0,m[0]],[1,0,0,-l[0]],[0,-1,0,m[1]],[0,1,0,-l[1]],[0,0,-1,m[2]],[0,0,1,-l[2]]],l,m)}static fromCenterSizeAngles(l,m,T){let P=o.bC([],T[0],T[1],T[2]),V=o.bD([],[m[0],0,0],P),W=o.bD([],[0,m[1],0],P),te=o.bD([],[0,0,m[2]],P),se=[...l],fe=[...l];for(let Re=0;Re<8;Re++)for(let Me=0;Me<3;Me++){let je=l[Me]+V[Me]*(1&~Re?-1:1)+W[Me]*((Re>>1&1)==1?1:-1)+te[Me]*((Re>>2&1)==1?1:-1);se[Me]=Math.min(se[Me],je),fe[Me]=Math.max(fe[Me],je)}let ye=[];for(let Re=0;Re<8;Re++){let Me=[...l];o.b1(Me,Me,o.b0([],V,1&~Re?-1:1)),o.b1(Me,Me,o.b0([],W,(Re>>1&1)==1?1:-1)),o.b1(Me,Me,o.b0([],te,(Re>>2&1)==1?1:-1)),ye.push(Me)}return new Da(ye,[[...V,-o.b6(V,ye[0])],[...W,-o.b6(W,ye[0])],[...te,-o.b6(te,ye[0])],[-V[0],-V[1],-V[2],-o.b6(V,ye[7])],[-W[0],-W[1],-W[2],-o.b6(W,ye[7])],[-te[0],-te[1],-te[2],-o.b6(te,ye[7])]],se,fe)}intersectsFrustum(l){let m=!0,T=this.points.length,P=this.planes.length,V=l.planes.length,W=l.points.length;for(let te=0;te=0&&fe++}if(fe===0)return 0;fe=0&&fe++}if(fe===0)return 0}return 1}intersectsPlane(l){let m=this.points.length,T=0;for(let P=0;P=0&&T++}return T===m?2:T===0?0:1}}function Ka(z,l,m){let T=z-l;return T<0?-T:Math.max(0,T-m)}function Yn(z,l,m,T,P){let V=z-m,W;return W=V<0?Math.min(-V,1+V-P):V>1?Math.min(Math.max(V-P,0),1-V):0,Math.max(W,Ka(l,T,P))}class Er{constructor(){this._boundingVolumeCache=new al(this._computeTileBoundingVolume)}prepareNextFrame(){this._boundingVolumeCache.swapBuffers()}distanceToTile2d(l,m,T,P){let V=1<4}allowWorldCopies(){return!1}getTileBoundingVolume(l,m,T,P){return this._boundingVolumeCache.getTileBoundingVolume(l,m,T,P)}_computeTileBoundingVolume(l,m,T,P){var V,W;let te=0,se=0;if(P?.terrain){let fe=new o.a2(l.z,m,l.z,l.x,l.y),ye=P.terrain.getMinMaxElevation(fe);te=(V=ye.minElevation)!==null&&V!==void 0?V:Math.min(0,T),se=(W=ye.maxElevation)!==null&&W!==void 0?W:Math.max(0,T)}if(te/=o.bF,se/=o.bF,te+=1,se+=1,l.z<=0)return Da.fromAabb([-se,-se,-se],[se,se,se]);if(l.z===1)return Da.fromAabb([l.x===0?-se:0,l.y===0?0:-se,-se],[l.x===0?0:se,l.y===0?se:0,se]);{let fe=[cr(0,0,l.x,l.y,l.z),cr(o.a5,0,l.x,l.y,l.z),cr(o.a5,o.a5,l.x,l.y,l.z),cr(0,o.a5,l.x,l.y,l.z)],ye=[];for(let Rr of fe)ye.push(o.b0([],Rr,se));if(se!==te)for(let Rr of fe)ye.push(o.b0([],Rr,te));l.y===0&&ye.push([0,1,0]),l.y===(1<=(1<{let P=o.ao(m.lat,-o.ap,o.ap),V=o.ao(+T,this.minZoom+gn(0,P),this.maxZoom);return{center:new o.V(m.lng,P),zoom:V}},this.applyConstrain=(m,T)=>this._helper.applyConstrain(m,T),this._helper=new xl({calcMatrices:()=>{this._calcMatrices()},defaultConstrain:(m,T)=>this.defaultConstrain(m,T)},l),this._coveringTilesDetailsProvider=new Er}clone(){let l=new wi;return l.apply(this),l}apply(l,m){this._globeLatitudeErrorCorrectionRadians=m||0,this._helper.apply(l)}get projectionMatrix(){return this._projectionMatrix}get modelViewProjectionMatrix(){return this._globeViewProjMatrixNoCorrection}get inverseProjectionMatrix(){return this._globeProjMatrixInverted}get cameraPosition(){let l=o.bA();return l[0]=this._cameraPosition[0],l[1]=this._cameraPosition[1],l[2]=this._cameraPosition[2],l}get cameraToCenterDistance(){return this._helper.cameraToCenterDistance}getProjectionData(l){let{overscaledTileID:m,applyGlobeMatrix:T}=l,P=this._helper.getMercatorTileCoordinates(m);return{mainMatrix:this._globeViewProjMatrix32f,tileMercatorCoords:P,clippingPlane:this._cachedClippingPlane,projectionTransition:T?1:0,fallbackMatrix:this._globeViewProjMatrix32f}}_computeClippingPlane(l){let m=this.pitchInRadians,T=this.cameraToCenterDistance/l,P=Math.sin(m)*T,V=Math.cos(m)*T+1,W=1/Math.sqrt(P*P+V*V)*1,te=-P,se=V,fe=Math.sqrt(te*te+se*se);te/=fe,se/=fe;let ye=[0,te,se];o.bH(ye,ye,[0,0,0],-this.bearingInRadians),o.bI(ye,ye,[0,0,0],-1*this.center.lat*Math.PI/180),o.bJ(ye,ye,[0,0,0],this.center.lng*Math.PI/180);let Re=1/o.b8(ye);return o.b0(ye,ye,Re),[...ye,-W*Re]}isLocationOccluded(l){return!this.isSurfacePointVisible(Fr(l))}transformLightDirection(l){let m=this._helper._center.lng*Math.PI/180,T=this._helper._center.lat*Math.PI/180,P=Math.cos(T),V=[Math.sin(m)*P,Math.sin(T),Math.cos(m)*P],W=[V[2],0,-V[0]],te=[0,0,0];o.b5(te,W,V),o.b4(W,W),o.b4(te,te);let se=[0,0,0];return o.b4(se,[W[0]*l[0]+te[0]*l[1]+V[0]*l[2],W[1]*l[0]+te[1]*l[1]+V[1]*l[2],W[2]*l[0]+te[2]*l[1]+V[2]*l[2]]),se}getPixelScale(){return 1/Math.cos(this._helper._center.lat*Math.PI/180)}getCircleRadiusCorrection(){return Math.cos(this._helper._center.lat*Math.PI/180)}getPitchedTextCorrection(l,m,T){let P=function(te,se,fe){let ye=1/(1<V&&(V=Me),jete&&(te=je)}let ye=[fe.lng+W,fe.lat+se,fe.lng+V,fe.lat+te];return this.isSurfacePointOnScreen([0,1,0])&&(ye[3]=90,ye[0]=-180,ye[2]=180),this.isSurfacePointOnScreen([0,-1,0])&&(ye[1]=-90,ye[0]=-180,ye[2]=180),new Ho(ye)}calculateCenterFromCameraLngLatAlt(l,m,T,P){return this._helper.calculateCenterFromCameraLngLatAlt(l,m,T,P)}setLocationAtPoint(l,m){let T=Fr(this.unprojectScreenPoint(m)),P=Fr(l),V=o.bA();o.bM(V);let W=o.bA();o.bJ(W,T,V,-this.center.lng*Math.PI/180),o.bI(W,W,V,this.center.lat*Math.PI/180);let te=P[0]*P[0]+P[2]*P[2],se=W[0]*W[0];if(te=-vt&&tt<=vt,Kt=At>=-vt&&At<=vt,It,Xt;if(Lt&&Kt){let br=this.center.lng*Math.PI/180,Cr=this.center.lat*Math.PI/180;o.bO(Re,br)+o.bO(tt,Cr)=0}isSurfacePointOnScreen(l){if(!this.isSurfacePointVisible(l))return!1;let m=o.bG();return o.aI(m,[...l,1],this._globeViewProjMatrixNoCorrection),m[0]/=m[3],m[1]/=m[3],m[2]/=m[3],m[0]>-1&&m[0]<1&&m[1]>-1&&m[1]<1&&m[2]>-1&&m[2]<1}rayPlanetIntersection(l,m){let T=o.b6(l,m),P=o.bA(),V=o.bA();o.b0(V,m,T),o.b3(P,l,V);let W=1-o.b6(P,P);if(W<0)return null;let te=o.b6(l,l)-1,se=-T+(T<0?1:-1)*Math.sqrt(W),fe=te/se,ye=se;return{tMin:Math.min(fe,ye),tMax:Math.max(fe,ye)}}unprojectScreenPoint(l){let m=this._cameraPosition,T=this.getRayDirectionFromPixel(l),P=this.rayPlanetIntersection(m,T);if(P){let ye=o.bA();o.b1(ye,m,[T[0]*P.tMin,T[1]*P.tMin,T[2]*P.tMin]);let Re=o.bA();return o.b4(Re,ye),vr(Re)}let V=this._cachedClippingPlane,W=V[0]*T[0]+V[1]*T[1]+V[2]*T[2],te=-o.bc(V,m)/W,se=o.bA();if(te>0)o.b1(se,m,[T[0]*te,T[1]*te,T[2]*te]);else{let ye=o.bA();o.b1(ye,m,[2*T[0],2*T[1],2*T[2]]);let Re=o.bc(this._cachedClippingPlane,ye);o.b3(se,ye,[this._cachedClippingPlane[0]*Re,this._cachedClippingPlane[1]*Re,this._cachedClippingPlane[2]*Re])}let fe=function(ye){let Re=o.bA();return Re[0]=ye[0]*-ye[3],Re[1]=ye[1]*-ye[3],Re[2]=ye[2]*-ye[3],{center:Re,radius:Math.sqrt(1-ye[3]*ye[3])}}(V);return vr(function(ye,Re,Me){let je=o.bA();o.b3(je,Me,ye);let tt=o.bA();return o.bB(tt,ye,je,Re/o.ba(je)),tt}(fe.center,fe.radius,se))}getMatrixForModel(l,m){let T=o.V.convert(l),P=1/o.bF,V=o.bk();return o.bK(V,V,T.lng/180*Math.PI),o.bi(V,V,-T.lat/180*Math.PI),o.O(V,V,[0,0,1+m/o.bF]),o.bi(V,V,.5*Math.PI),o.Q(V,V,[P,P,P]),V}getProjectionDataForCustomLayer(l=!0){let m=this.getProjectionData({overscaledTileID:new o.a2(0,0,0,0,0),applyGlobeMatrix:l});return m.tileMercatorCoords=[0,0,1,1],m}getFastPathSimpleProjectionMatrix(l){}}class ni{get pixelsToClipSpaceMatrix(){return this._helper.pixelsToClipSpaceMatrix}get clipSpaceToPixelsMatrix(){return this._helper.clipSpaceToPixelsMatrix}get pixelsToGLUnits(){return this._helper.pixelsToGLUnits}get centerOffset(){return this._helper.centerOffset}get size(){return this._helper.size}get rotationMatrix(){return this._helper.rotationMatrix}get centerPoint(){return this._helper.centerPoint}get pixelsPerMeter(){return this._helper.pixelsPerMeter}setMinZoom(l){this._helper.setMinZoom(l)}setMaxZoom(l){this._helper.setMaxZoom(l)}setMinPitch(l){this._helper.setMinPitch(l)}setMaxPitch(l){this._helper.setMaxPitch(l)}setRenderWorldCopies(l){this._helper.setRenderWorldCopies(l)}setBearing(l){this._helper.setBearing(l)}setPitch(l){this._helper.setPitch(l)}setRoll(l){this._helper.setRoll(l)}setFov(l){this._helper.setFov(l)}setZoom(l){this._helper.setZoom(l)}setCenter(l){this._helper.setCenter(l)}setElevation(l){this._helper.setElevation(l)}setMinElevationForCurrentTile(l){this._helper.setMinElevationForCurrentTile(l)}setPadding(l){this._helper.setPadding(l)}interpolatePadding(l,m,T){return this._helper.interpolatePadding(l,m,T)}isPaddingEqual(l){return this._helper.isPaddingEqual(l)}resize(l,m,T=!0){this._helper.resize(l,m,T)}getMaxBounds(){return this._helper.getMaxBounds()}setMaxBounds(l){this._helper.setMaxBounds(l)}setConstrainOverride(l){this._helper.setConstrainOverride(l)}overrideNearFarZ(l,m){this._helper.overrideNearFarZ(l,m)}clearNearFarZOverride(){this._helper.clearNearFarZOverride()}getCameraQueryGeometry(l){return this._helper.getCameraQueryGeometry(this.getCameraPoint(),l)}get tileSize(){return this._helper.tileSize}get tileZoom(){return this._helper.tileZoom}get scale(){return this._helper.scale}get worldSize(){return this._helper.worldSize}get width(){return this._helper.width}get height(){return this._helper.height}get lngRange(){return this._helper.lngRange}get latRange(){return this._helper.latRange}get minZoom(){return this._helper.minZoom}get maxZoom(){return this._helper.maxZoom}get zoom(){return this._helper.zoom}get center(){return this._helper.center}get minPitch(){return this._helper.minPitch}get maxPitch(){return this._helper.maxPitch}get pitch(){return this._helper.pitch}get pitchInRadians(){return this._helper.pitchInRadians}get roll(){return this._helper.roll}get rollInRadians(){return this._helper.rollInRadians}get bearing(){return this._helper.bearing}get bearingInRadians(){return this._helper.bearingInRadians}get fov(){return this._helper.fov}get fovInRadians(){return this._helper.fovInRadians}get elevation(){return this._helper.elevation}get minElevationForCurrentTile(){return this._helper.minElevationForCurrentTile}get padding(){return this._helper.padding}get unmodified(){return this._helper.unmodified}get renderWorldCopies(){return this._helper.renderWorldCopies}get cameraToCenterDistance(){return this._helper.cameraToCenterDistance}get constrainOverride(){return this._helper.constrainOverride}get nearZ(){return this._helper.nearZ}get farZ(){return this._helper.farZ}get autoCalculateNearFarZ(){return this._helper.autoCalculateNearFarZ}get isGlobeRendering(){return this._globeness>0}setTransitionState(l,m){this._globeness=l,this._globeLatitudeErrorCorrectionRadians=m,this._calcMatrices(),this._verticalPerspectiveTransform.getCoveringTilesDetailsProvider().prepareNextFrame(),this._mercatorTransform.getCoveringTilesDetailsProvider().prepareNextFrame()}get currentTransform(){return this.isGlobeRendering?this._verticalPerspectiveTransform:this._mercatorTransform}constructor(l){this._globeLatitudeErrorCorrectionRadians=0,this._globeness=1,this.defaultConstrain=(m,T)=>this.currentTransform.defaultConstrain(m,T),this.applyConstrain=(m,T)=>this._helper.applyConstrain(m,T),this._helper=new xl({calcMatrices:()=>{this._calcMatrices()},defaultConstrain:(m,T)=>this.defaultConstrain(m,T)},l),this._globeness=1,this._mercatorTransform=new Gf,this._verticalPerspectiveTransform=new wi}clone(){let l=new ni;return l._globeness=this._globeness,l._globeLatitudeErrorCorrectionRadians=this._globeLatitudeErrorCorrectionRadians,l.apply(this),l}apply(l){this._helper.apply(l),this._mercatorTransform.apply(this),this._verticalPerspectiveTransform.apply(this,this._globeLatitudeErrorCorrectionRadians)}get projectionMatrix(){return this.currentTransform.projectionMatrix}get modelViewProjectionMatrix(){return this.currentTransform.modelViewProjectionMatrix}get inverseProjectionMatrix(){return this.currentTransform.inverseProjectionMatrix}get cameraPosition(){return this.currentTransform.cameraPosition}getProjectionData(l){let m=this._mercatorTransform.getProjectionData(l),T=this._verticalPerspectiveTransform.getProjectionData(l);return{mainMatrix:this.isGlobeRendering?T.mainMatrix:m.mainMatrix,clippingPlane:T.clippingPlane,tileMercatorCoords:T.tileMercatorCoords,projectionTransition:l.applyGlobeMatrix?this._globeness:0,fallbackMatrix:m.fallbackMatrix}}isLocationOccluded(l){return this.currentTransform.isLocationOccluded(l)}transformLightDirection(l){return this.currentTransform.transformLightDirection(l)}getPixelScale(){return o.bv(this._mercatorTransform.getPixelScale(),this._verticalPerspectiveTransform.getPixelScale(),this._globeness)}getCircleRadiusCorrection(){return o.bv(this._mercatorTransform.getCircleRadiusCorrection(),this._verticalPerspectiveTransform.getCircleRadiusCorrection(),this._globeness)}getPitchedTextCorrection(l,m,T){let P=this._mercatorTransform.getPitchedTextCorrection(l,m,T),V=this._verticalPerspectiveTransform.getPitchedTextCorrection(l,m,T);return o.bv(P,V,this._globeness)}projectTileCoordinates(l,m,T,P){return this.currentTransform.projectTileCoordinates(l,m,T,P)}_calcMatrices(){this._helper._width&&this._helper._height&&(this._verticalPerspectiveTransform.apply(this,this._globeLatitudeErrorCorrectionRadians),this._helper._nearZ=this._verticalPerspectiveTransform.nearZ,this._helper._farZ=this._verticalPerspectiveTransform.farZ,this._mercatorTransform.apply(this,!0,this.isGlobeRendering),this._helper._nearZ=this._mercatorTransform.nearZ,this._helper._farZ=this._mercatorTransform.farZ)}calculateFogMatrix(l){return this.currentTransform.calculateFogMatrix(l)}getVisibleUnwrappedCoordinates(l){return this.currentTransform.getVisibleUnwrappedCoordinates(l)}getCameraFrustum(){return this.currentTransform.getCameraFrustum()}getClippingPlane(){return this.currentTransform.getClippingPlane()}getCoveringTilesDetailsProvider(){return this.currentTransform.getCoveringTilesDetailsProvider()}recalculateZoomAndCenter(l){this._mercatorTransform.recalculateZoomAndCenter(l),this._verticalPerspectiveTransform.recalculateZoomAndCenter(l)}maxPitchScaleFactor(){return this._mercatorTransform.maxPitchScaleFactor()}getCameraPoint(){return this._helper.getCameraPoint()}getCameraAltitude(){return this._helper.getCameraAltitude()}getCameraLngLat(){return this._helper.getCameraLngLat()}lngLatToCameraDepth(l,m){return this.currentTransform.lngLatToCameraDepth(l,m)}populateCache(l){this._mercatorTransform.populateCache(l),this._verticalPerspectiveTransform.populateCache(l)}getBounds(){return this.currentTransform.getBounds()}calculateCenterFromCameraLngLatAlt(l,m,T,P){return this._helper.calculateCenterFromCameraLngLatAlt(l,m,T,P)}setLocationAtPoint(l,m){if(!this.isGlobeRendering)return this._mercatorTransform.setLocationAtPoint(l,m),void this.apply(this._mercatorTransform);this._verticalPerspectiveTransform.setLocationAtPoint(l,m),this.apply(this._verticalPerspectiveTransform)}locationToScreenPoint(l,m){return this.currentTransform.locationToScreenPoint(l,m)}screenPointToMercatorCoordinate(l,m){return this.currentTransform.screenPointToMercatorCoordinate(l,m)}screenPointToLocation(l,m){return this.currentTransform.screenPointToLocation(l,m)}isPointOnMapSurface(l,m){return this.currentTransform.isPointOnMapSurface(l,m)}getRayDirectionFromPixel(l){return this._verticalPerspectiveTransform.getRayDirectionFromPixel(l)}getMatrixForModel(l,m){return this.currentTransform.getMatrixForModel(l,m)}getProjectionDataForCustomLayer(l=!0){let m=this._mercatorTransform.getProjectionDataForCustomLayer(l);if(!this.isGlobeRendering)return m;let T=this._verticalPerspectiveTransform.getProjectionDataForCustomLayer(l);return T.fallbackMatrix=m.mainMatrix,T}getFastPathSimpleProjectionMatrix(l){return this.currentTransform.getFastPathSimpleProjectionMatrix(l)}}class b{get useGlobeControls(){return!0}handlePanInertia(l,m){let T=gs(l,m);return Math.abs(T.lng-m.center.lng)>180&&(T.lng=m.center.lng+179.5*Math.sign(T.lng-m.center.lng)),{easingCenter:T,easingOffset:new o.P(0,0)}}handleMapControlsRollPitchBearingZoom(l,m){let T=l.around,P=m.screenPointToLocation(T);l.bearingDelta&&m.setBearing(m.bearing+l.bearingDelta),l.pitchDelta&&m.setPitch(m.pitch+l.pitchDelta),l.rollDelta&&m.setRoll(m.roll+l.rollDelta);let V=m.zoom;l.zoomDelta&&m.setZoom(m.zoom+l.zoomDelta);let W=m.zoom-V;if(W===0)return;let te=o.bL(m.center.lng,P.lng),se=te/(Math.abs(te/180)+1),fe=o.bL(m.center.lat,P.lat),ye=m.getRayDirectionFromPixel(T),Re=m.cameraPosition,Me=-1*o.b6(Re,ye),je=o.bA();o.b1(je,Re,[ye[0]*Me,ye[1]*Me,ye[2]*Me]);let tt=o.b8(je)-1,yt=Math.exp(.5*-Math.max(tt-.3,0)),At=li(m.worldSize,m.center.lat)/Math.min(m.width,m.height),vt=o.by(At,.9,.5,1,.25),Lt=(1-o.ar(-W))*Math.min(yt,vt),Kt=m.center.lat,It=m.zoom,Xt=new o.V(m.center.lng+se*Lt,o.ao(m.center.lat+fe*Lt,-o.ap,o.ap));m.setLocationAtPoint(P,T);let Rt=m.center,zt=o.by(Math.abs(te),45,85,0,1),jt=o.by(At,.75,.35,0,1),br=Math.pow(Math.max(zt,jt),.25),Cr=o.bL(Rt.lng,Xt.lng),Rr=o.bL(Rt.lat,Xt.lat);m.setCenter(new o.V(Rt.lng+Cr*br,Rt.lat+Rr*br).wrap()),m.setZoom(It+gn(Kt,m.center.lat))}handleMapControlsPan(l,m,T){if(!l.panDelta)return;let P=m.center.lat,V=m.zoom;m.setCenter(gs(l.panDelta,m).wrap()),m.setZoom(V+gn(P,m.center.lat))}cameraForBoxAndBearing(l,m,T,P,V){let W=Cp(l,m,T,P,V),te=m.left/V.width*2-1,se=(V.width-m.right)/V.width*2-1,fe=m.top/V.height*-2+1,ye=(V.height-m.bottom)/V.height*-2+1,Re=o.bL(T.getWest(),T.getEast())<0,Me=Re?T.getEast():T.getWest(),je=Re?T.getWest():T.getEast(),tt=Math.max(T.getNorth(),T.getSouth()),yt=Math.min(T.getNorth(),T.getSouth()),At=Me+.5*o.bL(Me,je),vt=tt+.5*o.bL(tt,yt),Lt=V.clone();Lt.setCenter(W.center),Lt.setBearing(W.bearing),Lt.setPitch(0),Lt.setRoll(0),Lt.setZoom(W.zoom);let Kt=Lt.modelViewProjectionMatrix,It=[Fr(T.getNorthWest()),Fr(T.getNorthEast()),Fr(T.getSouthWest()),Fr(T.getSouthEast()),Fr(new o.V(je,vt)),Fr(new o.V(Me,vt)),Fr(new o.V(At,tt)),Fr(new o.V(At,yt))],Xt=Fr(W.center),Rt=Number.POSITIVE_INFINITY;for(let zt of It)te<0&&(Rt=b.getLesserNonNegativeNonNull(Rt,b.solveVectorScale(zt,Xt,Kt,"x",te))),se>0&&(Rt=b.getLesserNonNegativeNonNull(Rt,b.solveVectorScale(zt,Xt,Kt,"x",se))),fe>0&&(Rt=b.getLesserNonNegativeNonNull(Rt,b.solveVectorScale(zt,Xt,Kt,"y",fe))),ye<0&&(Rt=b.getLesserNonNegativeNonNull(Rt,b.solveVectorScale(zt,Xt,Kt,"y",ye)));if(Number.isFinite(Rt)&&Rt!==0)return W.zoom=Lt.zoom+o.au(Rt),W;Wh()}handleJumpToCenterZoom(l,m){let T=l.center.lat,P=l.applyConstrain(m.center?o.V.convert(m.center):l.center,l.zoom).center;l.setCenter(P.wrap());let V=m.zoom!==void 0?+m.zoom:l.zoom+gn(T,P.lat);l.zoom!==V&&l.setZoom(V)}handleEaseTo(l,m){let T=l.zoom,P=l.center,V=l.padding,W={roll:l.roll,pitch:l.pitch,bearing:l.bearing},te={roll:m.roll===void 0?l.roll:m.roll,pitch:m.pitch===void 0?l.pitch:m.pitch,bearing:m.bearing===void 0?l.bearing:m.bearing},se=m.zoom!==void 0,fe=!l.isPaddingEqual(m.padding),ye=!1,Re=m.center?o.V.convert(m.center):P,Me=l.applyConstrain(Re,T).center;tu(l,Me);let je=l.clone();je.setCenter(Me),je.setZoom(se?+m.zoom:T+gn(P.lat,Re.lat)),je.setBearing(m.bearing);let tt=new o.P(o.ao(l.centerPoint.x+m.offsetAsPoint.x,0,l.width),o.ao(l.centerPoint.y+m.offsetAsPoint.y,0,l.height));je.setLocationAtPoint(Me,tt);let yt=(m.offset&&m.offsetAsPoint.mag())>0?je.center:Me,At=se?+m.zoom:T+gn(P.lat,yt.lat),vt=T+gn(P.lat,0),Lt=At+gn(yt.lat,0),Kt=o.bL(P.lng,yt.lng),It=o.bL(P.lat,yt.lat),Xt=o.ar(Lt-vt);return ye=At!==T,{easeFunc:Rt=>{if(o.bp(W,te)||Hd({startEulerAngles:W,endEulerAngles:te,tr:l,k:Rt,useSlerp:W.roll!=te.roll}),fe&&l.interpolatePadding(V,m.padding,Rt),m.around)o.w("Easing around a point is not supported under globe projection."),l.setLocationAtPoint(m.around,m.aroundPoint);else{let zt=Lt>vt?Math.min(2,Xt):Math.max(.5,Xt),jt=Math.pow(zt,1-Rt),br=bl(P,Kt,It,Rt*jt);l.setCenter(br.wrap())}if(ye){let zt=o.G.number(vt,Lt,Rt)+gn(0,l.center.lat);l.setZoom(zt)}},isZooming:ye,elevationCenter:yt}}handleFlyTo(l,m){let T=m.zoom!==void 0,P=l.center,V=l.zoom,W=l.padding,te=!l.isPaddingEqual(m.padding),se=l.applyConstrain(o.V.convert(m.center||m.locationAtOffset),V).center,fe=T?+m.zoom:l.zoom+gn(l.center.lat,se.lat),ye=l.clone();ye.setCenter(se),ye.setZoom(fe),ye.setBearing(m.bearing);let Re=new o.P(o.ao(l.centerPoint.x+m.offsetAsPoint.x,0,l.width),o.ao(l.centerPoint.y+m.offsetAsPoint.y,0,l.height));ye.setLocationAtPoint(se,Re);let Me=ye.center;tu(l,Me);let je=function(It,Xt,Rt){let zt=Fr(Xt),jt=Fr(Rt),br=o.b6(zt,jt),Cr=Math.acos(br),Rr=Ut(It);return Cr/(2*Math.PI)*Rr}(l,P,Me),tt=V+gn(P.lat,0),yt=fe+gn(Me.lat,0),At=o.ar(yt-tt),vt;if(typeof m.minZoom=="number"){let It=+m.minZoom+gn(Me.lat,0),Xt=Math.min(It,tt,yt)+gn(0,Me.lat),Rt=l.applyConstrain(Me,Xt).zoom+gn(Me.lat,0);vt=o.ar(Rt-tt)}let Lt=o.bL(P.lng,Me.lng),Kt=o.bL(P.lat,Me.lat);return{easeFunc:(It,Xt,Rt,zt)=>{let jt=bl(P,Lt,Kt,Rt);te&&l.interpolatePadding(W,m.padding,It);let br=It===1?Me:jt;l.setCenter(br.wrap());let Cr=tt+o.au(Xt);l.setZoom(It===1?fe:Cr+gn(0,br.lat))},scaleOfZoom:At,targetCenter:Me,scaleOfMinZoom:vt,pixelPathLength:je}}static solveVectorScale(l,m,T,P,V){let W=P==="x"?[T[0],T[4],T[8],T[12]]:[T[1],T[5],T[9],T[13]],te=[T[3],T[7],T[11],T[15]],se=l[0]*W[0]+l[1]*W[1]+l[2]*W[2],fe=l[0]*te[0]+l[1]*te[1]+l[2]*te[2],ye=m[0]*W[0]+m[1]*W[1]+m[2]*W[2],Re=m[0]*te[0]+m[1]*te[1]+m[2]*te[2];return ye+V*fe===se+V*Re||te[3]*(se-ye)+W[3]*(Re-fe)+se*Re==ye*fe?null:(ye+W[3]-V*Re-V*te[3])/(ye-se-V*Re+V*fe)}static getLesserNonNegativeNonNull(l,m){return m!==null&&m>=0&&mo.B(z,l&&l.filter(m=>m.identifier!=="source.canvas")),Ye=o.bP();class Ms extends o.E{constructor(l,m={}){var T,P;super(),this._rtlPluginLoaded=()=>{for(let W in this.tileManagers){let te=this.tileManagers[W].getSource().type;te!=="vector"&&te!=="geojson"||this.tileManagers[W].reload()}},this.map=l,this.dispatcher=new Ft(nt(),l._getMapId()),this.dispatcher.registerMessageHandler("GG",(W,te)=>this.getGlyphs(W,te)),this.dispatcher.registerMessageHandler("GI",(W,te)=>this.getImages(W,te)),this.dispatcher.registerMessageHandler("GDA",(W,te)=>this.getDashes(W,te)),this.imageManager=new _e,this.imageManager.setEventedParent(this);let V=((T=l._container)===null||T===void 0?void 0:T.lang)||typeof document<"u"&&((P=document.documentElement)===null||P===void 0?void 0:P.lang)||void 0;this.glyphManager=new sr(l._requestManager,m.localIdeographFontFamily,V),this.lineAtlas=new Yr(256,512),this.crossTileSymbolIndex=new Ql,this._setInitialValues(),this._resetUpdates(),this.dispatcher.broadcast("SR",o.bQ()),fr().on(Vt,this._rtlPluginLoaded),this.on("data",W=>{if(W.dataType!=="source"||W.sourceDataType!=="metadata")return;let te=this.tileManagers[W.sourceId];if(!te)return;let se=te.getSource();if(se&&se.vectorLayerIds)for(let fe in this._layers){let ye=this._layers[fe];ye.source===se.id&&this._validateLayer(ye)}})}_setInitialValues(){var l;this._spritesImagesIds={},this._layers={},this._order=[],this.tileManagers={},this.zoomHistory=new o.bR,this._availableImages=[],this._globalState={},this._serializedLayers={},this.stylesheet=null,this.light=null,this.sky=null,this.projection&&(this.projection.destroy(),delete this.projection),this._loaded=!1,this._changed=!1,this._updatedLayers={},this._updatedSources={},this._changedImages={},this._glyphsDidChange=!1,this._updatedPaintProps={},this._layerOrderChanged=!1,this.crossTileSymbolIndex=new(((l=this.crossTileSymbolIndex)===null||l===void 0?void 0:l.constructor)||Object),this.pauseablePlacement=void 0,this.placement=void 0,this.z=0}setGlobalStateProperty(l,m){var T,P,V;this._checkLoaded();let W=m===null?(V=(P=(T=this.stylesheet.state)===null||T===void 0?void 0:T[l])===null||P===void 0?void 0:P.default)!==null&&V!==void 0?V:null:m;if(o.bS(W,this._globalState[l]))return this;this._globalState[l]=W,this._applyGlobalStateChanges([l])}getGlobalState(){return this._globalState}setGlobalState(l){this._checkLoaded();let m=[];for(let T in l)!o.bS(this._globalState[T],l[T].default)&&(m.push(T),this._globalState[T]=l[T].default);this._applyGlobalStateChanges(m)}_applyGlobalStateChanges(l){if(l.length===0)return;let m=new Set,T={};for(let P of l){T[P]=this._globalState[P];for(let V in this._layers){let W=this._layers[V],te=W.getLayoutAffectingGlobalStateRefs(),se=W.getPaintAffectingGlobalStateRefs();if(te.has(P)&&m.add(W.source),se.has(P))for(let{name:fe,value:ye}of se.get(P))this._updatePaintProperty(W,fe,ye)}}this.dispatcher.broadcast("UGS",T);for(let P in this.tileManagers)m.has(P)&&(this._reloadSource(P),this._changed=!0)}loadURL(l,m={},T){this.fire(new o.l("dataloading",{dataType:"style"})),m.validate=typeof m.validate!="boolean"||m.validate;let P=this.map._requestManager.transformRequest(l,"Style");this._loadStyleRequest=new AbortController;let V=this._loadStyleRequest;o.j(P,this._loadStyleRequest).then(W=>{this._loadStyleRequest=null,this._load(W.data,m,T)}).catch(W=>{this._loadStyleRequest=null,W&&!V.signal.aborted&&this.fire(new o.k(W))})}loadJSON(l,m={},T){this.fire(new o.l("dataloading",{dataType:"style"})),this._frameRequest=new AbortController,I.frameAsync(this._frameRequest).then(()=>{this._frameRequest=null,m.validate=m.validate!==!1,this._load(l,m,T)}).catch(()=>{})}loadEmpty(){this.fire(new o.l("dataloading",{dataType:"style"})),this._load(Ye,{validate:!1})}_load(l,m,T){var P,V;let W=m.transformStyle?m.transformStyle(T,l):l;if(!m.validate||!_o(this,o.C(W))){W=Object.assign({},W),this._loaded=!0,this.stylesheet=W;for(let te in W.sources)this.addSource(te,W.sources[te],{validate:!1});W.sprite?this._loadSprite(W.sprite):this.imageManager.setLoaded(!0),this.glyphManager.setURL(W.glyphs),this._createLayers(),this.light=new mi(this.stylesheet.light),this._setProjectionInternal(((P=this.stylesheet.projection)===null||P===void 0?void 0:P.type)||"mercator"),this.sky=new un(this.stylesheet.sky),this.map.setTerrain((V=this.stylesheet.terrain)!==null&&V!==void 0?V:null),this.fire(new o.l("data",{dataType:"style"})),this.fire(new o.l("style.load"))}}_createLayers(){var l,m,T;let P=o.bT(this.stylesheet.layers);this.setGlobalState((l=this.stylesheet.state)!==null&&l!==void 0?l:null),this.dispatcher.broadcast("SL",P),this._order=P.map(V=>V.id),this._layers={},this._serializedLayers=null;for(let V of P){let W=o.bU(V,this._globalState);if(W.setEventedParent(this,{layer:{id:V.id}}),this._layers[V.id]=W,o.bV(W)&&this.tileManagers[W.source]){let te=(T=(m=V.paint)===null||m===void 0?void 0:m["raster-fade-duration"])!==null&&T!==void 0?T:W.paint.get("raster-fade-duration");this.tileManagers[W.source].setRasterFadeDuration(te)}}}_loadSprite(l,m=!1,T=void 0){this.imageManager.setLoaded(!1);let P=new AbortController,V;this._spriteRequest=P,function(W,te,se,fe){return o._(this,void 0,void 0,function*(){let ye=Ge(W),Re=se>1?"@2x":"",Me={},je={};for(let{id:tt,url:yt}of ye){let At=te.transformRequest(Xe(yt,Re,".json"),"SpriteJSON");Me[tt]=o.j(At,fe);let vt=te.transformRequest(Xe(yt,Re,".png"),"SpriteImage");je[tt]=Oe.getImage(vt,fe)}return yield Promise.all([...Object.values(Me),...Object.values(je)]),function(tt,yt){return o._(this,void 0,void 0,function*(){let At={};for(let vt in tt){At[vt]={};let Lt=I.getImageCanvasContext((yield yt[vt]).data),Kt=(yield tt[vt]).data;for(let It in Kt){let{width:Xt,height:Rt,x:zt,y:jt,sdf:br,pixelRatio:Cr,stretchX:Rr,stretchY:Pr,content:Ai,textFitWidth:_i,textFitHeight:hi}=Kt[It];At[vt][It]={data:null,pixelRatio:Cr,sdf:br,stretchX:Rr,stretchY:Pr,content:Ai,textFitWidth:_i,textFitHeight:hi,spriteData:{width:Xt,height:Rt,x:zt,y:jt,context:Lt}}}}return At})}(Me,je)})}(l,this.map._requestManager,this.map.getPixelRatio(),this._spriteRequest).then(W=>{if(this._spriteRequest=null,W)for(let te in W){this._spritesImagesIds[te]=[];let se=this._spritesImagesIds[te]?this._spritesImagesIds[te].filter(fe=>!(fe in W)):[];for(let fe of se)this.imageManager.removeImage(fe),this._changedImages[fe]=!0;for(let fe in W[te]){let ye=te==="default"?fe:`${te}:${fe}`;this._spritesImagesIds[te].push(ye),ye in this.imageManager.images?this.imageManager.updateImage(ye,W[te][fe],!1):this.imageManager.addImage(ye,W[te][fe]),m&&(this._changedImages[ye]=!0)}}}).catch(W=>{this._spriteRequest=null,V=W,P.signal.aborted||this.fire(new o.k(V))}).finally(()=>{this.imageManager.setLoaded(!0),this._availableImages=this.imageManager.listImages(),m&&(this._changed=!0),this.dispatcher.broadcast("SI",this._availableImages),this.fire(new o.l("data",{dataType:"style"})),T&&T(V)})}_unloadSprite(){for(let l of Object.values(this._spritesImagesIds).flat())this.imageManager.removeImage(l),this._changedImages[l]=!0;this._spritesImagesIds={},this._availableImages=this.imageManager.listImages(),this._changed=!0,this.dispatcher.broadcast("SI",this._availableImages),this.fire(new o.l("data",{dataType:"style"}))}_validateLayer(l){let m=this.tileManagers[l.source];if(!m)return;let T=l.sourceLayer;if(!T)return;let P=m.getSource();(P.type==="geojson"||P.vectorLayerIds&&P.vectorLayerIds.indexOf(T)===-1)&&this.fire(new o.k(new Error(`Source layer "${T}" does not exist on source "${P.id}" as specified by style layer "${l.id}".`)))}loaded(){if(!this._loaded||Object.keys(this._updatedSources).length)return!1;for(let l in this.tileManagers)if(!this.tileManagers[l].loaded())return!1;return!!this.imageManager.isLoaded()}_serializeByIds(l,m=!1){let T=this._serializedAllLayers();if(!l||l.length===0)return Object.values(m?o.bW(T):T);let P=[];for(let V of l)if(T[V]){let W=m?o.bW(T[V]):T[V];P.push(W)}return P}_serializedAllLayers(){let l=this._serializedLayers;if(l)return l;l=this._serializedLayers={};let m=Object.keys(this._layers);for(let T of m){let P=this._layers[T];P.type!=="custom"&&(l[T]=P.serialize())}return l}hasTransitions(){var l,m,T;if(!((l=this.light)===null||l===void 0)&&l.hasTransition()||!((m=this.sky)===null||m===void 0)&&m.hasTransition()||!((T=this.projection)===null||T===void 0)&&T.hasTransition())return!0;for(let P in this.tileManagers)if(this.tileManagers[P].hasTransition())return!0;for(let P in this._layers)if(this._layers[P].hasTransition())return!0;return!1}_checkLoaded(){if(!this._loaded)throw new Error("Style is not done loading.")}update(l){if(!this._loaded)return;let m=this._changed;if(m){let P=Object.keys(this._updatedLayers),V=Object.keys(this._removedLayers);(P.length||V.length)&&this._updateWorkerLayers(P,V);for(let W in this._updatedSources){let te=this._updatedSources[W];if(te==="reload")this._reloadSource(W);else{if(te!=="clear")throw new Error(`Invalid action ${te}`);this._clearSource(W)}}this._updateTilesForChangedImages(),this._updateTilesForChangedGlyphs();for(let W in this._updatedPaintProps)this._layers[W].updateTransitions(l);this.light.updateTransitions(l),this.sky.updateTransitions(l),this._resetUpdates()}let T={};for(let P in this.tileManagers){let V=this.tileManagers[P];T[P]=V.used,V.used=!1}for(let P of this._order){let V=this._layers[P];V.recalculate(l,this._availableImages),!V.isHidden(l.zoom)&&V.source&&(this.tileManagers[V.source].used=!0)}for(let P in T){let V=this.tileManagers[P];!!T[P]!=!!V.used&&V.fire(new o.l("data",{sourceDataType:"visibility",dataType:"source",sourceId:P}))}this.light.recalculate(l),this.sky.recalculate(l),this.projection.recalculate(l),this.z=l.zoom,m&&this.fire(new o.l("data",{dataType:"style"}))}_updateTilesForChangedImages(){let l=Object.keys(this._changedImages);if(l.length){for(let m in this.tileManagers)this.tileManagers[m].reloadTilesForDependencies(["icons","patterns"],l);this._changedImages={}}}_updateTilesForChangedGlyphs(){if(this._glyphsDidChange){for(let l in this.tileManagers)this.tileManagers[l].reloadTilesForDependencies(["glyphs"],[""]);this._glyphsDidChange=!1}}_updateWorkerLayers(l,m){this.dispatcher.broadcast("UL",{layers:this._serializeByIds(l,!1),removedIds:m})}_resetUpdates(){this._changed=!1,this._updatedLayers={},this._removedLayers={},this._updatedSources={},this._updatedPaintProps={},this._changedImages={},this._glyphsDidChange=!1}setState(l,m={}){var T;this._checkLoaded();let P=this.serialize();if(l=m.transformStyle?m.transformStyle(P,l):l,((T=m.validate)===null||T===void 0||T)&&_o(this,o.C(l)))return!1;(l=o.bW(l)).layers=o.bT(l.layers);let V=o.bX(P,l),W=this._getOperationsToPerform(V);if(W.unimplemented.length>0)throw new Error(`Unimplemented: ${W.unimplemented.join(", ")}.`);if(W.operations.length===0)return!1;for(let te of W.operations)te();return this.stylesheet=l,this._serializedLayers=null,!0}_getOperationsToPerform(l){let m=[],T=[];for(let P of l)switch(P.command){case"setCenter":case"setZoom":case"setBearing":case"setPitch":case"setRoll":continue;case"addLayer":m.push(()=>this.addLayer.apply(this,P.args));break;case"removeLayer":m.push(()=>this.removeLayer.apply(this,P.args));break;case"setPaintProperty":m.push(()=>this.setPaintProperty.apply(this,P.args));break;case"setLayoutProperty":m.push(()=>this.setLayoutProperty.apply(this,P.args));break;case"setFilter":m.push(()=>this.setFilter.apply(this,P.args));break;case"addSource":m.push(()=>this.addSource.apply(this,P.args));break;case"removeSource":m.push(()=>this.removeSource.apply(this,P.args));break;case"setLayerZoomRange":m.push(()=>this.setLayerZoomRange.apply(this,P.args));break;case"setLight":m.push(()=>this.setLight.apply(this,P.args));break;case"setGeoJSONSourceData":m.push(()=>this.setGeoJSONSourceData.apply(this,P.args));break;case"setGlyphs":m.push(()=>this.setGlyphs.apply(this,P.args));break;case"setSprite":m.push(()=>this.setSprite.apply(this,P.args));break;case"setTerrain":m.push(()=>this.map.setTerrain.apply(this,P.args));break;case"setSky":m.push(()=>this.setSky.apply(this,P.args));break;case"setProjection":this.setProjection.apply(this,P.args);break;case"setGlobalState":m.push(()=>this.setGlobalState.apply(this,P.args));break;case"setTransition":m.push(()=>{});break;default:T.push(P.command)}return{operations:m,unimplemented:T}}addImage(l,m){if(this.getImage(l))return this.fire(new o.k(new Error(`An image named "${l}" already exists.`)));this.imageManager.addImage(l,m),this._afterImageUpdated(l)}updateImage(l,m){this.imageManager.updateImage(l,m)}getImage(l){return this.imageManager.getImage(l)}removeImage(l){if(!this.getImage(l))return this.fire(new o.k(new Error(`An image named "${l}" does not exist.`)));this.imageManager.removeImage(l),this._afterImageUpdated(l)}_afterImageUpdated(l){this._availableImages=this.imageManager.listImages(),this._changedImages[l]=!0,this._changed=!0,this.dispatcher.broadcast("SI",this._availableImages),this.fire(new o.l("data",{dataType:"style"}))}listImages(){return this._checkLoaded(),this.imageManager.listImages()}addSource(l,m,T={}){if(this._checkLoaded(),this.tileManagers[l]!==void 0)throw new Error(`Source "${l}" already exists.`);if(!m.type)throw new Error(`The type property must be defined, but only the following properties were given: ${Object.keys(m).join(", ")}.`);if(["vector","raster","geojson","video","image"].indexOf(m.type)>=0&&this._validate(o.C.source,`sources.${l}`,m,null,T))return;this.map&&this.map._collectResourceTiming&&(m.collectResourceTiming=!0);let P=this.tileManagers[l]=new si(l,m,this.dispatcher);P.style=this,P.setEventedParent(this,()=>({isSourceLoaded:P.loaded(),source:P.serialize(),sourceId:l})),P.onAdd(this.map),this._changed=!0}removeSource(l){if(this._checkLoaded(),this.tileManagers[l]===void 0)throw new Error("There is no source with this ID");for(let T in this._layers)if(this._layers[T].source===l)return this.fire(new o.k(new Error(`Source "${l}" cannot be removed while layer "${T}" is using it.`)));let m=this.tileManagers[l];delete this.tileManagers[l],delete this._updatedSources[l],m.fire(new o.l("data",{sourceDataType:"metadata",dataType:"source",sourceId:l})),m.setEventedParent(null),m.onRemove(this.map),this._changed=!0}setGeoJSONSourceData(l,m){if(this._checkLoaded(),this.tileManagers[l]===void 0)throw new Error(`There is no source with this ID=${l}`);let T=this.tileManagers[l].getSource();if(T.type!=="geojson")throw new Error(`geojsonSource.type is ${T.type}, which is !== 'geojson`);T.setData(m),this._changed=!0}getSource(l){return this.tileManagers[l]&&this.tileManagers[l].getSource()}addLayer(l,m,T={}){this._checkLoaded();let P=l.id;if(this.getLayer(P))return void this.fire(new o.k(new Error(`Layer "${P}" already exists on this map.`)));let V;if(l.type==="custom"){if(_o(this,o.bY(l)))return;V=o.bU(l,this._globalState)}else{if("source"in l&&typeof l.source=="object"&&(this.addSource(P,l.source),l=o.bW(l),l=o.e(l,{source:P})),this._validate(o.C.layer,`layers.${P}`,l,{arrayIndex:-1},T))return;V=o.bU(l,this._globalState),this._validateLayer(V),V.setEventedParent(this,{layer:{id:P}})}let W=m?this._order.indexOf(m):this._order.length;if(m&&W===-1)this.fire(new o.k(new Error(`Cannot add layer "${P}" before non-existing layer "${m}".`)));else{if(this._order.splice(W,0,P),this._layerOrderChanged=!0,this._layers[P]=V,this._removedLayers[P]&&V.source&&V.type!=="custom"){let te=this._removedLayers[P];delete this._removedLayers[P],te.type!==V.type?this._updatedSources[V.source]="clear":(this._updatedSources[V.source]="reload",this.tileManagers[V.source].pause())}this._updateLayer(V),V.onAdd&&V.onAdd(this.map)}}moveLayer(l,m){if(this._checkLoaded(),this._changed=!0,!this._layers[l])return void this.fire(new o.k(new Error(`The layer '${l}' does not exist in the map's style and cannot be moved.`)));if(l===m)return;let T=this._order.indexOf(l);this._order.splice(T,1);let P=m?this._order.indexOf(m):this._order.length;m&&P===-1?this.fire(new o.k(new Error(`Cannot move layer "${l}" before non-existing layer "${m}".`))):(this._order.splice(P,0,l),this._layerOrderChanged=!0)}removeLayer(l){this._checkLoaded();let m=this._layers[l];if(!m)return void this.fire(new o.k(new Error(`Cannot remove non-existing layer "${l}".`)));m.setEventedParent(null);let T=this._order.indexOf(l);this._order.splice(T,1),this._layerOrderChanged=!0,this._changed=!0,this._removedLayers[l]=m,delete this._layers[l],this._serializedLayers&&delete this._serializedLayers[l],delete this._updatedLayers[l],delete this._updatedPaintProps[l],m.onRemove&&m.onRemove(this.map)}getLayer(l){return this._layers[l]}getLayersOrder(){return[...this._order]}hasLayer(l){return l in this._layers}setLayerZoomRange(l,m,T){this._checkLoaded();let P=this.getLayer(l);P?P.minzoom===m&&P.maxzoom===T||(m!=null&&(P.minzoom=m),T!=null&&(P.maxzoom=T),this._updateLayer(P)):this.fire(new o.k(new Error(`Cannot set the zoom range of non-existing layer "${l}".`)))}setFilter(l,m,T={}){this._checkLoaded();let P=this.getLayer(l);if(P){if(!o.bS(P.filter,m))return m==null?(P.setFilter(void 0),void this._updateLayer(P)):void(this._validate(o.C.filter,`layers.${P.id}.filter`,m,null,T)||(P.setFilter(o.bW(m)),this._updateLayer(P)))}else this.fire(new o.k(new Error(`Cannot filter non-existing layer "${l}".`)))}getFilter(l){return o.bW(this.getLayer(l).filter)}setLayoutProperty(l,m,T,P={}){this._checkLoaded();let V=this.getLayer(l);V?o.bS(V.getLayoutProperty(m),T)||(V.setLayoutProperty(m,T,P),this._updateLayer(V)):this.fire(new o.k(new Error(`Cannot style non-existing layer "${l}".`)))}getLayoutProperty(l,m){let T=this.getLayer(l);if(T)return T.getLayoutProperty(m);this.fire(new o.k(new Error(`Cannot get style of non-existing layer "${l}".`)))}setPaintProperty(l,m,T,P={}){this._checkLoaded();let V=this.getLayer(l);V?o.bS(V.getPaintProperty(m),T)||this._updatePaintProperty(V,m,T,P):this.fire(new o.k(new Error(`Cannot style non-existing layer "${l}".`)))}_updatePaintProperty(l,m,T,P={}){l.setPaintProperty(m,T,P)&&this._updateLayer(l),o.bV(l)&&m==="raster-fade-duration"&&this.tileManagers[l.source].setRasterFadeDuration(T),this._changed=!0,this._updatedPaintProps[l.id]=!0,this._serializedLayers=null}getPaintProperty(l,m){return this.getLayer(l).getPaintProperty(m)}setFeatureState(l,m){this._checkLoaded();let T=l.source,P=l.sourceLayer,V=this.tileManagers[T];if(V===void 0)return void this.fire(new o.k(new Error(`The source '${T}' does not exist in the map's style.`)));let W=V.getSource().type;W==="geojson"&&P?this.fire(new o.k(new Error("GeoJSON sources cannot have a sourceLayer parameter."))):W!=="vector"||P?(l.id===void 0&&this.fire(new o.k(new Error("The feature id parameter must be provided."))),V.setFeatureState(P,l.id,m)):this.fire(new o.k(new Error("The sourceLayer parameter must be provided for vector source types.")))}removeFeatureState(l,m){this._checkLoaded();let T=l.source,P=this.tileManagers[T];if(P===void 0)return void this.fire(new o.k(new Error(`The source '${T}' does not exist in the map's style.`)));let V=P.getSource().type,W=V==="vector"?l.sourceLayer:void 0;V!=="vector"||W?m&&typeof l.id!="string"&&typeof l.id!="number"?this.fire(new o.k(new Error("A feature id is required to remove its specific state property."))):P.removeFeatureState(W,l.id,m):this.fire(new o.k(new Error("The sourceLayer parameter must be provided for vector source types.")))}getFeatureState(l){this._checkLoaded();let m=l.source,T=l.sourceLayer,P=this.tileManagers[m];if(P!==void 0)return P.getSource().type!=="vector"||T?(l.id===void 0&&this.fire(new o.k(new Error("The feature id parameter must be provided."))),P.getFeatureState(T,l.id)):void this.fire(new o.k(new Error("The sourceLayer parameter must be provided for vector source types.")));this.fire(new o.k(new Error(`The source '${m}' does not exist in the map's style.`)))}getTransition(){return o.e({duration:300,delay:0},this.stylesheet&&this.stylesheet.transition)}serialize(){if(!this._loaded)return;let l=o.bZ(this.tileManagers,V=>V.serialize()),m=this._serializeByIds(this._order,!0),T=this.map.getTerrain()||void 0,P=this.stylesheet;return o.b_({version:P.version,name:P.name,metadata:P.metadata,light:P.light,sky:P.sky,center:P.center,zoom:P.zoom,bearing:P.bearing,pitch:P.pitch,sprite:P.sprite,glyphs:P.glyphs,transition:P.transition,projection:P.projection,sources:l,layers:m,terrain:T},V=>V!==void 0)}_updateLayer(l){this._updatedLayers[l.id]=!0,l.source&&!this._updatedSources[l.source]&&this.tileManagers[l.source].getSource().type!=="raster"&&(this._updatedSources[l.source]="reload",this.tileManagers[l.source].pause()),this._serializedLayers=null,this._changed=!0}_flattenAndSortRenderedFeatures(l){let m=W=>this._layers[W].type==="fill-extrusion",T={},P=[];for(let W=this._order.length-1;W>=0;W--){let te=this._order[W];if(m(te)){T[te]=W;for(let se of l){let fe=se[te];if(fe)for(let ye of fe)P.push(ye)}}}P.sort((W,te)=>te.intersectionZ-W.intersectionZ);let V=[];for(let W=this._order.length-1;W>=0;W--){let te=this._order[W];if(m(te))for(let se=P.length-1;se>=0;se--){let fe=P[se].feature;if(T[fe.layer.id]this.map.terrain.getElevation(ye,Re,Me):void 0));return this.placement&&V.push(function(fe,ye,Re,Me,je,tt,yt){let At={},vt=tt.queryRenderedSymbols(Me),Lt=[];for(let Kt of Object.keys(vt).map(Number))Lt.push(yt[Kt]);Lt.sort(ln);for(let Kt of Lt){let It=Kt.featureIndex.lookupSymbolFeatures(vt[Kt.bucketInstanceId],ye,Kt.bucketIndex,Kt.sourceLayerIndex,{filterSpec:je.filter,globalState:je.globalState},je.layers,je.availableImages,fe);for(let Xt in It){let Rt=At[Xt]=At[Xt]||[],zt=It[Xt];zt.sort((jt,br)=>{let Cr=Kt.featureSortOrder;if(Cr){let Rr=Cr.indexOf(jt.featureIndex);return Cr.indexOf(br.featureIndex)-Rr}return br.featureIndex-jt.featureIndex});for(let jt of zt)Rt.push(jt)}}return function(Kt,It,Xt){for(let Rt in Kt)for(let zt of Kt[Rt])Nn(zt,Xt[It[Rt].source]);return Kt}(At,fe,Re)}(this._layers,W,this.tileManagers,l,se,this.placement.collisionIndex,this.placement.retainedQueryData)),this._flattenAndSortRenderedFeatures(V)}querySourceFeatures(l,m){m?.filter&&this._validate(o.C.filter,"querySourceFeatures.filter",m.filter,null,m);let T=this.tileManagers[l];return T?function(P,V){let W=P.getRenderableIds().map(fe=>P.getTileByID(fe)),te=[],se={};for(let fe=0;feMe.getTileByID(je)).sort((je,tt)=>tt.tileID.overscaledZ-je.tileID.overscaledZ||(je.tileID.isLessThan(tt.tileID)?-1:1))}let Re=this.crossTileSymbolIndex.addLayer(ye,se[ye.source],l.center.lng);W=W||Re}if(this.crossTileSymbolIndex.pruneUnusedLayers(this._order),((V=V||this._layerOrderChanged||T===0)||!this.pauseablePlacement||this.pauseablePlacement.isDone()&&!this.placement.stillRecent(k(),l.zoom))&&(this.pauseablePlacement=new Hh(l,this.map.terrain,this._order,V,m,T,P,this.placement),this._layerOrderChanged=!1),this.pauseablePlacement.isDone()?this.placement.setStale():(this.pauseablePlacement.continuePlacement(this._order,this._layers,se),this.pauseablePlacement.isDone()&&(this.placement=this.pauseablePlacement.commit(k()),te=!0),W&&this.pauseablePlacement.placement.setStale()),te||W)for(let fe of this._order){let ye=this._layers[fe];ye.type==="symbol"&&this.placement.updateLayerOpacities(ye,se[ye.source])}return!this.pauseablePlacement.isDone()||this.placement.hasTransitions(k())}_releaseSymbolFadeTiles(){for(let l in this.tileManagers)this.tileManagers[l].releaseSymbolFadeTiles()}getImages(l,m){return o._(this,void 0,void 0,function*(){let T=yield this.imageManager.getImages(m.icons);this._updateTilesForChangedImages();let P=this.tileManagers[m.source];return P&&P.setDependencies(m.tileID.key,m.type,m.icons),T})}getGlyphs(l,m){return o._(this,void 0,void 0,function*(){let T=yield this.glyphManager.getGlyphs(m.stacks),P=this.tileManagers[m.source];return P&&P.setDependencies(m.tileID.key,m.type,[""]),T})}getGlyphsUrl(){return this.stylesheet.glyphs||null}setGlyphs(l,m={}){this._checkLoaded(),l&&this._validate(o.C.glyphs,"glyphs",l,null,m)||(this._glyphsDidChange=!0,this.stylesheet.glyphs=l,this.glyphManager.entries={},this.glyphManager.setURL(l))}getDashes(l,m){return o._(this,void 0,void 0,function*(){let T={};for(let[P,V]of Object.entries(m.dashes))T[P]=this.lineAtlas.getDash(V.dasharray,V.round);return T})}addSprite(l,m,T={},P){this._checkLoaded();let V=[{id:l,url:m}],W=[...Ge(this.stylesheet.sprite),...V];this._validate(o.C.sprite,"sprite",W,null,T)||(this.stylesheet.sprite=W,this._loadSprite(V,!0,P))}removeSprite(l){this._checkLoaded();let m=Ge(this.stylesheet.sprite);if(m.find(T=>T.id===l)){if(this._spritesImagesIds[l])for(let T of this._spritesImagesIds[l])this.imageManager.removeImage(T),this._changedImages[T]=!0;m.splice(m.findIndex(T=>T.id===l),1),this.stylesheet.sprite=m.length>0?m:void 0,delete this._spritesImagesIds[l],this._availableImages=this.imageManager.listImages(),this._changed=!0,this.dispatcher.broadcast("SI",this._availableImages),this.fire(new o.l("data",{dataType:"style"}))}else this.fire(new o.k(new Error(`Sprite "${l}" doesn't exists on this map.`)))}getSprite(){return Ge(this.stylesheet.sprite)}setSprite(l,m={},T){this._checkLoaded(),l&&this._validate(o.C.sprite,"sprite",l,null,m)||(this.stylesheet.sprite=l,l?this._loadSprite(l,!0,T):(this._unloadSprite(),T&&T(null)))}destroy(){this._frameRequest&&(this._frameRequest.abort(),this._frameRequest=null),this._loadStyleRequest&&(this._loadStyleRequest.abort(),this._loadStyleRequest=null),this._spriteRequest&&(this._spriteRequest.abort(),this._spriteRequest=null);for(let l in this.tileManagers){let m=this.tileManagers[l];m.setEventedParent(null),m.onRemove(this.map)}this.tileManagers={},this.imageManager&&(this.imageManager.setEventedParent(null),this.imageManager.destroy(),this._availableImages=[],this._spritesImagesIds={}),this.glyphManager&&this.glyphManager.destroy();for(let l in this._layers){let m=this._layers[l];m.setEventedParent(null),m.onRemove&&m.onRemove(this.map)}this._setInitialValues(),this.setEventedParent(null),this.dispatcher.unregisterMessageHandler("GG"),this.dispatcher.unregisterMessageHandler("GI"),this.dispatcher.unregisterMessageHandler("GDA"),this.dispatcher.remove(!0),this._listeners={},this._oneTimeListeners={}}}var ao=o.aV([{name:"a_pos",type:"Int16",components:2},{name:"a_texture_pos",type:"Int16",components:2}]);class Ps{constructor(){this.boundProgram=null,this.boundLayoutVertexBuffer=null,this.boundPaintVertexBuffers=[],this.boundIndexBuffer=null,this.boundVertexOffset=null,this.boundDynamicVertexBuffer=null,this.vao=null}bind(l,m,T,P,V,W,te,se,fe){this.context=l;let ye=this.boundPaintVertexBuffers.length!==P.length;for(let Re=0;!ye&&Re({u_texture:0,u_ele_delta:z,u_fog_matrix:l,u_fog_color:m?m.properties.get("fog-color"):o.bq.white,u_fog_ground_blend:m?m.properties.get("fog-ground-blend"):1,u_fog_ground_blend_opacity:P?0:m?m.calculateFogBlendOpacity(T):0,u_horizon_color:m?m.properties.get("horizon-color"):o.bq.white,u_horizon_fog_blend:m?m.properties.get("horizon-fog-blend"):1,u_is_globe_mode:P?1:0}),Go={mainMatrix:"u_projection_matrix",tileMercatorCoords:"u_projection_tile_mercator_coords",clippingPlane:"u_projection_clipping_plane",projectionTransition:"u_projection_transition",fallbackMatrix:"u_projection_fallback_matrix"};function Qs(z){let l=[];for(let m=0;m({u_depth:new o.b$(Cr,Rr.u_depth),u_terrain:new o.b$(Cr,Rr.u_terrain),u_terrain_dim:new o.br(Cr,Rr.u_terrain_dim),u_terrain_matrix:new o.c1(Cr,Rr.u_terrain_matrix),u_terrain_unpack:new o.c2(Cr,Rr.u_terrain_unpack),u_terrain_exaggeration:new o.br(Cr,Rr.u_terrain_exaggeration)}))(l,br),this.projectionUniforms=((Cr,Rr)=>({u_projection_matrix:new o.c1(Cr,Rr.u_projection_matrix),u_projection_tile_mercator_coords:new o.c2(Cr,Rr.u_projection_tile_mercator_coords),u_projection_clipping_plane:new o.c2(Cr,Rr.u_projection_clipping_plane),u_projection_transition:new o.br(Cr,Rr.u_projection_transition),u_projection_fallback_matrix:new o.c1(Cr,Rr.u_projection_fallback_matrix)}))(l,br),this.binderUniforms=T?T.getUniforms(l,br):[]}draw(l,m,T,P,V,W,te,se,fe,ye,Re,Me,je,tt,yt,At,vt,Lt,Kt){let It=l.gl;if(this.failedToCreate)return;if(l.program.set(this.program),l.setDepthMode(T),l.setStencilMode(P),l.setColorMode(V),l.setCullFace(W),se){l.activeTexture.set(It.TEXTURE2),It.bindTexture(It.TEXTURE_2D,se.depthTexture),l.activeTexture.set(It.TEXTURE3),It.bindTexture(It.TEXTURE_2D,se.texture);for(let Rt in this.terrainUniforms)this.terrainUniforms[Rt].set(se[Rt])}if(fe)for(let Rt in fe)this.projectionUniforms[Go[Rt]].set(fe[Rt]);if(te)for(let Rt in this.fixedUniforms)this.fixedUniforms[Rt].set(te[Rt]);At&&At.setUniforms(l,this.binderUniforms,tt,{zoom:yt});let Xt=0;switch(m){case It.LINES:Xt=2;break;case It.TRIANGLES:Xt=3;break;case It.LINE_STRIP:Xt=1}for(let Rt of je.get()){let zt=Rt.vaos||(Rt.vaos={});(zt[ye]||(zt[ye]=new Ps)).bind(l,this,Re,At?At.getPaintVertexBuffers():[],Me,Rt.vertexOffset,vt,Lt,Kt),It.drawElements(m,Rt.primitiveLength*Xt,It.UNSIGNED_SHORT,Rt.primitiveOffset*Xt*2)}}}function Os(z,l,m){let T=1/o.aO(m,1,l.transform.tileZoom),P=Math.pow(2,m.tileID.overscaledZ),V=m.tileSize*Math.pow(2,l.transform.tileZoom)/P,W=V*(m.tileID.canonical.x+m.tileID.wrap*P),te=V*m.tileID.canonical.y;return{u_image:0,u_texsize:m.imageAtlasTexture.size,u_scale:[T,z.fromScale,z.toScale],u_fade:z.t,u_pixel_coord_upper:[W>>16,te>>16],u_pixel_coord_lower:[65535&W,65535&te]}}let gh=(z,l,m,T)=>{let P=z.style.light,V=P.properties.get("position"),W=[V.x,V.y,V.z],te=o.c5();P.properties.get("anchor")==="viewport"&&o.c6(te,z.transform.bearingInRadians),o.c7(W,W,te);let se=z.transform.transformLightDirection(W),fe=P.properties.get("color");return{u_lightpos:W,u_lightpos_globe:se,u_lightintensity:P.properties.get("intensity"),u_lightcolor:[fe.r,fe.g,fe.b],u_vertical_gradient:+l,u_opacity:m,u_fill_translate:T}},Ss=(z,l,m,T,P,V,W)=>o.e(gh(z,l,m,T),Os(V,z,W),{u_height_factor:-Math.pow(2,P.overscaledZ)/W.tileSize/8}),Ah=(z,l,m,T)=>o.e(Os(l,z,m),{u_fill_translate:T}),mc=(z,l)=>({u_world:z,u_fill_translate:l}),Qa=(z,l,m,T,P)=>o.e(Ah(z,l,m,P),{u_world:T}),Ru=(z,l,m,T,P)=>{let V=z.transform,W,te,se=0;if(m.paint.get("circle-pitch-alignment")==="map"){let fe=o.aO(l,1,V.zoom);W=!0,te=[fe,fe],se=fe/(o.a5*Math.pow(2,l.tileID.overscaledZ))*2*Math.PI*P}else W=!1,te=V.pixelsToGLUnits;return{u_camera_to_center_distance:V.cameraToCenterDistance,u_scale_with_map:+(m.paint.get("circle-pitch-scale")==="map"),u_pitch_with_map:+W,u_device_pixel_ratio:z.pixelRatio,u_extrude_scale:te,u_globe_extrude_scale:se,u_translate:T}},gc=z=>({u_pixel_extrude_scale:[1/z.width,1/z.height]}),_h=z=>({u_viewport_size:[z.width,z.height]}),Fl=(z,l=1)=>({u_color:z,u_overlay:0,u_overlay_scale:l}),Ac=(z,l,m,T)=>{let P=o.aO(z,1,l)/(o.a5*Math.pow(2,z.tileID.overscaledZ))*2*Math.PI*T;return{u_extrude_scale:o.aO(z,1,l),u_intensity:m,u_globe_extrude_scale:P}},qn=(z,l,m,T)=>{let P=o.N();o.c8(P,0,z.width,z.height,0,0,1);let V=z.context.gl;return{u_matrix:P,u_world:[V.drawingBufferWidth,V.drawingBufferHeight],u_image:m,u_color_ramp:T,u_opacity:l.paint.get("heatmap-opacity")}},dt=(z,l,m)=>{let T=m.paint.get("hillshade-accent-color"),P;switch(m.paint.get("hillshade-method")){case"basic":P=4;break;case"combined":P=1;break;case"igor":P=2;break;case"multidirectional":P=3;break;default:P=0}let V=m.getIlluminationProperties();for(let W=0;W{let m=l.stride,T=o.N();return o.c8(T,0,o.a5,-o.a5,0,0,1),o.O(T,T,[0,-o.a5,0]),{u_matrix:T,u_image:1,u_dimension:[m,m],u_zoom:z.overscaledZ,u_unpack:l.getUnpackVector()}};function $h(z,l){let m=Math.pow(2,l.canonical.z),T=l.canonical.y;return[new o.ab(0,T/m).toLngLat().lat,new o.ab(0,(T+1)/m).toLngLat().lat]}let _f=(z,l,m=0)=>({u_image:0,u_unpack:l.getUnpackVector(),u_dimension:[l.stride,l.stride],u_elevation_stops:1,u_color_stops:4,u_color_ramp_size:m,u_opacity:z.paint.get("color-relief-opacity")}),Xh=(z,l,m,T)=>{let P=z.transform;return{u_translation:Wf(z,l,m),u_ratio:T/o.aO(l,1,P.zoom),u_device_pixel_ratio:z.pixelRatio,u_units_to_pixels:[1/P.pixelsToGLUnits[0],1/P.pixelsToGLUnits[1]]}},Wd=(z,l,m,T,P)=>o.e(Xh(z,l,m,T),{u_image:0,u_image_height:P}),Ad=(z,l,m,T,P)=>{let V=z.transform,W=Bu(l,V);return{u_translation:Wf(z,l,m),u_texsize:l.imageAtlasTexture.size,u_ratio:T/o.aO(l,1,V.zoom),u_device_pixel_ratio:z.pixelRatio,u_image:0,u_scale:[W,P.fromScale,P.toScale],u_fade:P.t,u_units_to_pixels:[1/V.pixelsToGLUnits[0],1/V.pixelsToGLUnits[1]]}},et=(z,l,m,T,P)=>{let V=Bu(l,z.transform);return o.e(Xh(z,l,m,T),{u_tileratio:V,u_crossfade_from:P.fromScale,u_crossfade_to:P.toScale,u_image:0,u_mix:P.t,u_lineatlas_width:z.lineAtlas.width,u_lineatlas_height:z.lineAtlas.height})},yf=(z,l,m,T,P,V)=>{let W=Bu(l,z.transform);return o.e(Xh(z,l,m,T),{u_image:0,u_image_height:V,u_tileratio:W,u_crossfade_from:P.fromScale,u_crossfade_to:P.toScale,u_image_dash:1,u_mix:P.t,u_lineatlas_width:z.lineAtlas.width,u_lineatlas_height:z.lineAtlas.height})};function Bu(z,l){return 1/o.aO(z,1,l.tileZoom)}function Wf(z,l,m){return o.aP(z.transform,l,m.paint.get("line-translate"),m.paint.get("line-translate-anchor"))}let qf=(z,l,m,T,P)=>{return{u_tl_parent:z,u_scale_parent:l,u_buffer_scale:1,u_fade_t:m.mix,u_opacity:m.opacity*T.paint.get("raster-opacity"),u_image0:0,u_image1:1,u_brightness_low:T.paint.get("raster-brightness-min"),u_brightness_high:T.paint.get("raster-brightness-max"),u_saturation_factor:(W=T.paint.get("raster-saturation"),W>0?1-1/(1.001-W):-W),u_contrast_factor:(V=T.paint.get("raster-contrast"),V>0?1/(1-V):1+V),u_spin_weights:Bt(T.paint.get("raster-hue-rotate")),u_coords_top:[P[0].x,P[0].y,P[1].x,P[1].y],u_coords_bottom:[P[3].x,P[3].y,P[2].x,P[2].y]};var V,W};function Bt(z){z*=Math.PI/180;let l=Math.sin(z),m=Math.cos(z);return[(2*m+1)/3,(-Math.sqrt(3)*l-m+1)/3,(Math.sqrt(3)*l-m+1)/3]}let ar=(z,l,m,T,P,V,W,te,se,fe,ye,Re,Me)=>{let je=W.transform;return{u_is_size_zoom_constant:+(z==="constant"||z==="source"),u_is_size_feature_constant:+(z==="constant"||z==="camera"),u_size_t:l?l.uSizeT:0,u_size:l?l.uSize:0,u_camera_to_center_distance:je.cameraToCenterDistance,u_pitch:je.pitch/360*2*Math.PI,u_rotate_symbol:+m,u_aspect_ratio:je.width/je.height,u_fade_change:W.options.fadeDuration?W.symbolFadeChange:1,u_label_plane_matrix:te,u_coord_matrix:se,u_is_text:+ye,u_pitch_with_map:+T,u_is_along_line:P,u_is_variable_anchor:V,u_texsize:Re,u_texture:0,u_translation:fe,u_pitched_scale:Me}},Br=(z,l,m,T,P,V,W,te,se,fe,ye,Re,Me,je)=>{let tt=W.transform;return o.e(ar(z,l,m,T,P,V,W,te,se,fe,ye,Re,je),{u_gamma_scale:T?Math.cos(tt.pitch*Math.PI/180)*tt.cameraToCenterDistance:1,u_device_pixel_ratio:W.pixelRatio,u_is_halo:1})},Ur=(z,l,m,T,P,V,W,te,se,fe,ye,Re,Me)=>o.e(Br(z,l,m,T,P,V,W,te,se,fe,!0,ye,0,Me),{u_texsize_icon:Re,u_texture_icon:1}),ci=(z,l)=>({u_opacity:z,u_color:l}),Li=(z,l,m,T,P)=>o.e(function(V,W,te,se){let fe=te.imageManager.getPattern(V.from.toString()),ye=te.imageManager.getPattern(V.to.toString()),{width:Re,height:Me}=te.imageManager.getPixelSize(),je=Math.pow(2,se.tileID.overscaledZ),tt=se.tileSize*Math.pow(2,te.transform.tileZoom)/je,yt=tt*(se.tileID.canonical.x+se.tileID.wrap*je),At=tt*se.tileID.canonical.y;return{u_image:0,u_pattern_tl_a:fe.tl,u_pattern_br_a:fe.br,u_pattern_tl_b:ye.tl,u_pattern_br_b:ye.br,u_texsize:[Re,Me],u_mix:W.t,u_pattern_size_a:fe.displaySize,u_pattern_size_b:ye.displaySize,u_scale_a:W.fromScale,u_scale_b:W.toScale,u_tile_units_to_pixels:1/o.aO(se,1,te.transform.tileZoom),u_pixel_coord_upper:[yt>>16,At>>16],u_pixel_coord_lower:[65535&yt,65535&At]}}(m,P,l,T),{u_opacity:z}),yi=(z,l)=>{},Pn={fillExtrusion:(z,l)=>({u_lightpos:new o.c3(z,l.u_lightpos),u_lightpos_globe:new o.c3(z,l.u_lightpos_globe),u_lightintensity:new o.br(z,l.u_lightintensity),u_lightcolor:new o.c3(z,l.u_lightcolor),u_vertical_gradient:new o.br(z,l.u_vertical_gradient),u_opacity:new o.br(z,l.u_opacity),u_fill_translate:new o.c4(z,l.u_fill_translate)}),fillExtrusionPattern:(z,l)=>({u_lightpos:new o.c3(z,l.u_lightpos),u_lightpos_globe:new o.c3(z,l.u_lightpos_globe),u_lightintensity:new o.br(z,l.u_lightintensity),u_lightcolor:new o.c3(z,l.u_lightcolor),u_vertical_gradient:new o.br(z,l.u_vertical_gradient),u_height_factor:new o.br(z,l.u_height_factor),u_opacity:new o.br(z,l.u_opacity),u_fill_translate:new o.c4(z,l.u_fill_translate),u_image:new o.b$(z,l.u_image),u_texsize:new o.c4(z,l.u_texsize),u_pixel_coord_upper:new o.c4(z,l.u_pixel_coord_upper),u_pixel_coord_lower:new o.c4(z,l.u_pixel_coord_lower),u_scale:new o.c3(z,l.u_scale),u_fade:new o.br(z,l.u_fade)}),fill:(z,l)=>({u_fill_translate:new o.c4(z,l.u_fill_translate)}),fillPattern:(z,l)=>({u_image:new o.b$(z,l.u_image),u_texsize:new o.c4(z,l.u_texsize),u_pixel_coord_upper:new o.c4(z,l.u_pixel_coord_upper),u_pixel_coord_lower:new o.c4(z,l.u_pixel_coord_lower),u_scale:new o.c3(z,l.u_scale),u_fade:new o.br(z,l.u_fade),u_fill_translate:new o.c4(z,l.u_fill_translate)}),fillOutline:(z,l)=>({u_world:new o.c4(z,l.u_world),u_fill_translate:new o.c4(z,l.u_fill_translate)}),fillOutlinePattern:(z,l)=>({u_world:new o.c4(z,l.u_world),u_image:new o.b$(z,l.u_image),u_texsize:new o.c4(z,l.u_texsize),u_pixel_coord_upper:new o.c4(z,l.u_pixel_coord_upper),u_pixel_coord_lower:new o.c4(z,l.u_pixel_coord_lower),u_scale:new o.c3(z,l.u_scale),u_fade:new o.br(z,l.u_fade),u_fill_translate:new o.c4(z,l.u_fill_translate)}),circle:(z,l)=>({u_camera_to_center_distance:new o.br(z,l.u_camera_to_center_distance),u_scale_with_map:new o.b$(z,l.u_scale_with_map),u_pitch_with_map:new o.b$(z,l.u_pitch_with_map),u_extrude_scale:new o.c4(z,l.u_extrude_scale),u_device_pixel_ratio:new o.br(z,l.u_device_pixel_ratio),u_globe_extrude_scale:new o.br(z,l.u_globe_extrude_scale),u_translate:new o.c4(z,l.u_translate)}),collisionBox:(z,l)=>({u_pixel_extrude_scale:new o.c4(z,l.u_pixel_extrude_scale)}),collisionCircle:(z,l)=>({u_viewport_size:new o.c4(z,l.u_viewport_size)}),debug:(z,l)=>({u_color:new o.c0(z,l.u_color),u_overlay:new o.b$(z,l.u_overlay),u_overlay_scale:new o.br(z,l.u_overlay_scale)}),depth:yi,clippingMask:yi,heatmap:(z,l)=>({u_extrude_scale:new o.br(z,l.u_extrude_scale),u_intensity:new o.br(z,l.u_intensity),u_globe_extrude_scale:new o.br(z,l.u_globe_extrude_scale)}),heatmapTexture:(z,l)=>({u_matrix:new o.c1(z,l.u_matrix),u_world:new o.c4(z,l.u_world),u_image:new o.b$(z,l.u_image),u_color_ramp:new o.b$(z,l.u_color_ramp),u_opacity:new o.br(z,l.u_opacity)}),hillshade:(z,l)=>({u_image:new o.b$(z,l.u_image),u_latrange:new o.c4(z,l.u_latrange),u_exaggeration:new o.br(z,l.u_exaggeration),u_altitudes:new o.ca(z,l.u_altitudes),u_azimuths:new o.ca(z,l.u_azimuths),u_accent:new o.c0(z,l.u_accent),u_method:new o.b$(z,l.u_method),u_shadows:new o.c9(z,l.u_shadows),u_highlights:new o.c9(z,l.u_highlights)}),hillshadePrepare:(z,l)=>({u_matrix:new o.c1(z,l.u_matrix),u_image:new o.b$(z,l.u_image),u_dimension:new o.c4(z,l.u_dimension),u_zoom:new o.br(z,l.u_zoom),u_unpack:new o.c2(z,l.u_unpack)}),colorRelief:(z,l)=>({u_image:new o.b$(z,l.u_image),u_unpack:new o.c2(z,l.u_unpack),u_dimension:new o.c4(z,l.u_dimension),u_elevation_stops:new o.b$(z,l.u_elevation_stops),u_color_stops:new o.b$(z,l.u_color_stops),u_color_ramp_size:new o.b$(z,l.u_color_ramp_size),u_opacity:new o.br(z,l.u_opacity)}),line:(z,l)=>({u_translation:new o.c4(z,l.u_translation),u_ratio:new o.br(z,l.u_ratio),u_device_pixel_ratio:new o.br(z,l.u_device_pixel_ratio),u_units_to_pixels:new o.c4(z,l.u_units_to_pixels)}),lineGradient:(z,l)=>({u_translation:new o.c4(z,l.u_translation),u_ratio:new o.br(z,l.u_ratio),u_device_pixel_ratio:new o.br(z,l.u_device_pixel_ratio),u_units_to_pixels:new o.c4(z,l.u_units_to_pixels),u_image:new o.b$(z,l.u_image),u_image_height:new o.br(z,l.u_image_height)}),linePattern:(z,l)=>({u_translation:new o.c4(z,l.u_translation),u_texsize:new o.c4(z,l.u_texsize),u_ratio:new o.br(z,l.u_ratio),u_device_pixel_ratio:new o.br(z,l.u_device_pixel_ratio),u_image:new o.b$(z,l.u_image),u_units_to_pixels:new o.c4(z,l.u_units_to_pixels),u_scale:new o.c3(z,l.u_scale),u_fade:new o.br(z,l.u_fade)}),lineSDF:(z,l)=>({u_translation:new o.c4(z,l.u_translation),u_ratio:new o.br(z,l.u_ratio),u_device_pixel_ratio:new o.br(z,l.u_device_pixel_ratio),u_units_to_pixels:new o.c4(z,l.u_units_to_pixels),u_image:new o.b$(z,l.u_image),u_mix:new o.br(z,l.u_mix),u_tileratio:new o.br(z,l.u_tileratio),u_crossfade_from:new o.br(z,l.u_crossfade_from),u_crossfade_to:new o.br(z,l.u_crossfade_to),u_lineatlas_width:new o.br(z,l.u_lineatlas_width),u_lineatlas_height:new o.br(z,l.u_lineatlas_height)}),lineGradientSDF:(z,l)=>({u_translation:new o.c4(z,l.u_translation),u_ratio:new o.br(z,l.u_ratio),u_device_pixel_ratio:new o.br(z,l.u_device_pixel_ratio),u_units_to_pixels:new o.c4(z,l.u_units_to_pixels),u_image:new o.b$(z,l.u_image),u_image_height:new o.br(z,l.u_image_height),u_tileratio:new o.br(z,l.u_tileratio),u_crossfade_from:new o.br(z,l.u_crossfade_from),u_crossfade_to:new o.br(z,l.u_crossfade_to),u_image_dash:new o.b$(z,l.u_image_dash),u_mix:new o.br(z,l.u_mix),u_lineatlas_width:new o.br(z,l.u_lineatlas_width),u_lineatlas_height:new o.br(z,l.u_lineatlas_height)}),raster:(z,l)=>({u_tl_parent:new o.c4(z,l.u_tl_parent),u_scale_parent:new o.br(z,l.u_scale_parent),u_buffer_scale:new o.br(z,l.u_buffer_scale),u_fade_t:new o.br(z,l.u_fade_t),u_opacity:new o.br(z,l.u_opacity),u_image0:new o.b$(z,l.u_image0),u_image1:new o.b$(z,l.u_image1),u_brightness_low:new o.br(z,l.u_brightness_low),u_brightness_high:new o.br(z,l.u_brightness_high),u_saturation_factor:new o.br(z,l.u_saturation_factor),u_contrast_factor:new o.br(z,l.u_contrast_factor),u_spin_weights:new o.c3(z,l.u_spin_weights),u_coords_top:new o.c2(z,l.u_coords_top),u_coords_bottom:new o.c2(z,l.u_coords_bottom)}),symbolIcon:(z,l)=>({u_is_size_zoom_constant:new o.b$(z,l.u_is_size_zoom_constant),u_is_size_feature_constant:new o.b$(z,l.u_is_size_feature_constant),u_size_t:new o.br(z,l.u_size_t),u_size:new o.br(z,l.u_size),u_camera_to_center_distance:new o.br(z,l.u_camera_to_center_distance),u_pitch:new o.br(z,l.u_pitch),u_rotate_symbol:new o.b$(z,l.u_rotate_symbol),u_aspect_ratio:new o.br(z,l.u_aspect_ratio),u_fade_change:new o.br(z,l.u_fade_change),u_label_plane_matrix:new o.c1(z,l.u_label_plane_matrix),u_coord_matrix:new o.c1(z,l.u_coord_matrix),u_is_text:new o.b$(z,l.u_is_text),u_pitch_with_map:new o.b$(z,l.u_pitch_with_map),u_is_along_line:new o.b$(z,l.u_is_along_line),u_is_variable_anchor:new o.b$(z,l.u_is_variable_anchor),u_texsize:new o.c4(z,l.u_texsize),u_texture:new o.b$(z,l.u_texture),u_translation:new o.c4(z,l.u_translation),u_pitched_scale:new o.br(z,l.u_pitched_scale)}),symbolSDF:(z,l)=>({u_is_size_zoom_constant:new o.b$(z,l.u_is_size_zoom_constant),u_is_size_feature_constant:new o.b$(z,l.u_is_size_feature_constant),u_size_t:new o.br(z,l.u_size_t),u_size:new o.br(z,l.u_size),u_camera_to_center_distance:new o.br(z,l.u_camera_to_center_distance),u_pitch:new o.br(z,l.u_pitch),u_rotate_symbol:new o.b$(z,l.u_rotate_symbol),u_aspect_ratio:new o.br(z,l.u_aspect_ratio),u_fade_change:new o.br(z,l.u_fade_change),u_label_plane_matrix:new o.c1(z,l.u_label_plane_matrix),u_coord_matrix:new o.c1(z,l.u_coord_matrix),u_is_text:new o.b$(z,l.u_is_text),u_pitch_with_map:new o.b$(z,l.u_pitch_with_map),u_is_along_line:new o.b$(z,l.u_is_along_line),u_is_variable_anchor:new o.b$(z,l.u_is_variable_anchor),u_texsize:new o.c4(z,l.u_texsize),u_texture:new o.b$(z,l.u_texture),u_gamma_scale:new o.br(z,l.u_gamma_scale),u_device_pixel_ratio:new o.br(z,l.u_device_pixel_ratio),u_is_halo:new o.b$(z,l.u_is_halo),u_translation:new o.c4(z,l.u_translation),u_pitched_scale:new o.br(z,l.u_pitched_scale)}),symbolTextAndIcon:(z,l)=>({u_is_size_zoom_constant:new o.b$(z,l.u_is_size_zoom_constant),u_is_size_feature_constant:new o.b$(z,l.u_is_size_feature_constant),u_size_t:new o.br(z,l.u_size_t),u_size:new o.br(z,l.u_size),u_camera_to_center_distance:new o.br(z,l.u_camera_to_center_distance),u_pitch:new o.br(z,l.u_pitch),u_rotate_symbol:new o.b$(z,l.u_rotate_symbol),u_aspect_ratio:new o.br(z,l.u_aspect_ratio),u_fade_change:new o.br(z,l.u_fade_change),u_label_plane_matrix:new o.c1(z,l.u_label_plane_matrix),u_coord_matrix:new o.c1(z,l.u_coord_matrix),u_is_text:new o.b$(z,l.u_is_text),u_pitch_with_map:new o.b$(z,l.u_pitch_with_map),u_is_along_line:new o.b$(z,l.u_is_along_line),u_is_variable_anchor:new o.b$(z,l.u_is_variable_anchor),u_texsize:new o.c4(z,l.u_texsize),u_texsize_icon:new o.c4(z,l.u_texsize_icon),u_texture:new o.b$(z,l.u_texture),u_texture_icon:new o.b$(z,l.u_texture_icon),u_gamma_scale:new o.br(z,l.u_gamma_scale),u_device_pixel_ratio:new o.br(z,l.u_device_pixel_ratio),u_is_halo:new o.b$(z,l.u_is_halo),u_translation:new o.c4(z,l.u_translation),u_pitched_scale:new o.br(z,l.u_pitched_scale)}),background:(z,l)=>({u_opacity:new o.br(z,l.u_opacity),u_color:new o.c0(z,l.u_color)}),backgroundPattern:(z,l)=>({u_opacity:new o.br(z,l.u_opacity),u_image:new o.b$(z,l.u_image),u_pattern_tl_a:new o.c4(z,l.u_pattern_tl_a),u_pattern_br_a:new o.c4(z,l.u_pattern_br_a),u_pattern_tl_b:new o.c4(z,l.u_pattern_tl_b),u_pattern_br_b:new o.c4(z,l.u_pattern_br_b),u_texsize:new o.c4(z,l.u_texsize),u_mix:new o.br(z,l.u_mix),u_pattern_size_a:new o.c4(z,l.u_pattern_size_a),u_pattern_size_b:new o.c4(z,l.u_pattern_size_b),u_scale_a:new o.br(z,l.u_scale_a),u_scale_b:new o.br(z,l.u_scale_b),u_pixel_coord_upper:new o.c4(z,l.u_pixel_coord_upper),u_pixel_coord_lower:new o.c4(z,l.u_pixel_coord_lower),u_tile_units_to_pixels:new o.br(z,l.u_tile_units_to_pixels)}),terrain:(z,l)=>({u_texture:new o.b$(z,l.u_texture),u_ele_delta:new o.br(z,l.u_ele_delta),u_fog_matrix:new o.c1(z,l.u_fog_matrix),u_fog_color:new o.c0(z,l.u_fog_color),u_fog_ground_blend:new o.br(z,l.u_fog_ground_blend),u_fog_ground_blend_opacity:new o.br(z,l.u_fog_ground_blend_opacity),u_horizon_color:new o.c0(z,l.u_horizon_color),u_horizon_fog_blend:new o.br(z,l.u_horizon_fog_blend),u_is_globe_mode:new o.br(z,l.u_is_globe_mode)}),terrainDepth:(z,l)=>({u_ele_delta:new o.br(z,l.u_ele_delta)}),terrainCoords:(z,l)=>({u_texture:new o.b$(z,l.u_texture),u_terrain_coords_id:new o.br(z,l.u_terrain_coords_id),u_ele_delta:new o.br(z,l.u_ele_delta)}),projectionErrorMeasurement:(z,l)=>({u_input:new o.br(z,l.u_input),u_output_expected:new o.br(z,l.u_output_expected)}),atmosphere:(z,l)=>({u_sun_pos:new o.c3(z,l.u_sun_pos),u_atmosphere_blend:new o.br(z,l.u_atmosphere_blend),u_globe_position:new o.c3(z,l.u_globe_position),u_globe_radius:new o.br(z,l.u_globe_radius),u_inv_proj_matrix:new o.c1(z,l.u_inv_proj_matrix)}),sky:(z,l)=>({u_sky_color:new o.c0(z,l.u_sky_color),u_horizon_color:new o.c0(z,l.u_horizon_color),u_horizon:new o.c4(z,l.u_horizon),u_horizon_normal:new o.c4(z,l.u_horizon_normal),u_sky_horizon_blend:new o.br(z,l.u_sky_horizon_blend),u_sky_blend:new o.br(z,l.u_sky_blend)})};class sn{constructor(l,m,T){this.context=l;let P=l.gl;this.buffer=P.createBuffer(),this.dynamicDraw=Boolean(T),this.context.unbindVAO(),l.bindElementBuffer.set(this.buffer),P.bufferData(P.ELEMENT_ARRAY_BUFFER,m.arrayBuffer,this.dynamicDraw?P.DYNAMIC_DRAW:P.STATIC_DRAW),this.dynamicDraw||delete m.arrayBuffer}bind(){this.context.bindElementBuffer.set(this.buffer)}updateData(l){let m=this.context.gl;if(!this.dynamicDraw)throw new Error("Attempted to update data while not in dynamic mode.");this.context.unbindVAO(),this.bind(),m.bufferSubData(m.ELEMENT_ARRAY_BUFFER,0,l.arrayBuffer)}destroy(){this.buffer&&(this.context.gl.deleteBuffer(this.buffer),delete this.buffer)}}let To={Int8:"BYTE",Uint8:"UNSIGNED_BYTE",Int16:"SHORT",Uint16:"UNSIGNED_SHORT",Int32:"INT",Uint32:"UNSIGNED_INT",Float32:"FLOAT"};class Hi{constructor(l,m,T,P){this.length=m.length,this.attributes=T,this.itemSize=m.bytesPerElement,this.dynamicDraw=P,this.context=l;let V=l.gl;this.buffer=V.createBuffer(),l.bindVertexBuffer.set(this.buffer),V.bufferData(V.ARRAY_BUFFER,m.arrayBuffer,this.dynamicDraw?V.DYNAMIC_DRAW:V.STATIC_DRAW),this.dynamicDraw||delete m.arrayBuffer}bind(){this.context.bindVertexBuffer.set(this.buffer)}updateData(l){if(l.length!==this.length)throw new Error(`Length of new data is ${l.length}, which doesn't match current length of ${this.length}`);let m=this.context.gl;this.bind(),m.bufferSubData(m.ARRAY_BUFFER,0,l.arrayBuffer)}enableAttributes(l,m){for(let T=0;T0&&(fe.push({circleArray:Xt,circleOffset:Re,coord:Lt}),ye+=Xt.length/4,Re=ye),It&&se.draw(V,te.LINES,Ao.disabled,us.disabled,z.colorModeForRenderPass(),ms.disabled,gc(z.transform),z.style.map.terrain&&z.style.map.terrain.getTerrainData(Lt),W.getProjectionData({overscaledTileID:Lt,applyGlobeMatrix:!0,applyTerrainMatrix:!0}),m.id,It.layoutVertexBuffer,It.indexBuffer,It.segments,null,z.transform.zoom,null,null,It.collisionVertexBuffer)}if(!P||!fe.length)return;let Me=z.useProgram("collisionCircle"),je=new o.cb;je.resize(4*ye),je._trim();let tt=0;for(let vt of fe)for(let Lt=0;Lt=0&&(yt[vt.associatedIconIndex]={shiftedAnchor:hi,angle:hn})}else Ya(vt.numGlyphs,je)}if(se){tt.clear();let At=z.icon.placedSymbolArray;for(let vt=0;vtz.style.map.terrain.getElevation(Cr,Tt,er):null,wt=m.layout.get("text-rotation-alignment")==="map";Ls(Pr,z,P,v,x,vt,fe,wt,Cr.toUnwrapped(),yt.width,yt.height,B,bt)}let Q=P&&zt||X,ue=Lt||Q?xf:vt?v:z.transform.clipSpaceToPixelsMatrix,Ae=hi&&m.paint.get(P?"text-halo-width":"icon-halo-width").constantOr(1)!==0,Te;Te=hi?Pr.iconsInText?Ur(hn.kind,di,Kt,vt,Lt,Q,z,ue,E,B,Ja,Wa,br):Br(hn.kind,di,Kt,vt,Lt,Q,z,ue,E,B,P,Ja,0,br):ar(hn.kind,di,Kt,vt,Lt,Q,z,ue,E,B,P,Ja,br);let at={program:$r,buffers:Ai,uniformValues:Te,projectionData:N,atlasTexture:ya,atlasTextureIcon:Hl,atlasInterpolation:jl,atlasInterpolationIcon:qs,isSDF:hi,hasHalo:Ae};if(It&&Pr.canOverlap){Xt=!0;let bt=Ai.segments.get();for(let wt of bt)jt.push({segments:new o.aY([wt]),sortKey:wt.sortKey,state:at,terrainData:oa})}else jt.push({segments:Ai.segments,sortKey:0,state:at,terrainData:oa})}Xt&&jt.sort((Cr,Rr)=>Cr.sortKey-Rr.sortKey);for(let Cr of jt){let Rr=Cr.state;if(je.activeTexture.set(tt.TEXTURE0),Rr.atlasTexture.bind(Rr.atlasInterpolation,tt.CLAMP_TO_EDGE),Rr.atlasTextureIcon&&(je.activeTexture.set(tt.TEXTURE1),Rr.atlasTextureIcon&&Rr.atlasTextureIcon.bind(Rr.atlasInterpolationIcon,tt.CLAMP_TO_EDGE)),Rr.isSDF){let Pr=Rr.uniformValues;Rr.hasHalo&&(Pr.u_is_halo=1,nn(Rr.buffers,Cr.segments,m,z,Rr.program,Rt,ye,Re,Pr,Rr.projectionData,Cr.terrainData)),Pr.u_is_halo=0}nn(Rr.buffers,Cr.segments,m,z,Rr.program,Rt,ye,Re,Rr.uniformValues,Rr.projectionData,Cr.terrainData)}}function nn(z,l,m,T,P,V,W,te,se,fe,ye){let Re=T.context;P.draw(Re,Re.gl.TRIANGLES,V,W,te,ms.backCCW,se,ye,fe,m.id,z.layoutVertexBuffer,z.indexBuffer,l,m.paint,T.transform.zoom,z.programConfigurations.get(m.id),z.dynamicLayoutVertexBuffer,z.opacityVertexBuffer)}function Xd(z,l,m,T,P){let V=z.context,W=V.gl,te=us.disabled,se=new ia([W.ONE,W.ONE],o.bq.transparent,[!0,!0,!0,!0]),fe=l.getBucket(m);if(!fe)return;let ye=T.key,Re=m.heatmapFbos.get(ye);Re||(Re=Au(V,l.tileSize,l.tileSize),m.heatmapFbos.set(ye,Re)),V.bindFramebuffer.set(Re.framebuffer),V.viewport.set([0,0,l.tileSize,l.tileSize]),V.clear({color:o.bq.transparent});let Me=fe.programConfigurations.get(m.id),je=z.useProgram("heatmap",Me,!P),tt=z.transform.getProjectionData({overscaledTileID:l.tileID,applyGlobeMatrix:!0,applyTerrainMatrix:!0}),yt=z.style.map.terrain.getTerrainData(T);je.draw(V,W.TRIANGLES,Ao.disabled,te,se,ms.disabled,Ac(l,z.transform.zoom,m.paint.get("heatmap-intensity"),1),yt,tt,m.id,fe.layoutVertexBuffer,fe.indexBuffer,fe.segments,m.paint,z.transform.zoom,Me)}function Vc(z,l,m,T,P){let V=z.context,W=V.gl,te=z.transform;V.setColorMode(z.colorModeForRenderPass());let se=Cl(V,l),fe=m.key,ye=l.heatmapFbos.get(fe);if(!ye)return;V.activeTexture.set(W.TEXTURE0),W.bindTexture(W.TEXTURE_2D,ye.colorAttachment.get()),V.activeTexture.set(W.TEXTURE1),se.bind(W.LINEAR,W.CLAMP_TO_EDGE);let Re=te.getProjectionData({overscaledTileID:m,applyTerrainMatrix:P,applyGlobeMatrix:!T});z.useProgram("heatmapTexture").draw(V,W.TRIANGLES,Ao.disabled,us.disabled,z.colorModeForRenderPass(),ms.disabled,qn(z,l,0,1),null,Re,l.id,z.rasterBoundsBuffer,z.quadTriangleIndexBuffer,z.rasterBoundsSegments,l.paint,te.zoom),ye.destroy(),l.heatmapFbos.delete(fe)}function Au(z,l,m){var T,P;let V=z.gl,W=V.createTexture();V.bindTexture(V.TEXTURE_2D,W),V.texParameteri(V.TEXTURE_2D,V.TEXTURE_WRAP_S,V.CLAMP_TO_EDGE),V.texParameteri(V.TEXTURE_2D,V.TEXTURE_WRAP_T,V.CLAMP_TO_EDGE),V.texParameteri(V.TEXTURE_2D,V.TEXTURE_MIN_FILTER,V.LINEAR),V.texParameteri(V.TEXTURE_2D,V.TEXTURE_MAG_FILTER,V.LINEAR);let te=(T=z.HALF_FLOAT)!==null&&T!==void 0?T:V.UNSIGNED_BYTE,se=(P=z.RGBA16F)!==null&&P!==void 0?P:V.RGBA;V.texImage2D(V.TEXTURE_2D,0,se,l,m,0,V.RGBA,te,null);let fe=z.createFramebuffer(l,m,!1,!1);return fe.colorAttachment.set(W),fe}function Cl(z,l){return l.colorRampTexture||(l.colorRampTexture=new o.T(z,l.colorRamp,z.gl.RGBA)),l.colorRampTexture}function Zh(z,l,m,T,P,V,W,te){let se=256;if(P.stepInterpolant){let fe=l.getSource().maxzoom,ye=W.canonical.z===fe?Math.ceil(1<20&&Me.texParameterf(Me.TEXTURE_2D,Re.extTextureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT,Re.extTextureFilterAnisotropicMax);let _i=z.style.map.terrain&&z.style.map.terrain.getTerrainData(Rt),hi=tt.getProjectionData({overscaledTileID:Rt,aligned:vt,applyGlobeMatrix:!fe,applyTerrainMatrix:!0}),hn=qf(Pr,Rr,Ai.fadeMix,m,te),fo=yt.getMeshFromTileID(Re,Rt.canonical,V,W,"raster");je.draw(Re,Me.TRIANGLES,zt,P?P[Rt.overscaledZ]:us.disabled,At,se?ms.frontCCW:ms.backCCW,hn,_i,hi,m.id,fo.vertexBuffer,fo.indexBuffer,fo.segments)}}function Zf(z,l,m,T){let P={parentTile:null,parentScaleBy:1,parentTopLeft:[0,0],fadeValues:{tileOpacity:1,parentTileOpacity:1,fadeMix:{opacity:1,mix:0}}};if(m===0||T)return P;if(z.fadingParentID){let V=l.getLoadedTile(z.fadingParentID);if(!V)return P;let W=Math.pow(2,V.tileID.overscaledZ-z.tileID.overscaledZ),te=[z.tileID.canonical.x*W%1,z.tileID.canonical.y*W%1],se=function(fe,ye,Re){let Me=k(),je=(Me-ye.timeAdded)/Re,tt=fe.fadingDirection===xr.Incoming,yt=o.ao((Me-fe.timeAdded)/Re,0,1),At=o.ao(1-je,0,1),vt=tt?yt:At;return{tileOpacity:vt,parentTileOpacity:tt?At:yt,fadeMix:{opacity:1,mix:1-vt}}}(z,V,m);return{parentTile:V,parentScaleBy:W,parentTopLeft:te,fadeValues:se}}if(z.selfFading){let V=function(W,te){let se=(k()-W.timeAdded)/te,fe=o.ao(se,0,1);return{tileOpacity:fe,fadeMix:{opacity:fe,mix:0}}}(z,m);return{parentTile:null,parentScaleBy:1,parentTopLeft:[0,0],fadeValues:V}}return P}let Zd=new o.bq(1,0,0,1),xd=new o.bq(0,1,0,1),mm=new o.bq(0,0,1,1),xh=new o.bq(1,0,1,1),Qu=new o.bq(0,1,1,1);function Yd(z,l,m,T){bh(z,0,l+m/2,z.transform.width,m,T)}function Kh(z,l,m,T){bh(z,l-m/2,0,m,z.transform.height,T)}function bh(z,l,m,T,P,V){let W=z.context,te=W.gl;te.enable(te.SCISSOR_TEST),te.scissor(l*z.pixelRatio,m*z.pixelRatio,T*z.pixelRatio,P*z.pixelRatio),W.clear({color:V}),te.disable(te.SCISSOR_TEST)}function Rp(z,l,m){let T=z.context,P=T.gl,V=z.useProgram("debug"),W=Ao.disabled,te=us.disabled,se=z.colorModeForRenderPass(),fe="$debug",ye=z.style.map.terrain&&z.style.map.terrain.getTerrainData(m);T.activeTexture.set(P.TEXTURE0);let Re=l.getTileByID(m.key).latestRawTileData,Me=Math.floor((Re&&Re.byteLength||0)/1024),je=l.getTile(m).tileSize,tt=512/Math.min(je,512)*(m.overscaledZ/z.transform.zoom)*.5,yt=m.canonical.toString();m.overscaledZ!==m.canonical.z&&(yt+=` => ${m.overscaledZ}`),function(vt,Lt){vt.initDebugOverlayCanvas();let Kt=vt.debugOverlayCanvas,It=vt.context.gl,Xt=vt.debugOverlayCanvas.getContext("2d");Xt.clearRect(0,0,Kt.width,Kt.height),Xt.shadowColor="white",Xt.shadowBlur=2,Xt.lineWidth=1.5,Xt.strokeStyle="white",Xt.textBaseline="top",Xt.font="bold 36px Open Sans, sans-serif",Xt.fillText(Lt,5,5),Xt.strokeText(Lt,5,5),vt.debugOverlayTexture.update(Kt),vt.debugOverlayTexture.bind(It.LINEAR,It.CLAMP_TO_EDGE)}(z,`${yt} ${Me}kB`);let At=z.transform.getProjectionData({overscaledTileID:m,applyGlobeMatrix:!0,applyTerrainMatrix:!0});V.draw(T,P.TRIANGLES,W,te,ia.alphaBlended,ms.disabled,Fl(o.bq.transparent,tt),null,At,fe,z.debugBuffer,z.quadTriangleIndexBuffer,z.debugSegments),V.draw(T,P.LINE_STRIP,W,te,se,ms.disabled,Fl(o.bq.red),ye,At,fe,z.debugBuffer,z.tileBorderIndexBuffer,z.debugSegments)}function bf(z,l,m,T){let{isRenderingGlobe:P}=T,V=z.context,W=V.gl,te=z.transform,se=z.colorModeForRenderPass(),fe=z.getDepthModeFor3D(),ye=z.useProgram("terrain");V.bindFramebuffer.set(null),V.viewport.set([0,0,z.width,z.height]);for(let Re of m){let Me=l.getTerrainMesh(Re.tileID),je=z.renderToTexture.getTexture(Re),tt=l.getTerrainData(Re.tileID);V.activeTexture.set(W.TEXTURE0),W.bindTexture(W.TEXTURE_2D,je.texture);let yt=l.getMeshFrameDelta(te.zoom),At=te.calculateFogMatrix(Re.tileID.toUnwrapped()),vt=Rs(yt,At,z.style.sky,te.pitch,P),Lt=te.getProjectionData({overscaledTileID:Re.tileID,applyTerrainMatrix:!1,applyGlobeMatrix:!0});ye.draw(V,W.TRIANGLES,fe,us.disabled,se,ms.backCCW,vt,tt,Lt,"terrain",Me.vertexBuffer,Me.indexBuffer,Me.segments)}}function Du(z,l){if(!l.mesh){let m=new o.aX;m.emplaceBack(-1,-1),m.emplaceBack(1,-1),m.emplaceBack(1,1),m.emplaceBack(-1,1);let T=new o.aZ;T.emplaceBack(0,1,2),T.emplaceBack(0,2,3),l.mesh=new Gs(z.createVertexBuffer(m,ec.members),z.createIndexBuffer(T),o.aY.simpleSegment(0,0,m.length,T.length))}return l.mesh}class Bp{constructor(l,m){this.context=new Lu(l),this.transform=m,this._tileTextures={},this.terrainFacilitator={dirty:!0,matrix:o.as(new Float64Array(16)),renderTime:0},this.setup(),this.numSublayers=si.maxOverzooming+si.maxUnderzooming+1,this.depthEpsilon=1/Math.pow(2,16),this.crossTileSymbolIndex=new Ql}resize(l,m,T){if(this.width=Math.floor(l*T),this.height=Math.floor(m*T),this.pixelRatio=T,this.context.viewport.set([0,0,this.width,this.height]),this.style)for(let P of this.style._order)this.style._layers[P].resize()}setup(){let l=this.context,m=new o.aX;m.emplaceBack(0,0),m.emplaceBack(o.a5,0),m.emplaceBack(0,o.a5),m.emplaceBack(o.a5,o.a5),this.tileExtentBuffer=l.createVertexBuffer(m,ec.members),this.tileExtentSegments=o.aY.simpleSegment(0,0,4,2);let T=new o.aX;T.emplaceBack(0,0),T.emplaceBack(o.a5,0),T.emplaceBack(0,o.a5),T.emplaceBack(o.a5,o.a5),this.debugBuffer=l.createVertexBuffer(T,ec.members),this.debugSegments=o.aY.simpleSegment(0,0,4,5);let P=new o.ci;P.emplaceBack(0,0,0,0),P.emplaceBack(o.a5,0,o.a5,0),P.emplaceBack(0,o.a5,0,o.a5),P.emplaceBack(o.a5,o.a5,o.a5,o.a5),this.rasterBoundsBuffer=l.createVertexBuffer(P,ao.members),this.rasterBoundsSegments=o.aY.simpleSegment(0,0,4,2);let V=new o.aX;V.emplaceBack(0,0),V.emplaceBack(o.a5,0),V.emplaceBack(0,o.a5),V.emplaceBack(o.a5,o.a5),this.rasterBoundsBufferPosOnly=l.createVertexBuffer(V,ec.members),this.rasterBoundsSegmentsPosOnly=o.aY.simpleSegment(0,0,4,5);let W=new o.aX;W.emplaceBack(0,0),W.emplaceBack(1,0),W.emplaceBack(0,1),W.emplaceBack(1,1),this.viewportBuffer=l.createVertexBuffer(W,ec.members),this.viewportSegments=o.aY.simpleSegment(0,0,4,2);let te=new o.cj;te.emplaceBack(0),te.emplaceBack(1),te.emplaceBack(3),te.emplaceBack(2),te.emplaceBack(0),this.tileBorderIndexBuffer=l.createIndexBuffer(te);let se=new o.aZ;se.emplaceBack(1,0,2),se.emplaceBack(1,2,3),this.quadTriangleIndexBuffer=l.createIndexBuffer(se);let fe=this.context.gl;this.stencilClearMode=new us({func:fe.ALWAYS,mask:0},0,255,fe.ZERO,fe.ZERO,fe.ZERO),this.tileExtentMesh=new Gs(this.tileExtentBuffer,this.quadTriangleIndexBuffer,this.tileExtentSegments)}clearStencil(){let l=this.context,m=l.gl;this.nextStencilID=1,this.currentStencilSource=void 0;let T=o.N();o.c8(T,0,this.width,this.height,0,0,1),o.Q(T,T,[m.drawingBufferWidth,m.drawingBufferHeight,0]);let P={mainMatrix:T,tileMercatorCoords:[0,0,1,1],clippingPlane:[0,0,0,0],projectionTransition:0,fallbackMatrix:T};this.useProgram("clippingMask",null,!0).draw(l,m.TRIANGLES,Ao.disabled,this.stencilClearMode,ia.disabled,ms.disabled,null,null,P,"$clipping",this.viewportBuffer,this.quadTriangleIndexBuffer,this.viewportSegments)}_renderTileClippingMasks(l,m,T){if(this.currentStencilSource===l.source||!l.isTileClipped()||!m||!m.length)return;this.currentStencilSource=l.source,this.nextStencilID+m.length>256&&this.clearStencil();let P=this.context;P.setColorMode(ia.disabled),P.setDepthMode(Ao.disabled);let V={};for(let W of m)V[W.key]=this.nextStencilID++;this._renderTileMasks(V,m,T,!0),this._renderTileMasks(V,m,T,!1),this._tileClippingMaskIDs=V}_renderTileMasks(l,m,T,P){let V=this.context,W=V.gl,te=this.style.projection,se=this.transform,fe=this.useProgram("clippingMask");for(let ye of m){let Re=l[ye.key],Me=this.style.map.terrain&&this.style.map.terrain.getTerrainData(ye),je=te.getMeshFromTileID(this.context,ye.canonical,P,!0,"stencil"),tt=se.getProjectionData({overscaledTileID:ye,applyGlobeMatrix:!T,applyTerrainMatrix:!0});fe.draw(V,W.TRIANGLES,Ao.disabled,new us({func:W.ALWAYS,mask:0},Re,255,W.KEEP,W.KEEP,W.REPLACE),ia.disabled,T?ms.disabled:ms.backCCW,null,Me,tt,"$clipping",je.vertexBuffer,je.indexBuffer,je.segments)}}_renderTilesDepthBuffer(){let l=this.context,m=l.gl,T=this.style.projection,P=this.transform,V=this.useProgram("depth"),W=this.getDepthModeFor3D(),te=Qe(P,{tileSize:P.tileSize});for(let se of te){let fe=this.style.map.terrain&&this.style.map.terrain.getTerrainData(se),ye=T.getMeshFromTileID(this.context,se.canonical,!0,!0,"raster"),Re=P.getProjectionData({overscaledTileID:se,applyGlobeMatrix:!0,applyTerrainMatrix:!0});V.draw(l,m.TRIANGLES,W,us.disabled,ia.disabled,ms.backCCW,null,fe,Re,"$clipping",ye.vertexBuffer,ye.indexBuffer,ye.segments)}}stencilModeFor3D(){this.currentStencilSource=void 0,this.nextStencilID+1>256&&this.clearStencil();let l=this.nextStencilID++,m=this.context.gl;return new us({func:m.NOTEQUAL,mask:255},l,255,m.KEEP,m.KEEP,m.REPLACE)}stencilModeForClipping(l){let m=this.context.gl;return new us({func:m.EQUAL,mask:255},this._tileClippingMaskIDs[l.key],0,m.KEEP,m.KEEP,m.REPLACE)}getStencilConfigForOverlapAndUpdateStencilID(l){let m=this.context.gl,T=l.sort((W,te)=>te.overscaledZ-W.overscaledZ),P=T[T.length-1].overscaledZ,V=T[0].overscaledZ-P+1;if(V>1){this.currentStencilSource=void 0,this.nextStencilID+V>256&&this.clearStencil();let W={};for(let te=0;tete.overscaledZ-W.overscaledZ),P=T[T.length-1].overscaledZ,V=T[0].overscaledZ-P+1;if(this.clearStencil(),V>1){let W={},te={};for(let se=0;se0};for(let Me in W){let je=W[Me];je.used&&je.prepare(this.context),te[Me]=je.getVisibleCoordinates(!1),se[Me]=te[Me].slice().reverse(),fe[Me]=je.getVisibleCoordinates(!0).reverse()}this.opaquePassCutoff=1/0;for(let Me=0;Methis.useProgram(Me)}),this.context.viewport.set([0,0,this.width,this.height]),this.context.bindFramebuffer.set(null),this.context.clear({color:m.showOverdrawInspector?o.bq.black:o.bq.transparent,depth:1}),this.clearStencil(),this.style.sky&&function(Me,je){let tt=Me.context,yt=tt.gl,At=((Rt,zt,jt)=>{let br=Math.cos(zt.rollInRadians),Cr=Math.sin(zt.rollInRadians),Rr=bs(zt),Pr=zt.getProjectionData({overscaledTileID:null,applyGlobeMatrix:!0,applyTerrainMatrix:!0}).projectionTransition;return{u_sky_color:Rt.properties.get("sky-color"),u_horizon_color:Rt.properties.get("horizon-color"),u_horizon:[(zt.width/2-Rr*Cr)*jt,(zt.height/2+Rr*br)*jt],u_horizon_normal:[-Cr,br],u_sky_horizon_blend:Rt.properties.get("sky-horizon-blend")*zt.height/2*jt,u_sky_blend:Pr}})(je,Me.style.map.transform,Me.pixelRatio),vt=new Ao(yt.LEQUAL,Ao.ReadWrite,[0,1]),Lt=us.disabled,Kt=Me.colorModeForRenderPass(),It=Me.useProgram("sky"),Xt=Du(tt,je);It.draw(tt,yt.TRIANGLES,vt,Lt,Kt,ms.disabled,At,null,void 0,"sky",Xt.vertexBuffer,Xt.indexBuffer,Xt.segments)}(this,this.style.sky),this._showOverdrawInspector=m.showOverdrawInspector,this.depthRangeFor3D=[0,1-(l._order.length+2)*this.numSublayers*this.depthEpsilon],!this.renderToTexture)for(this.renderPass="opaque",this.currentLayer=V.length-1;this.currentLayer>=0;this.currentLayer--){let Me=this.style._layers[V[this.currentLayer]],je=W[Me.source],tt=te[Me.source];this._renderTileClippingMasks(Me,tt,!1),this.renderLayer(this,je,Me,tt,ye)}this.renderPass="translucent";let Re=!1;for(this.currentLayer=0;this.currentLayer({u_sun_pos:Pr,u_atmosphere_blend:Ai,u_globe_position:_i,u_globe_radius:hi,u_inv_proj_matrix:hn}))(It,Rt,[br[0],br[1],br[2]],zt,jt),Rr=Du(yt,je);vt.draw(yt,At.TRIANGLES,Lt,us.disabled,ia.alphaBlended,ms.disabled,Cr,null,null,"atmosphere",Rr.vertexBuffer,Rr.indexBuffer,Rr.segments)}(this,this.style.sky,this.style.light),this.options.showTileBoundaries){let Me=function(je,tt){let yt=null,At=Object.values(je._layers).flatMap(It=>It.source&&!It.isHidden(tt)?[je.tileManagers[It.source]]:[]),vt=At.filter(It=>It.getSource().type==="vector"),Lt=At.filter(It=>It.getSource().type!=="vector"),Kt=It=>{(!yt||yt.getSource().maxzoomKt(It)),yt||Lt.forEach(It=>Kt(It)),yt}(this.style,this.transform.zoom);Me&&function(je,tt,yt){for(let At=0;Atbr.getElevation(Pr,Ja,ya):null;El(_i,Cr,Rr,zt,jt,fo,di,hi,$r,o.aP(jt,Ai,Xt,Rt),Pr.toUnwrapped(),oa)}}}(fe,W,se,te,se.layout.get("text-rotation-alignment"),se.layout.get("text-pitch-alignment"),se.paint.get("text-translate"),se.paint.get("text-translate-anchor"),ye),se.paint.get("icon-opacity").constantOr(1)!==0&&An(W,te,se,fe,!1,se.paint.get("icon-translate"),se.paint.get("icon-translate-anchor"),se.layout.get("icon-rotation-alignment"),se.layout.get("icon-pitch-alignment"),se.layout.get("icon-keep-upright"),je,tt,Me),se.paint.get("text-opacity").constantOr(1)!==0&&An(W,te,se,fe,!0,se.paint.get("text-translate"),se.paint.get("text-translate-anchor"),se.layout.get("text-rotation-alignment"),se.layout.get("text-pitch-alignment"),se.layout.get("text-keep-upright"),je,tt,Me),te.map.showCollisionBoxes&&(fa(W,te,se,fe,!0),fa(W,te,se,fe,!1))}(l,m,T,P,this.style.placement.variableOffsets,V):o.co(T)?function(W,te,se,fe,ye){if(W.renderPass!=="translucent")return;let{isRenderingToTexture:Re}=ye,Me=se.paint.get("circle-opacity"),je=se.paint.get("circle-stroke-width"),tt=se.paint.get("circle-stroke-opacity"),yt=!se.layout.get("circle-sort-key").isConstant();if(Me.constantOr(1)===0&&(je.constantOr(1)===0||tt.constantOr(1)===0))return;let At=W.context,vt=At.gl,Lt=W.transform,Kt=W.getDepthModeForSublayer(0,Ao.ReadOnly),It=us.disabled,Xt=W.colorModeForRenderPass(),Rt=[],zt=Lt.getCircleRadiusCorrection();for(let jt=0;jtjt.sortKey-br.sortKey);for(let jt of Rt){let{programConfiguration:br,program:Cr,layoutVertexBuffer:Rr,indexBuffer:Pr,uniformValues:Ai,terrainData:_i,projectionData:hi}=jt.state;Cr.draw(At,vt.TRIANGLES,Kt,It,Xt,ms.backCCW,Ai,_i,hi,se.id,Rr,Pr,jt.segments,se.paint,W.transform.zoom,br)}}(l,m,T,P,V):o.cp(T)?function(W,te,se,fe,ye){if(se.paint.get("heatmap-opacity")===0)return;let Re=W.context,{isRenderingToTexture:Me,isRenderingGlobe:je}=ye;if(W.style.map.terrain){for(let tt of fe){let yt=te.getTile(tt);te.hasRenderableParent(tt)||(W.renderPass==="offscreen"?Xd(W,yt,se,tt,je):W.renderPass==="translucent"&&Vc(W,se,tt,Me,je))}Re.viewport.set([0,0,W.width,W.height])}else W.renderPass==="offscreen"?function(tt,yt,At,vt){let Lt=tt.context,Kt=Lt.gl,It=tt.transform,Xt=us.disabled,Rt=new ia([Kt.ONE,Kt.ONE],o.bq.transparent,[!0,!0,!0,!0]);(function(zt,jt,br){let Cr=zt.gl;zt.activeTexture.set(Cr.TEXTURE1),zt.viewport.set([0,0,jt.width/4,jt.height/4]);let Rr=br.heatmapFbos.get(o.ce);Rr?(Cr.bindTexture(Cr.TEXTURE_2D,Rr.colorAttachment.get()),zt.bindFramebuffer.set(Rr.framebuffer)):(Rr=Au(zt,jt.width/4,jt.height/4),br.heatmapFbos.set(o.ce,Rr))})(Lt,tt,At),Lt.clear({color:o.bq.transparent});for(let zt=0;zt0?m.pop():null}isPatternMissing(l){if(!l)return!1;if(!l.from||!l.to)return!0;let m=this.imageManager.getPattern(l.from.toString()),T=this.imageManager.getPattern(l.to.toString());return!m||!T}useProgram(l,m,T=!1,P=[]){this.cache=this.cache||{};let V=!!this.style.map.terrain,W=this.style.projection,te=T?_a.projectionMercator:W.shaderPreludeCode,se=T?sl:W.shaderDefine,fe=l+(m?m.cacheKey:"")+`/${T?Ol:W.shaderVariantName}`+(this._showOverdrawInspector?"/overdraw":"")+(V?"/terrain":"")+(P?`/${P.join("/")}`:"");return this.cache[fe]||(this.cache[fe]=new Ts(this.context,_a[l],m,Pn[l],this._showOverdrawInspector,V,te,se,P)),this.cache[fe]}setCustomLayerDefaults(){this.context.unbindVAO(),this.context.cullFace.setDefault(),this.context.activeTexture.setDefault(),this.context.pixelStoreUnpack.setDefault(),this.context.pixelStoreUnpackPremultiplyAlpha.setDefault(),this.context.pixelStoreUnpackFlipY.setDefault()}setBaseState(){let l=this.context.gl;this.context.cullFace.set(!1),this.context.viewport.set([0,0,this.width,this.height]),this.context.blendEquation.set(l.FUNC_ADD)}initDebugOverlayCanvas(){this.debugOverlayCanvas==null&&(this.debugOverlayCanvas=document.createElement("canvas"),this.debugOverlayCanvas.width=512,this.debugOverlayCanvas.height=512,this.debugOverlayTexture=new o.T(this.context,this.debugOverlayCanvas,this.context.gl.RGBA))}destroy(){var l,m;if(this._tileTextures){for(let T in this._tileTextures){let P=this._tileTextures[T];if(P)for(let V of P)V.destroy()}this._tileTextures={}}if(this.tileExtentBuffer&&this.tileExtentBuffer.destroy(),this.debugBuffer&&this.debugBuffer.destroy(),this.rasterBoundsBuffer&&this.rasterBoundsBuffer.destroy(),this.rasterBoundsBufferPosOnly&&this.rasterBoundsBufferPosOnly.destroy(),this.viewportBuffer&&this.viewportBuffer.destroy(),this.tileBorderIndexBuffer&&this.tileBorderIndexBuffer.destroy(),this.quadTriangleIndexBuffer&&this.quadTriangleIndexBuffer.destroy(),this.tileExtentMesh&&((l=this.tileExtentMesh.vertexBuffer)===null||l===void 0||l.destroy()),this.tileExtentMesh&&((m=this.tileExtentMesh.indexBuffer)===null||m===void 0||m.destroy()),this.debugOverlayTexture&&this.debugOverlayTexture.destroy(),this.cache){for(let T in this.cache){let P=this.cache[T];P&&P.program&&this.context.gl.deleteProgram(P.program)}this.cache={}}this.context&&this.context.setDefault()}overLimit(){let{drawingBufferWidth:l,drawingBufferHeight:m}=this.context.gl;return this.width!==l||this.height!==m}}function Kd(z,l){let m,T=!1,P=null,V=null,W=()=>{P=null,T&&(z.apply(V,m),P=setTimeout(W,l),T=!1)};return(...te)=>(T=!0,V=this,m=te,P||W(),P)}class Yf{constructor(l){this._getCurrentHash=()=>{let m=window.location.hash.replace("#","");if(this._hashName){let T;return m.split("&").map(P=>P.split("=")).forEach(P=>{P[0]===this._hashName&&(T=P)}),(T&&T[1]||"").split("/")}return m.split("/")},this._onHashChange=()=>{let m=this._getCurrentHash();if(!this._isValidHash(m))return!1;let T=this._map.dragRotate.isEnabled()&&this._map.touchZoomRotate.isEnabled()?+(m[3]||0):this._map.getBearing();return this._map.jumpTo({center:[+m[2],+m[1]],zoom:+m[0],bearing:T,pitch:+(m[4]||0)}),!0},this._updateHashUnthrottled=()=>{let m=window.location.href.replace(/(#.*)?$/,this.getHashString());window.history.replaceState(window.history.state,null,m)},this._removeHash=()=>{let m=this._getCurrentHash();if(m.length===0)return;let T=m.join("/"),P=T;P.split("&").length>0&&(P=P.split("&")[0]),this._hashName&&(P=`${this._hashName}=${T}`);let V=window.location.hash.replace(P,"");V.startsWith("#&")?V=V.slice(0,1)+V.slice(2):V==="#"&&(V="");let W=window.location.href.replace(/(#.+)?$/,V);W=W.replace("&&","&"),window.history.replaceState(window.history.state,null,W)},this._updateHash=Kd(this._updateHashUnthrottled,300),this._hashName=l&&encodeURIComponent(l)}addTo(l){return this._map=l,addEventListener("hashchange",this._onHashChange,!1),this._map.on("moveend",this._updateHash),this}remove(){return removeEventListener("hashchange",this._onHashChange,!1),this._map.off("moveend",this._updateHash),clearTimeout(this._updateHash()),this._removeHash(),delete this._map,this}getHashString(l){let m=this._map.getCenter(),T=Math.round(100*this._map.getZoom())/100,P=Math.ceil((T*Math.LN2+Math.log(512/360/.5))/Math.LN10),V=Math.pow(10,P),W=Math.round(m.lng*V)/V,te=Math.round(m.lat*V)/V,se=this._map.getBearing(),fe=this._map.getPitch(),ye="";if(ye+=l?`/${W}/${te}/${T}`:`${T}/${te}/${W}`,(se||fe)&&(ye+="/"+Math.round(10*se)/10),fe&&(ye+=`/${Math.round(fe)}`),this._hashName){let Re=this._hashName,Me=!1,je=window.location.hash.slice(1).split("&").map(tt=>{let yt=tt.split("=")[0];return yt===Re?(Me=!0,`${yt}=${ye}`):tt}).filter(tt=>tt);return Me||je.push(`${Re}=${ye}`),`#${je.join("&")}`}return`#${ye}`}_isValidHash(l){if(l.length<3||l.some(isNaN))return!1;try{new o.V(+l[2],+l[1])}catch{return!1}let m=+l[0],T=+(l[3]||0),P=+(l[4]||0);return m>=this._map.getMinZoom()&&m<=this._map.getMaxZoom()&&T>=-180&&T<=180&&P>=this._map.getMinPitch()&&P<=this._map.getMaxPitch()}}let Qh={linearity:.3,easing:o.cx(0,0,.3,1)},w=o.e({deceleration:2500,maxSpeed:1400},Qh),M=o.e({deceleration:20,maxSpeed:1400},Qh),S=o.e({deceleration:1e3,maxSpeed:360},Qh),L=o.e({deceleration:1e3,maxSpeed:90},Qh),Y=o.e({deceleration:1e3,maxSpeed:360},Qh);class ie{constructor(l){this._map=l,this.clear()}clear(){this._inertiaBuffer=[]}record(l){this._drainInertiaBuffer(),this._inertiaBuffer.push({time:k(),settings:l})}_drainInertiaBuffer(){let l=this._inertiaBuffer,m=k();for(;l.length>0&&m-l[0].time>160;)l.shift()}_onMoveEnd(l){if(this._drainInertiaBuffer(),this._inertiaBuffer.length<2)return;let m={zoom:0,bearing:0,pitch:0,roll:0,pan:new o.P(0,0),pinchAround:void 0,around:void 0};for(let{settings:V}of this._inertiaBuffer)m.zoom+=V.zoomDelta||0,m.bearing+=V.bearingDelta||0,m.pitch+=V.pitchDelta||0,m.roll+=V.rollDelta||0,V.panDelta&&m.pan._add(V.panDelta),V.around&&(m.around=V.around),V.pinchAround&&(m.pinchAround=V.pinchAround);let T=this._inertiaBuffer[this._inertiaBuffer.length-1].time-this._inertiaBuffer[0].time,P={};if(m.pan.mag()){let V=ge(m.pan.mag(),T,o.e({},w,l||{})),W=m.pan.mult(V.amount/m.pan.mag()),te=this._map.cameraHelper.handlePanInertia(W,this._map.transform);P.center=te.easingCenter,P.offset=te.easingOffset,ae(P,V)}if(m.zoom){let V=ge(m.zoom,T,M);P.zoom=this._map.transform.zoom+V.amount,ae(P,V)}if(m.bearing){let V=ge(m.bearing,T,S);P.bearing=this._map.transform.bearing+o.ao(V.amount,-179,179),ae(P,V)}if(m.pitch){let V=ge(m.pitch,T,L);P.pitch=this._map.transform.pitch+V.amount,ae(P,V)}if(m.roll){let V=ge(m.roll,T,Y);P.roll=this._map.transform.roll+o.ao(V.amount,-179,179),ae(P,V)}if(P.zoom||P.bearing){let V=m.pinchAround===void 0?m.around:m.pinchAround;P.around=V?this._map.unproject(V):this._map.getCenter()}return this.clear(),o.e(P,{noMoveStart:!0})}}function ae(z,l){(!z.duration||z.durationm.unproject(se)),te=V.reduce((se,fe,ye,Re)=>se.add(fe.div(Re.length)),new o.P(0,0));super(l,{points:V,point:te,lngLats:W,lngLat:m.unproject(te),originalEvent:T}),this._defaultPrevented=!1}}class ct extends o.l{preventDefault(){this._defaultPrevented=!0}get defaultPrevented(){return this._defaultPrevented}constructor(l,m,T){super(l,{originalEvent:T}),this._defaultPrevented=!1}}class ft{constructor(l,m){this._map=l,this._clickTolerance=m.clickTolerance}reset(){delete this._mousedownPos}wheel(l){return this._firePreventable(new ct(l.type,this._map,l))}mousedown(l,m){return this._mousedownPos=m,this._firePreventable(new Pe(l.type,this._map,l))}mouseup(l){this._map.fire(new Pe(l.type,this._map,l))}click(l,m){this._mousedownPos&&this._mousedownPos.dist(m)>=this._clickTolerance||this._map.fire(new Pe(l.type,this._map,l))}dblclick(l){return this._firePreventable(new Pe(l.type,this._map,l))}mouseover(l){this._map.fire(new Pe(l.type,this._map,l))}mouseout(l){this._map.fire(new Pe(l.type,this._map,l))}touchstart(l){return this._firePreventable(new Ue(l.type,this._map,l))}touchmove(l){this._map.fire(new Ue(l.type,this._map,l))}touchend(l){this._map.fire(new Ue(l.type,this._map,l))}touchcancel(l){this._map.fire(new Ue(l.type,this._map,l))}_firePreventable(l){if(this._map.fire(l),l.defaultPrevented)return{}}isEnabled(){return!0}isActive(){return!1}enable(){}disable(){}}class gt{constructor(l){this._map=l}reset(){this._delayContextMenu=!1,this._ignoreContextMenu=!0,delete this._contextMenuEvent}mousemove(l){this._map.fire(new Pe(l.type,this._map,l))}mousedown(){this._delayContextMenu=!0,this._ignoreContextMenu=!1}mouseup(){this._delayContextMenu=!1,this._contextMenuEvent&&(this._map.fire(new Pe("contextmenu",this._map,this._contextMenuEvent)),delete this._contextMenuEvent)}contextmenu(l){this._delayContextMenu?this._contextMenuEvent=l:this._ignoreContextMenu||this._map.fire(new Pe(l.type,this._map,l)),this._map.listens("contextmenu")&&l.preventDefault()}isEnabled(){return!0}isActive(){return!1}enable(){}disable(){}}class ut{constructor(l){this._map=l}get transform(){return this._map._requestedCameraState||this._map.transform}get center(){return{lng:this.transform.center.lng,lat:this.transform.center.lat}}get zoom(){return this.transform.zoom}get pitch(){return this.transform.pitch}get bearing(){return this.transform.bearing}unproject(l){return this.transform.screenPointToLocation(o.P.convert(l),this._map.terrain)}}class Pt{constructor(l,m){this._map=l,this._tr=new ut(l),this._el=l.getCanvasContainer(),this._container=l.getContainer(),this._clickTolerance=m.clickTolerance||1}isEnabled(){return!!this._enabled}isActive(){return!!this._active}enable(){this.isEnabled()||(this._enabled=!0)}disable(){this.isEnabled()&&(this._enabled=!1)}mousedown(l,m){this.isEnabled()&&l.shiftKey&&l.button===0&&(U.disableDrag(),this._startPos=this._lastPos=m,this._active=!0)}mousemoveWindow(l,m){if(!this._active)return;let T=m;if(this._lastPos.equals(T)||!this._box&&T.dist(this._startPos)V.fitScreenCoordinates(T,P,this._tr.bearing,{linear:!0})};this._fireEvent("boxzoomcancel",l)}keydown(l){this._active&&l.keyCode===27&&(this.reset(),this._fireEvent("boxzoomcancel",l))}reset(){this._active=!1,this._container.classList.remove("maplibregl-crosshair"),this._box&&(U.remove(this._box),this._box=null),U.enableDrag(),delete this._startPos,delete this._lastPos}_fireEvent(l,m){return this._map.fire(new o.l(l,{originalEvent:m}))}}function Wt(z,l){if(z.length!==l.length)throw new Error(`The number of touches and points are not equal - touches ${z.length}, points ${l.length}`);let m={};for(let T=0;Tthis.numTouches)&&(this.aborted=!0),this.aborted||(this.startTime===void 0&&(this.startTime=l.timeStamp),T.length===this.numTouches&&(this.centroid=function(P){let V=new o.P(0,0);for(let W of P)V._add(W);return V.div(P.length)}(m),this.touches=Wt(T,m)))}touchmove(l,m,T){if(this.aborted||!this.centroid)return;let P=Wt(T,m);for(let V in this.touches){let W=P[V];(!W||W.dist(this.touches[V])>30)&&(this.aborted=!0)}}touchend(l,m,T){if((!this.centroid||l.timeStamp-this.startTime>500)&&(this.aborted=!0),T.length===0){let P=!this.aborted&&this.centroid;if(this.reset(),P)return P}}}class Zt{constructor(l){this.singleTap=new St(l),this.numTaps=l.numTaps,this.reset()}reset(){this.lastTime=1/0,delete this.lastTap,this.count=0,this.singleTap.reset()}touchstart(l,m,T){this.singleTap.touchstart(l,m,T)}touchmove(l,m,T){this.singleTap.touchmove(l,m,T)}touchend(l,m,T){let P=this.singleTap.touchend(l,m,T);if(P){let V=l.timeStamp-this.lastTime<500,W=!this.lastTap||this.lastTap.dist(P)<30;if(V&&W||this.reset(),this.count++,this.lastTime=l.timeStamp,this.lastTap=P,this.count===this.numTaps)return this.reset(),P}}}class ir{constructor(l){this._tr=new ut(l),this._zoomIn=new Zt({numTouches:1,numTaps:2}),this._zoomOut=new Zt({numTouches:2,numTaps:1}),this.reset()}reset(){this._active=!1,this._zoomIn.reset(),this._zoomOut.reset()}touchstart(l,m,T){this._zoomIn.touchstart(l,m,T),this._zoomOut.touchstart(l,m,T)}touchmove(l,m,T){this._zoomIn.touchmove(l,m,T),this._zoomOut.touchmove(l,m,T)}touchend(l,m,T){let P=this._zoomIn.touchend(l,m,T),V=this._zoomOut.touchend(l,m,T),W=this._tr;return P?(this._active=!0,l.preventDefault(),setTimeout(()=>this.reset(),0),{cameraAnimation:te=>te.easeTo({duration:300,zoom:W.zoom+1,around:W.unproject(P)},{originalEvent:l})}):V?(this._active=!0,l.preventDefault(),setTimeout(()=>this.reset(),0),{cameraAnimation:te=>te.easeTo({duration:300,zoom:W.zoom-1,around:W.unproject(V)},{originalEvent:l})}):void 0}touchcancel(){this.reset()}enable(){this._enabled=!0}disable(){this._enabled=!1,this.reset()}isEnabled(){return this._enabled}isActive(){return this._active}}class dr{constructor(l){this._enabled=!!l.enable,this._moveStateManager=l.moveStateManager,this._clickTolerance=l.clickTolerance||1,this._moveFunction=l.move,this._activateOnStart=!!l.activateOnStart,l.assignEvents(this),this.reset()}reset(l){this._active=!1,this._moved=!1,delete this._lastPoint,this._moveStateManager.endMove(l)}_move(...l){let m=this._moveFunction(...l);if(m.bearingDelta||m.pitchDelta||m.rollDelta||m.around||m.panDelta)return this._active=!0,m}dragStart(l,m){this.isEnabled()&&!this._lastPoint&&this._moveStateManager.isValidStartEvent(l)&&(this._moveStateManager.startMove(l),this._lastPoint=Array.isArray(m)?m[0]:m,this._activateOnStart&&this._lastPoint&&(this._active=!0))}dragMove(l,m){if(!this.isEnabled())return;let T=this._lastPoint;if(!T)return;if(l.preventDefault(),!this._moveStateManager.isValidMoveEvent(l))return void this.reset(l);let P=Array.isArray(m)?m[0]:m;return!this._moved&&P.dist(T)!0}),m=new Ci){this.mouseMoveStateManager=l,this.oneFingerTouchMoveStateManager=m}_executeRelevantHandler(l,m,T){return l instanceof MouseEvent?m(l):typeof TouchEvent<"u"&&l instanceof TouchEvent?T(l):void 0}startMove(l){this._executeRelevantHandler(l,m=>this.mouseMoveStateManager.startMove(m),m=>this.oneFingerTouchMoveStateManager.startMove(m))}endMove(l){this._executeRelevantHandler(l,m=>this.mouseMoveStateManager.endMove(m),m=>this.oneFingerTouchMoveStateManager.endMove(m))}isValidStartEvent(l){return this._executeRelevantHandler(l,m=>this.mouseMoveStateManager.isValidStartEvent(m),m=>this.oneFingerTouchMoveStateManager.isValidStartEvent(m))}isValidMoveEvent(l){return this._executeRelevantHandler(l,m=>this.mouseMoveStateManager.isValidMoveEvent(m),m=>this.oneFingerTouchMoveStateManager.isValidMoveEvent(m))}isValidEndEvent(l){return this._executeRelevantHandler(l,m=>this.mouseMoveStateManager.isValidEndEvent(m),m=>this.oneFingerTouchMoveStateManager.isValidEndEvent(m))}}let $i=z=>{z.mousedown=z.dragStart,z.mousemoveWindow=z.dragMove,z.mouseup=z.dragEnd,z.contextmenu=l=>{l.preventDefault()}};class bn{constructor(l,m){this._clickTolerance=l.clickTolerance||1,this._map=m,this.reset()}reset(){this._active=!1,this._touches={},this._sum=new o.P(0,0)}_shouldBePrevented(l){return l<(this._map.cooperativeGestures.isEnabled()?2:1)}touchstart(l,m,T){return this._calculateTransform(l,m,T)}touchmove(l,m,T){if(this._active){if(!this._shouldBePrevented(T.length))return l.preventDefault(),this._calculateTransform(l,m,T);this._map.cooperativeGestures.notifyGestureBlocked("touch_pan",l)}}touchend(l,m,T){this._calculateTransform(l,m,T),this._active&&this._shouldBePrevented(T.length)&&this.reset()}touchcancel(){this.reset()}_calculateTransform(l,m,T){T.length>0&&(this._active=!0);let P=Wt(T,m),V=new o.P(0,0),W=new o.P(0,0),te=0;for(let fe in P){let ye=P[fe],Re=this._touches[fe];Re&&(V._add(ye),W._add(ye.sub(Re)),te++,P[fe]=ye)}if(this._touches=P,this._shouldBePrevented(te)||!W.mag())return;let se=W.div(te);return this._sum._add(se),this._sum.mag()Math.abs(z.x)}class Hn extends Tn{constructor(l){super(),this._currentTouchCount=0,this._map=l}reset(){super.reset(),this._valid=void 0,delete this._firstMove,delete this._lastPoints}touchstart(l,m,T){super.touchstart(l,m,T),this._currentTouchCount=T.length}_start(l){this._lastPoints=l,Gi(l[0].sub(l[1]))&&(this._valid=!1)}_move(l,m,T){if(this._map.cooperativeGestures.isEnabled()&&this._currentTouchCount<3)return;let P=l[0].sub(this._lastPoints[0]),V=l[1].sub(this._lastPoints[1]);return this._valid=this.gestureBeginsVertically(P,V,T.timeStamp),this._valid?(this._lastPoints=l,this._active=!0,{pitchDelta:(P.y+V.y)/2*-.5}):void 0}gestureBeginsVertically(l,m,T){if(this._valid!==void 0)return this._valid;let P=l.mag()>=2,V=m.mag()>=2;if(!P&&!V)return;if(!P||!V)return this._firstMove===void 0&&(this._firstMove=T),T-this._firstMove<100&&void 0;let W=l.y>0==m.y>0;return Gi(l)&&Gi(m)&&W}}let eo={panStep:100,bearingStep:15,pitchStep:10};class Dn{constructor(l){this._tr=new ut(l);let m=eo;this._panStep=m.panStep,this._bearingStep=m.bearingStep,this._pitchStep=m.pitchStep,this._rotationDisabled=!1}reset(){this._active=!1}keydown(l){if(l.altKey||l.ctrlKey||l.metaKey)return;let m=0,T=0,P=0,V=0,W=0;switch(l.keyCode){case 61:case 107:case 171:case 187:m=1;break;case 189:case 109:case 173:m=-1;break;case 37:l.shiftKey?T=-1:(l.preventDefault(),V=-1);break;case 39:l.shiftKey?T=1:(l.preventDefault(),V=1);break;case 38:l.shiftKey?P=1:(l.preventDefault(),W=-1);break;case 40:l.shiftKey?P=-1:(l.preventDefault(),W=1);break;default:return}return this._rotationDisabled&&(T=0,P=0),{cameraAnimation:te=>{let se=this._tr;te.easeTo({duration:300,easeId:"keyboardHandler",easing:Rn,zoom:m?Math.round(se.zoom)+m*(l.shiftKey?2:1):se.zoom,bearing:se.bearing+T*this._bearingStep,pitch:se.pitch+P*this._pitchStep,offset:[-V*this._panStep,-W*this._panStep],center:se.center},{originalEvent:l})}}}enable(){this._enabled=!0}disable(){this._enabled=!1,this.reset()}isEnabled(){return this._enabled}isActive(){return this._active}disableRotation(){this._rotationDisabled=!0}enableRotation(){this._rotationDisabled=!1}}function Rn(z){return z*(2-z)}let Il=4.000244140625,Ga=1/450;class yc{constructor(l,m){this._onTimeout=T=>{this._type="wheel",this._delta-=this._lastValue,this._active||this._start(T)},this._map=l,this._tr=new ut(l),this._triggerRenderFrame=m,this._delta=0,this._defaultZoomRate=.01,this._wheelZoomRate=Ga}setZoomRate(l){this._defaultZoomRate=l}setWheelZoomRate(l){this._wheelZoomRate=l}isEnabled(){return!!this._enabled}isActive(){return!!this._active||this._finishTimeout!==void 0}isZooming(){return!!this._zooming}enable(l){this.isEnabled()||(this._enabled=!0,this._aroundCenter=!!l&&l.around==="center")}disable(){this.isEnabled()&&(this._enabled=!1)}_shouldBePrevented(l){return!!this._map.cooperativeGestures.isEnabled()&&!(l.ctrlKey||this._map.cooperativeGestures.isBypassed(l))}wheel(l){if(!this.isEnabled())return;if(this._shouldBePrevented(l))return void this._map.cooperativeGestures.notifyGestureBlocked("wheel_zoom",l);let m=l.deltaMode===WheelEvent.DOM_DELTA_LINE?40*l.deltaY:l.deltaY,T=k(),P=T-(this._lastWheelEventTime||0);this._lastWheelEventTime=T,m!==0&&m%Il==0?this._type="wheel":m!==0&&Math.abs(m)<4?this._type="trackpad":P>400?(this._type=null,this._lastValue=m,this._timeout=setTimeout(this._onTimeout,40,l)):this._type||(this._type=Math.abs(P*m)<200?"trackpad":"wheel",this._timeout&&(clearTimeout(this._timeout),this._timeout=null,m+=this._lastValue)),l.shiftKey&&m&&(m/=4),this._type&&(this._lastWheelEvent=l,this._delta-=m,this._active||this._start(l)),l.preventDefault()}_start(l){if(!this._delta)return;this._frameId&&(this._frameId=null),this._active=!0,this.isZooming()||(this._zooming=!0),this._finishTimeout&&(clearTimeout(this._finishTimeout),delete this._finishTimeout);let m=U.mousePos(this._map.getCanvas(),l),T=this._tr;this._aroundPoint=this._aroundCenter?T.transform.locationToScreenPoint(o.V.convert(T.center)):m,this._frameId||(this._frameId=!0,this._triggerRenderFrame())}renderFrame(){if(!this._frameId||(this._frameId=null,!this.isActive()))return;let l=this._tr.transform;if(typeof this._lastExpectedZoom=="number"){let te=l.zoom-this._lastExpectedZoom;typeof this._startZoom=="number"&&(this._startZoom+=te),typeof this._targetZoom=="number"&&(this._targetZoom+=te)}if(this._delta!==0){let te=this._type==="wheel"&&Math.abs(this._delta)>Il?this._wheelZoomRate:this._defaultZoomRate,se=2/(1+Math.exp(-Math.abs(this._delta*te)));this._delta<0&&se!==0&&(se=1/se);let fe=typeof this._targetZoom!="number"?l.scale:o.ar(this._targetZoom);this._targetZoom=l.applyConstrain(l.getCameraLngLat(),o.au(fe*se)).zoom,this._type==="wheel"&&(this._startZoom=l.zoom,this._easing=this._smoothOutEasing(200)),this._delta=0}let m=typeof this._targetZoom!="number"?l.zoom:this._targetZoom,T=this._startZoom,P=this._easing,V,W=!1;if(this._type==="wheel"&&T&&P){let te=k()-this._lastWheelEventTime,se=Math.min((te+5)/200,1),fe=P(se);V=o.G.number(T,m,fe),se<1?this._frameId||(this._frameId=!0):W=!0}else V=m,W=!0;return this._active=!0,W&&(this._active=!1,this._finishTimeout=setTimeout(()=>{this._zooming=!1,this._triggerRenderFrame(),delete this._targetZoom,delete this._lastExpectedZoom,delete this._finishTimeout},200)),this._lastExpectedZoom=V,{noInertia:!0,needsRenderFrame:!W,zoomDelta:V-l.zoom,around:this._aroundPoint,originalEvent:this._lastWheelEvent}}_smoothOutEasing(l){let m=o.cz;if(this._prevEase){let T=this._prevEase,P=(k()-T.start)/T.duration,V=T.easing(P+.01)-T.easing(P),W=.27/Math.sqrt(V*V+1e-4)*.01,te=Math.sqrt(.0729-W*W);m=o.cx(W,te,.25,1)}return this._prevEase={start:k(),duration:l,easing:m},m}reset(){this._active=!1,this._zooming=!1,delete this._targetZoom,delete this._lastExpectedZoom,this._finishTimeout&&(clearTimeout(this._finishTimeout),delete this._finishTimeout)}}class cl{constructor(l,m){this._clickZoom=l,this._tapZoom=m}enable(){this._clickZoom.enable(),this._tapZoom.enable()}disable(){this._clickZoom.disable(),this._tapZoom.disable()}isEnabled(){return this._clickZoom.isEnabled()&&this._tapZoom.isEnabled()}isActive(){return this._clickZoom.isActive()||this._tapZoom.isActive()}}class Vs{constructor(l){this._tr=new ut(l),this.reset()}reset(){this._active=!1}dblclick(l,m){return l.preventDefault(),{cameraAnimation:T=>{T.easeTo({duration:300,zoom:this._tr.zoom+(l.shiftKey?-1:1),around:this._tr.unproject(m)},{originalEvent:l})}}}enable(){this._enabled=!0}disable(){this._enabled=!1,this.reset()}isEnabled(){return this._enabled}isActive(){return this._active}}class Ta{constructor(){this._tap=new Zt({numTouches:1,numTaps:1}),this.reset()}reset(){this._active=!1,delete this._swipePoint,delete this._swipeTouch,delete this._tapTime,delete this._tapPoint,this._tap.reset()}touchstart(l,m,T){if(!this._swipePoint)if(this._tapTime){let P=m[0],V=l.timeStamp-this._tapTime<500,W=this._tapPoint.dist(P)<30;V&&W?T.length>0&&(this._swipePoint=P,this._swipeTouch=T[0].identifier):this.reset()}else this._tap.touchstart(l,m,T)}touchmove(l,m,T){if(this._tapTime){if(this._swipePoint){if(T[0].identifier!==this._swipeTouch)return;let P=m[0],V=P.y-this._swipePoint.y;return this._swipePoint=P,l.preventDefault(),this._active=!0,{zoomDelta:V/128}}}else this._tap.touchmove(l,m,T)}touchend(l,m,T){if(this._tapTime)this._swipePoint&&T.length===0&&this.reset();else{let P=this._tap.touchend(l,m,T);P&&(this._tapTime=l.timeStamp,this._tapPoint=P)}}touchcancel(){this.reset()}enable(){this._enabled=!0}disable(){this._enabled=!1,this.reset()}isEnabled(){return this._enabled}isActive(){return this._active}}class tn{constructor(l,m,T){this._el=l,this._mousePan=m,this._touchPan=T}enable(l){this._inertiaOptions=l||{},this._mousePan.enable(),this._touchPan.enable(),this._el.classList.add("maplibregl-touch-drag-pan")}disable(){this._mousePan.disable(),this._touchPan.disable(),this._el.classList.remove("maplibregl-touch-drag-pan")}isEnabled(){return this._mousePan.isEnabled()&&this._touchPan.isEnabled()}isActive(){return this._mousePan.isActive()||this._touchPan.isActive()}}class _n{constructor(l,m,T,P){this._pitchWithRotate=l.pitchWithRotate,this._rollEnabled=l.rollEnabled,this._mouseRotate=m,this._mousePitch=T,this._mouseRoll=P}enable(){this._mouseRotate.enable(),this._pitchWithRotate&&this._mousePitch.enable(),this._rollEnabled&&this._mouseRoll.enable()}disable(){this._mouseRotate.disable(),this._mousePitch.disable(),this._mouseRoll.disable()}isEnabled(){return this._mouseRotate.isEnabled()&&(!this._pitchWithRotate||this._mousePitch.isEnabled())&&(!this._rollEnabled||this._mouseRoll.isEnabled())}isActive(){return this._mouseRotate.isActive()||this._mousePitch.isActive()||this._mouseRoll.isActive()}}class Ju{constructor(l,m,T,P){this._el=l,this._touchZoom=m,this._touchRotate=T,this._tapDragZoom=P,this._rotationDisabled=!1,this._enabled=!0}enable(l){this._touchZoom.enable(l),this._rotationDisabled||this._touchRotate.enable(l),this._tapDragZoom.enable(),this._el.classList.add("maplibregl-touch-zoom-rotate")}disable(){this._touchZoom.disable(),this._touchRotate.disable(),this._tapDragZoom.disable(),this._el.classList.remove("maplibregl-touch-zoom-rotate")}isEnabled(){return this._touchZoom.isEnabled()&&(this._rotationDisabled||this._touchRotate.isEnabled())&&this._tapDragZoom.isEnabled()}isActive(){return this._touchZoom.isActive()||this._touchRotate.isActive()||this._tapDragZoom.isActive()}disableRotation(){this._rotationDisabled=!0,this._touchRotate.disable()}enableRotation(){this._rotationDisabled=!1,this._touchZoom.isEnabled()&&this._touchRotate.enable()}}class jc{constructor(l,m){this._bypassKey=navigator.userAgent.indexOf("Mac")!==-1?"metaKey":"ctrlKey",this._map=l,this._options=m,this._enabled=!1}isActive(){return!1}reset(){}_setupUI(){if(this._container)return;let l=this._map.getCanvasContainer();l.classList.add("maplibregl-cooperative-gestures"),this._container=U.create("div","maplibregl-cooperative-gesture-screen",l);let m=this._map._getUIString("CooperativeGesturesHandler.WindowsHelpText");this._bypassKey==="metaKey"&&(m=this._map._getUIString("CooperativeGesturesHandler.MacHelpText"));let T=this._map._getUIString("CooperativeGesturesHandler.MobileHelpText"),P=document.createElement("div");P.className="maplibregl-desktop-message",P.textContent=m,this._container.appendChild(P);let V=document.createElement("div");V.className="maplibregl-mobile-message",V.textContent=T,this._container.appendChild(V),this._container.setAttribute("aria-hidden","true")}_destroyUI(){this._container&&(U.remove(this._container),this._map.getCanvasContainer().classList.remove("maplibregl-cooperative-gestures")),delete this._container}enable(){this._setupUI(),this._enabled=!0}disable(){this._enabled=!1,this._destroyUI()}isEnabled(){return this._enabled}isBypassed(l){return l[this._bypassKey]}notifyGestureBlocked(l,m){this._enabled&&(this._map.fire(new o.l("cooperativegestureprevented",{gestureType:l,originalEvent:m})),this._container.classList.add("maplibregl-show"),setTimeout(()=>{this._container.classList.remove("maplibregl-show")},100))}}let Hc=z=>z.zoom||z.drag||z.roll||z.pitch||z.rotate;class Fa extends o.l{}function Gc(z){return z.panDelta&&z.panDelta.mag()||z.zoomDelta||z.bearingDelta||z.pitchDelta||z.rollDelta}class bd{constructor(l,m){this.handleWindowEvent=P=>{this.handleEvent(P,`${P.type}Window`)},this.handleEvent=(P,V)=>{if(P.type==="blur")return void this.stop(!0);this._updatingCamera=!0;let W=P.type==="renderFrame"?void 0:P,te={needsRenderFrame:!1},se={},fe={};for(let{handlerName:Me,handler:je,allowed:tt}of this._handlers){if(!je.isEnabled())continue;let yt;if(this._blockedByActive(fe,tt,Me))je.reset();else if(je[V||P.type]){if(o.cA(P,V||P.type)){let At=U.mousePos(this._map.getCanvas(),P);yt=je[V||P.type](P,At)}else if(o.cB(P,V||P.type)){let At=this._getMapTouches(P.touches),vt=U.touchPos(this._map.getCanvas(),At);yt=je[V||P.type](P,vt,At)}else o.cC(V||P.type)||(yt=je[V||P.type](P));this.mergeHandlerResult(te,se,yt,Me,W),yt&&yt.needsRenderFrame&&this._triggerRenderFrame()}(yt||je.isActive())&&(fe[Me]=je)}let ye={};for(let Me in this._previousActiveHandlers)fe[Me]||(ye[Me]=W);this._previousActiveHandlers=fe,(Object.keys(ye).length||Gc(te))&&(this._changes.push([te,se,ye]),this._triggerRenderFrame()),(Object.keys(fe).length||Gc(te))&&this._map._stop(!0),this._updatingCamera=!1;let{cameraAnimation:Re}=te;Re&&(this._inertia.clear(),this._fireEvents({},{},!0),this._changes=[],Re(this._map))},this._map=l,this._el=this._map.getCanvasContainer(),this._handlers=[],this._handlersById={},this._changes=[],this._inertia=new ie(l),this._bearingSnap=m.bearingSnap,this._previousActiveHandlers={},this._eventsInProgress={},this._addDefaultHandlers(m);let T=this._el;this._listeners=[[T,"touchstart",{passive:!0}],[T,"touchmove",{passive:!1}],[T,"touchend",void 0],[T,"touchcancel",void 0],[T,"mousedown",void 0],[T,"mousemove",void 0],[T,"mouseup",void 0],[document,"mousemove",{capture:!0}],[document,"mouseup",void 0],[T,"mouseover",void 0],[T,"mouseout",void 0],[T,"dblclick",void 0],[T,"click",void 0],[T,"keydown",{capture:!1}],[T,"keyup",void 0],[T,"wheel",{passive:!1}],[T,"contextmenu",void 0],[window,"blur",void 0]];for(let[P,V,W]of this._listeners)U.addEventListener(P,V,P===document?this.handleWindowEvent:this.handleEvent,W)}destroy(){for(let[l,m,T]of this._listeners)U.removeEventListener(l,m,l===document?this.handleWindowEvent:this.handleEvent,T)}_addDefaultHandlers(l){let m=this._map,T=m.getCanvasContainer();this._add("mapEvent",new ft(m,l));let P=m.boxZoom=new Pt(m,l);this._add("boxZoom",P),l.interactive&&l.boxZoom&&P.enable();let V=m.cooperativeGestures=new jc(m,l.cooperativeGestures);this._add("cooperativeGestures",V),l.cooperativeGestures&&V.enable();let W=new ir(m),te=new Vs(m);m.doubleClickZoom=new cl(te,W),this._add("tapZoom",W),this._add("clickZoom",te),l.interactive&&l.doubleClickZoom&&m.doubleClickZoom.enable();let se=new Ta;this._add("tapDragZoom",se);let fe=m.touchPitch=new Hn(m);this._add("touchPitch",fe),l.interactive&&l.touchPitch&&m.touchPitch.enable(l.touchPitch);let ye=()=>m.project(m.getCenter()),Re=function({enable:It,clickTolerance:Xt,aroundCenter:Rt=!0,minPixelCenterThreshold:zt=100,rotateDegreesPerPixelMoved:jt=.8},br){let Cr=new ai({checkCorrectEvent:Rr=>U.mouseButton(Rr)===0&&Rr.ctrlKey||U.mouseButton(Rr)===2&&!Rr.ctrlKey});return new dr({clickTolerance:Xt,move:(Rr,Pr)=>{let Ai=br();if(Rt&&Math.abs(Ai.y-Rr.y)>zt)return{bearingDelta:o.cy(new o.P(Rr.x,Pr.y),Pr,Ai)};let _i=(Pr.x-Rr.x)*jt;return Rt&&Pr.yU.mouseButton(jt)===0&&jt.ctrlKey||U.mouseButton(jt)===2});return new dr({clickTolerance:Xt,move:(jt,br)=>({pitchDelta:(br.y-jt.y)*Rt}),moveStateManager:zt,enable:It,assignEvents:$i})}(l),je=function({enable:It,clickTolerance:Xt,rollDegreesPerPixelMoved:Rt=.3},zt){let jt=new ai({checkCorrectEvent:br=>U.mouseButton(br)===2&&br.ctrlKey});return new dr({clickTolerance:Xt,move:(br,Cr)=>{let Rr=zt(),Pr=(Cr.x-br.x)*Rt;return Cr.yU.mouseButton(zt)===0&&!zt.ctrlKey});return new dr({clickTolerance:Xt,move:(zt,jt)=>({around:jt,panDelta:jt.sub(zt)}),activateOnStart:!0,moveStateManager:Rt,enable:It,assignEvents:$i})}(l),yt=new bn(l,m);m.dragPan=new tn(T,tt,yt),this._add("mousePan",tt),this._add("touchPan",yt,["touchZoom","touchRotate"]),l.interactive&&l.dragPan&&m.dragPan.enable(l.dragPan);let At=new $n,vt=new qi;m.touchZoomRotate=new Ju(T,vt,At,se),this._add("touchRotate",At,["touchPan","touchZoom"]),this._add("touchZoom",vt,["touchPan","touchRotate"]),l.interactive&&l.touchZoomRotate&&m.touchZoomRotate.enable(l.touchZoomRotate),this._add("blockableMapEvent",new gt(m));let Lt=m.scrollZoom=new yc(m,()=>this._triggerRenderFrame());this._add("scrollZoom",Lt,["mousePan"]),l.interactive&&l.scrollZoom&&m.scrollZoom.enable(l.scrollZoom);let Kt=m.keyboard=new Dn(m);this._add("keyboard",Kt),l.interactive&&l.keyboard&&m.keyboard.enable()}_add(l,m,T){this._handlers.push({handlerName:l,handler:m,allowed:T}),this._handlersById[l]=m}stop(l){if(!this._updatingCamera){for(let{handler:m}of this._handlers)m.reset();this._inertia.clear(),this._fireEvents({},{},l),this._changes=[]}}isActive(){for(let{handler:l}of this._handlers)if(l.isActive())return!0;return!1}isZooming(){return!!this._eventsInProgress.zoom||this._map.scrollZoom.isZooming()}isRotating(){return!!this._eventsInProgress.rotate}isMoving(){return Boolean(Hc(this._eventsInProgress))||this.isZooming()}_blockedByActive(l,m,T){for(let P in l)if(P!==T&&(!m||m.indexOf(P)<0))return!0;return!1}_getMapTouches(l){let m=[];for(let T of l)this._el.contains(T.target)&&m.push(T);return m}mergeHandlerResult(l,m,T,P,V){if(!T)return;o.e(l,T);let W={handlerName:P,originalEvent:T.originalEvent||V};T.zoomDelta!==void 0&&(m.zoom=W),T.panDelta!==void 0&&(m.drag=W),T.rollDelta!==void 0&&(m.roll=W),T.pitchDelta!==void 0&&(m.pitch=W),T.bearingDelta!==void 0&&(m.rotate=W)}_applyChanges(){let l={},m={},T={};for(let[P,V,W]of this._changes)P.panDelta&&(l.panDelta=(l.panDelta||new o.P(0,0))._add(P.panDelta)),P.zoomDelta&&(l.zoomDelta=(l.zoomDelta||0)+P.zoomDelta),P.bearingDelta&&(l.bearingDelta=(l.bearingDelta||0)+P.bearingDelta),P.pitchDelta&&(l.pitchDelta=(l.pitchDelta||0)+P.pitchDelta),P.rollDelta&&(l.rollDelta=(l.rollDelta||0)+P.rollDelta),P.around!==void 0&&(l.around=P.around),P.pinchAround!==void 0&&(l.pinchAround=P.pinchAround),P.noInertia&&(l.noInertia=P.noInertia),o.e(m,V),o.e(T,W);this._updateMapTransform(l,m,T),this._changes=[]}_updateMapTransform(l,m,T){let P=this._map,V=P._getTransformForUpdate(),W=P.terrain;if(!(Gc(l)||W&&this._terrainMovement))return this._fireEvents(m,T,!0);P._stop(!0);let{panDelta:te,zoomDelta:se,bearingDelta:fe,pitchDelta:ye,rollDelta:Re,around:Me,pinchAround:je}=l;je!==void 0&&(Me=je),Me=Me||P.transform.centerPoint,W&&!V.isPointOnMapSurface(Me)&&(Me=V.centerPoint);let tt={panDelta:te,zoomDelta:se,rollDelta:Re,pitchDelta:ye,bearingDelta:fe,around:Me};this._map.cameraHelper.useGlobeControls&&!V.isPointOnMapSurface(Me)&&(Me=V.centerPoint);let yt=Me.distSqr(V.centerPoint)<.01?V.center:V.screenPointToLocation(te?Me.sub(te):Me);this._handleMapControls({terrain:W,tr:V,deltasForHelper:tt,preZoomAroundLoc:yt,combinedEventsInProgress:m,panDelta:te}),P._applyUpdatedTransform(V),this._map._update(),l.noInertia||this._inertia.record(l),this._fireEvents(m,T,!0)}_handleMapControls({terrain:l,tr:m,deltasForHelper:T,preZoomAroundLoc:P,combinedEventsInProgress:V,panDelta:W}){let te=this._map.cameraHelper;if(te.handleMapControlsRollPitchBearingZoom(T,m),l)return te.useGlobeControls?(this._terrainMovement||!V.drag&&!V.zoom||(this._terrainMovement=!0,this._map._elevationFreeze=!0),void te.handleMapControlsPan(T,m,P)):this._terrainMovement||!V.drag&&!V.zoom?void(V.drag&&this._terrainMovement&&W?m.setCenter(m.screenPointToLocation(m.centerPoint.sub(W))):te.handleMapControlsPan(T,m,P)):(this._terrainMovement=!0,this._map._elevationFreeze=!0,void te.handleMapControlsPan(T,m,P));te.handleMapControlsPan(T,m,P)}_fireEvents(l,m,T){let P=Hc(this._eventsInProgress),V=Hc(l),W={};for(let Re in l){let{originalEvent:Me}=l[Re];this._eventsInProgress[Re]||(W[`${Re}start`]=Me),this._eventsInProgress[Re]=l[Re]}!P&&V&&this._fireEvent("movestart",V.originalEvent);for(let Re in W)this._fireEvent(Re,W[Re]);V&&this._fireEvent("move",V.originalEvent);for(let Re in l){let{originalEvent:Me}=l[Re];this._fireEvent(Re,Me)}let te={},se;for(let Re in this._eventsInProgress){let{handlerName:Me,originalEvent:je}=this._eventsInProgress[Re];this._handlersById[Me].isActive()||(delete this._eventsInProgress[Re],se=m[Me]||je,te[`${Re}end`]=se)}for(let Re in te)this._fireEvent(Re,te[Re]);let fe=Hc(this._eventsInProgress),ye=(P||V)&&!fe;if(ye&&this._terrainMovement){this._map._elevationFreeze=!1,this._terrainMovement=!1;let Re=this._map._getTransformForUpdate();this._map.getCenterClampedToGround()&&Re.recalculateZoomAndCenter(this._map.terrain),this._map._applyUpdatedTransform(Re)}if(T&&ye){this._updatingCamera=!0;let Re=this._inertia._onMoveEnd(this._map.dragPan._inertiaOptions),Me=je=>je!==0&&-this._bearingSnap{delete this._frameId,this.handleEvent(new Fa("renderFrame",{timeStamp:l})),this._applyChanges()})}_triggerRenderFrame(){this._frameId===void 0&&(this._frameId=this._requestFrame())}}class wd extends o.E{constructor(l,m,T){super(),this._renderFrameCallback=()=>{let P=Math.min((k()-this._easeStart)/this._easeOptions.duration,1);this._onEaseFrame(this._easeOptions.easing(P)),P<1&&this._easeFrameId?this._easeFrameId=this._requestRenderFrame(this._renderFrameCallback):this.stop()},this._moving=!1,this._zooming=!1,this.transform=l,this._bearingSnap=T.bearingSnap,this.cameraHelper=m,this.on("moveend",()=>{delete this._requestedCameraState})}migrateProjection(l,m){l.apply(this.transform),this.transform=l,this.cameraHelper=m}getCenter(){return new o.V(this.transform.center.lng,this.transform.center.lat)}setCenter(l,m){return this.jumpTo({center:l},m)}getCenterElevation(){return this.transform.elevation}setCenterElevation(l,m){return this.jumpTo({elevation:l},m),this}getCenterClampedToGround(){return this._centerClampedToGround}setCenterClampedToGround(l){this._centerClampedToGround=l}panBy(l,m,T){return l=o.P.convert(l).mult(-1),this.panTo(this.transform.center,o.e({offset:l},m),T)}panTo(l,m,T){return this.easeTo(o.e({center:l},m),T)}getZoom(){return this.transform.zoom}setZoom(l,m){return this.jumpTo({zoom:l},m),this}zoomTo(l,m,T){return this.easeTo(o.e({zoom:l},m),T)}zoomIn(l,m){return this.zoomTo(this.getZoom()+1,l,m),this}zoomOut(l,m){return this.zoomTo(this.getZoom()-1,l,m),this}getVerticalFieldOfView(){return this.transform.fov}setVerticalFieldOfView(l,m){return l!=this.transform.fov&&(this.transform.setFov(l),this.fire(new o.l("movestart",m)).fire(new o.l("move",m)).fire(new o.l("moveend",m))),this}getBearing(){return this.transform.bearing}setBearing(l,m){return this.jumpTo({bearing:l},m),this}getPadding(){return this.transform.padding}setPadding(l,m){return this.jumpTo({padding:l},m),this}rotateTo(l,m,T){return this.easeTo(o.e({bearing:l},m),T)}resetNorth(l,m){return this.rotateTo(0,o.e({duration:1e3},l),m),this}resetNorthPitch(l,m){return this.easeTo(o.e({bearing:0,pitch:0,roll:0,duration:1e3},l),m),this}snapToNorth(l,m){return Math.abs(this.getBearing()){yt.easeFunc(At),this.terrain&&!l.freezeElevation&&this._updateElevation(At),this._applyUpdatedTransform(T),this._fireMoveEvents(m)},At=>{this.terrain&&l.freezeElevation&&this._finalizeElevation(),this._afterEase(m,At)},l),this}_prepareEase(l,m,T={}){this._moving=!0,m||T.moving||this.fire(new o.l("movestart",l)),this._zooming&&!T.zooming&&this.fire(new o.l("zoomstart",l)),this._rotating&&!T.rotating&&this.fire(new o.l("rotatestart",l)),this._pitching&&!T.pitching&&this.fire(new o.l("pitchstart",l)),this._rolling&&!T.rolling&&this.fire(new o.l("rollstart",l))}_prepareElevation(l){this._elevationCenter=l,this._elevationStart=this.transform.elevation,this._elevationTarget=this.terrain.getElevationForLngLatZoom(l,this.transform.tileZoom),this._elevationFreeze=!0}_updateElevation(l){this._elevationStart!==void 0&&this._elevationCenter!==void 0||this._prepareElevation(this.transform.center),this.transform.setMinElevationForCurrentTile(this.terrain.getMinTileElevationForLngLatZoom(this._elevationCenter,this.transform.tileZoom));let m=this.terrain.getElevationForLngLatZoom(this._elevationCenter,this.transform.tileZoom);if(l<1&&m!==this._elevationTarget){let T=this._elevationTarget-this._elevationStart;this._elevationStart+=l*(T-(m-(T*l+this._elevationStart))/(1-l)),this._elevationTarget=m}this.transform.setElevation(o.G.number(this._elevationStart,this._elevationTarget,l))}_finalizeElevation(){this._elevationFreeze=!1,this.getCenterClampedToGround()&&this.transform.recalculateZoomAndCenter(this.terrain)}_getTransformForUpdate(){return this.transformCameraUpdate||this.terrain?(this._requestedCameraState||(this._requestedCameraState=this.transform.clone()),this._requestedCameraState):this.transform}_elevateCameraIfInsideTerrain(l){if(!this.terrain&&l.elevation>=0&&l.pitch<=90)return{};let m=l.getCameraLngLat(),T=l.getCameraAltitude(),P=this.terrain?this.terrain.getElevationForLngLatZoom(m,l.zoom):0;if(Tthis._elevateCameraIfInsideTerrain(P)),this.transformCameraUpdate&&m.push(P=>this.transformCameraUpdate(P)),!m.length)return;let T=l.clone();for(let P of m){let V=T.clone(),{center:W,zoom:te,roll:se,pitch:fe,bearing:ye,elevation:Re}=P(V);W&&V.setCenter(W),Re!==void 0&&V.setElevation(Re),te!==void 0&&V.setZoom(te),se!==void 0&&V.setRoll(se),fe!==void 0&&V.setPitch(fe),ye!==void 0&&V.setBearing(ye),T.apply(V)}this.transform.apply(T)}_fireMoveEvents(l){this.fire(new o.l("move",l)),this._zooming&&this.fire(new o.l("zoom",l)),this._rotating&&this.fire(new o.l("rotate",l)),this._pitching&&this.fire(new o.l("pitch",l)),this._rolling&&this.fire(new o.l("roll",l))}_afterEase(l,m){if(this._easeId&&m&&this._easeId===m)return;delete this._easeId;let T=this._zooming,P=this._rotating,V=this._pitching,W=this._rolling;this._moving=!1,this._zooming=!1,this._rotating=!1,this._pitching=!1,this._rolling=!1,this._padding=!1,T&&this.fire(new o.l("zoomend",l)),P&&this.fire(new o.l("rotateend",l)),V&&this.fire(new o.l("pitchend",l)),W&&this.fire(new o.l("rollend",l)),this.fire(new o.l("moveend",l))}flyTo(l,m){if(!l.essential&&I.prefersReducedMotion){let Pr=o.U(l,["center","zoom","bearing","pitch","roll","elevation","padding"]);return this.jumpTo(Pr,m)}this.stop(),l=o.e({offset:[0,0],speed:1.2,curve:1.42,easing:o.cz},l);let T=this._getTransformForUpdate(),P=T.bearing,V=T.pitch,W=T.roll,te=T.padding,se="bearing"in l?this._normalizeBearing(l.bearing,P):P,fe="pitch"in l?+l.pitch:V,ye="roll"in l?this._normalizeBearing(l.roll,W):W,Re="padding"in l?l.padding:T.padding,Me=o.P.convert(l.offset),je=T.centerPoint.add(Me),tt=T.screenPointToLocation(je),yt=this.cameraHelper.handleFlyTo(T,{bearing:se,pitch:fe,roll:ye,padding:Re,locationAtOffset:tt,offsetAsPoint:Me,center:l.center,minZoom:l.minZoom,zoom:l.zoom}),At=l.curve,vt=Math.max(T.width,T.height),Lt=vt/yt.scaleOfZoom,Kt=yt.pixelPathLength;typeof yt.scaleOfMinZoom=="number"&&(At=Math.sqrt(vt/yt.scaleOfMinZoom/Kt*2));let It=At*At;function Xt(Pr){let Ai=(Lt*Lt-vt*vt+(Pr?-1:1)*It*It*Kt*Kt)/(2*(Pr?Lt:vt)*It*Kt);return Math.log(Math.sqrt(Ai*Ai+1)-Ai)}function Rt(Pr){return(Math.exp(Pr)-Math.exp(-Pr))/2}function zt(Pr){return(Math.exp(Pr)+Math.exp(-Pr))/2}let jt=Xt(!1),br=function(Pr){return zt(jt)/zt(jt+At*Pr)},Cr=function(Pr){return vt*((zt(jt)*(Rt(Ai=jt+At*Pr)/zt(Ai))-Rt(jt))/It)/Kt;var Ai},Rr=(Xt(!0)-jt)/At;if(Math.abs(Kt)<2e-6||!isFinite(Rr)){if(Math.abs(vt-Lt)<1e-6)return this.easeTo(l,m);let Pr=Lt0,br=Ai=>Math.exp(Pr*At*Ai)}return l.duration="duration"in l?+l.duration:1e3*Rr/("screenSpeed"in l?+l.screenSpeed/At:+l.speed),l.maxDuration&&l.duration>l.maxDuration&&(l.duration=0),this._zooming=!0,this._rotating=P!==se,this._pitching=fe!==V,this._rolling=ye!==W,this._padding=!T.isPaddingEqual(Re),this._prepareEase(m,!1),this.terrain&&this._prepareElevation(yt.targetCenter),this._ease(Pr=>{let Ai=Pr*Rr,_i=1/br(Ai),hi=Cr(Ai);this._rotating&&T.setBearing(o.G.number(P,se,Pr)),this._pitching&&T.setPitch(o.G.number(V,fe,Pr)),this._rolling&&T.setRoll(o.G.number(W,ye,Pr)),this._padding&&(T.interpolatePadding(te,Re,Pr),je=T.centerPoint.add(Me)),yt.easeFunc(Pr,_i,hi,je),this.terrain&&!l.freezeElevation&&this._updateElevation(Pr),this._applyUpdatedTransform(T),this._fireMoveEvents(m)},()=>{this.terrain&&l.freezeElevation&&this._finalizeElevation(),this._afterEase(m)},l),this}isEasing(){return!!this._easeFrameId}stop(){return this._stop()}_stop(l,m){var T;if(this._easeFrameId&&(this._cancelRenderFrame(this._easeFrameId),delete this._easeFrameId,delete this._onEaseFrame),this._onEaseEnd){let P=this._onEaseEnd;delete this._onEaseEnd,P.call(this,m)}return l||(T=this.handlers)===null||T===void 0||T.stop(!1),this}_ease(l,m,T){T.animate===!1||T.duration===0?(l(1),m()):(this._easeStart=k(),this._easeOptions=T,this._onEaseFrame=l,this._onEaseEnd=m,this._easeFrameId=this._requestRenderFrame(this._renderFrameCallback))}_normalizeBearing(l,m){l=o.W(l,-180,180);let T=Math.abs(l-m);return Math.abs(l-360-m)MapLibre'};class Ou{constructor(l=Td){this._toggleAttribution=()=>{this._container.classList.contains("maplibregl-compact")&&(this._container.classList.contains("maplibregl-compact-show")?(this._container.setAttribute("open",""),this._container.classList.remove("maplibregl-compact-show")):(this._container.classList.add("maplibregl-compact-show"),this._container.removeAttribute("open")))},this._updateData=m=>{!m||m.sourceDataType!=="metadata"&&m.sourceDataType!=="visibility"&&m.dataType!=="style"&&m.type!=="terrain"||this._updateAttributions()},this._updateCompact=()=>{this._map.getCanvasContainer().offsetWidth<=640||this._compact?this._compact===!1?this._container.setAttribute("open",""):this._container.classList.contains("maplibregl-compact")||this._container.classList.contains("maplibregl-attrib-empty")||(this._container.setAttribute("open",""),this._container.classList.add("maplibregl-compact","maplibregl-compact-show")):(this._container.setAttribute("open",""),this._container.classList.contains("maplibregl-compact")&&this._container.classList.remove("maplibregl-compact","maplibregl-compact-show"))},this._updateCompactMinimize=()=>{this._container.classList.contains("maplibregl-compact")&&this._container.classList.contains("maplibregl-compact-show")&&this._container.classList.remove("maplibregl-compact-show")},this.options=l}getDefaultPosition(){return"bottom-right"}onAdd(l){return this._map=l,this._compact=this.options.compact,this._container=U.create("details","maplibregl-ctrl maplibregl-ctrl-attrib"),this._compactButton=U.create("summary","maplibregl-ctrl-attrib-button",this._container),this._compactButton.addEventListener("click",this._toggleAttribution),this._setElementTitle(this._compactButton,"ToggleAttribution"),this._innerContainer=U.create("div","maplibregl-ctrl-attrib-inner",this._container),this._updateAttributions(),this._updateCompact(),this._map.on("styledata",this._updateData),this._map.on("sourcedata",this._updateData),this._map.on("terrain",this._updateData),this._map.on("resize",this._updateCompact),this._map.on("drag",this._updateCompactMinimize),this._container}onRemove(){U.remove(this._container),this._map.off("styledata",this._updateData),this._map.off("sourcedata",this._updateData),this._map.off("terrain",this._updateData),this._map.off("resize",this._updateCompact),this._map.off("drag",this._updateCompactMinimize),this._map=void 0,this._compact=void 0,this._attribHTML=void 0}_setElementTitle(l,m){let T=this._map._getUIString(`AttributionControl.${m}`);l.title=T,l.setAttribute("aria-label",T)}_updateAttributions(){if(!this._map.style)return;let l=[];if(this.options.customAttribution&&(Array.isArray(this.options.customAttribution)?l=l.concat(this.options.customAttribution.map(P=>typeof P!="string"?"":P)):typeof this.options.customAttribution=="string"&&l.push(this.options.customAttribution)),this._map.style.stylesheet){let P=this._map.style.stylesheet;this.styleOwner=P.owner,this.styleId=P.id}let m=this._map.style.tileManagers;for(let P in m){let V=m[P];if(V.used||V.usedForTerrain){let W=V.getSource();W.attribution&&l.indexOf(W.attribution)<0&&l.push(W.attribution)}}l=l.filter(P=>String(P).trim()),l.sort((P,V)=>P.length-V.length),l=l.filter((P,V)=>{for(let W=V+1;W=0)return!1;return!0});let T=l.join(" | ");T!==this._attribHTML&&(this._attribHTML=T,l.length?(this._innerContainer.innerHTML=U.sanitize(T),this._container.classList.remove("maplibregl-attrib-empty")):this._container.classList.add("maplibregl-attrib-empty"),this._updateCompact(),this._editLink=null)}}class iu{constructor(l={}){this._updateCompact=()=>{let m=this._container.children;if(m.length){let T=m[0];this._map.getCanvasContainer().offsetWidth<=640||this._compact?this._compact!==!1&&T.classList.add("maplibregl-compact"):T.classList.remove("maplibregl-compact")}},this.options=l}getDefaultPosition(){return"bottom-left"}onAdd(l){this._map=l,this._compact=this.options&&this.options.compact,this._container=U.create("div","maplibregl-ctrl");let m=U.create("a","maplibregl-ctrl-logo");return m.target="_blank",m.rel="noopener nofollow",m.href="https://maplibre.org/",m.setAttribute("aria-label",this._map._getUIString("LogoControl.Title")),m.setAttribute("rel","noopener nofollow"),this._container.appendChild(m),this._container.style.display="block",this._map.on("resize",this._updateCompact),this._updateCompact(),this._container}onRemove(){U.remove(this._container),this._map.off("resize",this._updateCompact),this._map=void 0,this._compact=void 0}}class Sa{constructor(){this._queue=[],this._id=0,this._cleared=!1,this._currentlyRunning=!1}add(l){let m=++this._id;return this._queue.push({callback:l,id:m,cancelled:!1}),m}remove(l){let m=this._currentlyRunning,T=m?this._queue.concat(m):this._queue;for(let P of T)if(P.id===l)return void(P.cancelled=!0)}run(l=0){if(this._currentlyRunning)throw new Error("Attempting to run(), but is already running.");let m=this._currentlyRunning=this._queue;this._queue=[];for(let T of m)if(!T.cancelled&&(T.callback(l),this._cleared))break;this._cleared=!1,this._currentlyRunning=!1}clear(){this._currentlyRunning&&(this._cleared=!0),this._queue=[]}}var na=o.aV([{name:"a_pos3d",type:"Int16",components:3}]);class zl extends o.E{constructor(l){super(),this._lastTilesetChange=k(),this.tileManager=l,this._tiles={},this._renderableTilesKeys=[],this._sourceTileCache={},this.minzoom=0,this.maxzoom=22,this.deltaZoom=1,this.tileSize=l._source.tileSize*2**this.deltaZoom,l.usedForTerrain=!0,l.tileSize=this.tileSize}destruct(){this.tileManager.usedForTerrain=!1,this.tileManager.tileSize=null}getSource(){return this.tileManager._source}update(l,m){this.tileManager.update(l,m),this._renderableTilesKeys=[];let T={};for(let P of Qe(l,{tileSize:this.tileSize,minzoom:this.minzoom,maxzoom:this.maxzoom,reparseOverscaled:!1,terrain:m,calculateTileZoom:this.tileManager._source.calculateTileZoom}))T[P.key]=!0,this._renderableTilesKeys.push(P.key),this._tiles[P.key]||(P.terrainRttPosMatrix32f=new Float64Array(16),o.c8(P.terrainRttPosMatrix32f,0,o.a5,o.a5,0,0,1),this._tiles[P.key]=new ti(P,this.tileSize),this._lastTilesetChange=k());for(let P in this._tiles)T[P]||delete this._tiles[P]}freeRtt(l){for(let m in this._tiles){let T=this._tiles[m];(!l||T.tileID.equals(l)||T.tileID.isChildOf(l)||l.isChildOf(T.tileID))&&(T.rtt=[])}}getRenderableTiles(){return this._renderableTilesKeys.map(l=>this.getTileByID(l))}getTileByID(l){return this._tiles[l]}getTerrainCoords(l,m){return m?this._getTerrainCoordsForTileRanges(l,m):this._getTerrainCoordsForRegularTile(l)}_getTerrainCoordsForRegularTile(l){let m={};for(let T of this._renderableTilesKeys){let P=this._tiles[T].tileID,V=l.clone(),W=o.bl();if(P.canonical.equals(l.canonical))o.c8(W,0,o.a5,o.a5,0,0,1);else if(P.canonical.isChildOf(l.canonical)){let te=P.canonical.z-l.canonical.z,se=P.canonical.x-(P.canonical.x>>te<>te<>te;o.c8(W,0,ye,ye,0,0,1),o.O(W,W,[-se*ye,-fe*ye,0])}else{if(!l.canonical.isChildOf(P.canonical))continue;{let te=l.canonical.z-P.canonical.z,se=l.canonical.x-(l.canonical.x>>te<>te<>te;o.c8(W,0,o.a5,o.a5,0,0,1),o.O(W,W,[se*ye,fe*ye,0]),o.Q(W,W,[1/2**te,1/2**te,0])}}V.terrainRttPosMatrix32f=new Float32Array(W),m[T]=V}return m}_getTerrainCoordsForTileRanges(l,m){let T={};for(let P of this._renderableTilesKeys){let V=this._tiles[P].tileID;if(!this._isWithinTileRanges(V,m))continue;let W=l.clone(),te=o.bl();if(V.canonical.z===l.canonical.z){let se=l.canonical.x-V.canonical.x,fe=l.canonical.y-V.canonical.y;o.c8(te,0,o.a5,o.a5,0,0,1),o.O(te,te,[se*o.a5,fe*o.a5,0])}else if(V.canonical.z>l.canonical.z){let se=V.canonical.z-l.canonical.z,fe=V.canonical.x-(V.canonical.x>>se<>se<>se),Me=l.canonical.y-(V.canonical.y>>se),je=o.a5>>se;o.c8(te,0,je,je,0,0,1),o.O(te,te,[-fe*je+Re*o.a5,-ye*je+Me*o.a5,0])}else{let se=l.canonical.z-V.canonical.z,fe=l.canonical.x-(l.canonical.x>>se<>se<>se)-V.canonical.x,Me=(l.canonical.y>>se)-V.canonical.y,je=o.a5<T.maxzoom&&(P=T.maxzoom),P=T.minzoom&&!V?.dem;)V=this.findTileInCaches(l.scaledTo(P--).key);return V}findTileInCaches(l){let m=this.tileManager.getTileByID(l);return m||(m=this.tileManager._outOfViewCache.getByKey(l),m)}anyTilesAfterTime(l=Date.now()){return this._lastTilesetChange>=l}_isWithinTileRanges(l,m){return m[l.canonical.z]&&l.canonical.x>=m[l.canonical.z].minTileX&&l.canonical.x<=m[l.canonical.z].maxTileX&&l.canonical.y>=m[l.canonical.z].minTileY&&l.canonical.y<=m[l.canonical.z].maxTileY}}class eh{constructor(l,m,T){this._meshCache={},this.painter=l,this.tileManager=new zl(m),this.options=T,this.exaggeration=typeof T.exaggeration=="number"?T.exaggeration:1,this.qualityFactor=2,this.meshSize=128,this._demMatrixCache={},this.coordsIndex=[],this._coordsTextureSize=1024}getDEMElevation(l,m,T,P=o.a5){var V;if(!(m>=0&&m=0&&Tl.canonical.z&&(l.canonical.z>=P?V=l.canonical.z-P:o.w("cannot calculate elevation if elevation maxzoom > source.maxzoom"));let W=l.canonical.x-(l.canonical.x>>V<>V<>8<<4|V>>8,m[W+3]=0;let T=new o.R({width:this._coordsTextureSize,height:this._coordsTextureSize},new Uint8Array(m.buffer)),P=new o.T(l,T,l.gl.RGBA,{premultiply:!1});return P.bind(l.gl.NEAREST,l.gl.CLAMP_TO_EDGE),this._coordsTexture=P,P}pointCoordinate(l){this.painter.maybeDrawDepthAndCoords(!0);let m=new Uint8Array(4),T=this.painter.context,P=T.gl,V=Math.round(l.x*this.painter.pixelRatio/devicePixelRatio),W=Math.round(l.y*this.painter.pixelRatio/devicePixelRatio),te=Math.round(this.painter.height/devicePixelRatio);T.bindFramebuffer.set(this.getFramebuffer("coords").framebuffer),P.readPixels(V,te-W-1,1,1,P.RGBA,P.UNSIGNED_BYTE,m),T.bindFramebuffer.set(null);let se=m[0]+(m[2]>>4<<8),fe=m[1]+((15&m[2])<<8),ye=this.coordsIndex[255-m[3]],Re=ye&&this.tileManager.getTileByID(ye);if(!Re)return null;let Me=this._coordsTextureSize,je=(1<0,P=T&&l.canonical.y===0,V=T&&l.canonical.y===(1<l.id!==m),this._recentlyUsed.push(l.id)}stampObject(l){l.stamp=++this._stamp}getOrCreateFreeObject(){for(let m of this._recentlyUsed)if(!this._objects[m].inUse)return this._objects[m];if(this._objects.length>=this._size)throw new Error("No free RenderPool available, call freeAllObjects() required!");let l=this._createObject(this._objects.length);return this._objects.push(l),l}freeObject(l){l.inUse=!1}freeAllObjects(){for(let l of this._objects)this.freeObject(l)}isFull(){return!(this._objects.length!l.inUse)===!1}}let Ul={background:!0,fill:!0,line:!0,raster:!0,hillshade:!0,"color-relief":!0};class _s{constructor(l,m){this.painter=l,this.terrain=m,this.pool=new Jh(l.context,30,m.tileManager.tileSize*m.qualityFactor)}destruct(){this.pool.destruct()}getTexture(l){return this.pool.getObjectForId(l.rtt[this._stacks.length-1].id).texture}prepareForRender(l,m){this._stacks=[],this._prevType=null,this._rttTiles=[],this._renderableTiles=this.terrain.tileManager.getRenderableTiles(),this._renderableLayerIds=l._order.filter(T=>!l._layers[T].isHidden(m)),this._coordsAscending={};for(let T in l.tileManagers){this._coordsAscending[T]={};let P=l.tileManagers[T].getVisibleCoordinates(),V=l.tileManagers[T].getSource(),W=V instanceof ws?V.terrainTileRanges:null;for(let te of P){let se=this.terrain.tileManager.getTerrainCoords(te,W);for(let fe in se)this._coordsAscending[T][fe]||(this._coordsAscending[T][fe]=[]),this._coordsAscending[T][fe].push(se[fe])}}this._coordsAscendingStr={};for(let T of l._order){let P=l._layers[T],V=P.source;if(Ul[P.type]&&!this._coordsAscendingStr[V]){this._coordsAscendingStr[V]={};for(let W in this._coordsAscending[V])this._coordsAscendingStr[V][W]=this._coordsAscending[V][W].map(te=>te.key).sort().join()}}for(let T of this._renderableTiles)for(let P in this._coordsAscendingStr){let V=this._coordsAscendingStr[P][T.tileID.key];V&&V!==T.rttCoords[P]&&(T.rtt=[])}}renderLayer(l,m){if(l.isHidden(this.painter.transform.zoom))return!1;let T=Object.assign(Object.assign({},m),{isRenderingToTexture:!0}),P=l.type,V=this.painter,W=this._renderableLayerIds[this._renderableLayerIds.length-1]===l.id;if(Ul[P]&&(this._prevType&&Ul[this._prevType]||this._stacks.push([]),this._prevType=P,this._stacks[this._stacks.length-1].push(l.id),!W))return!0;if(Ul[this._prevType]||Ul[P]&&W){this._prevType=P;let te=this._stacks.length-1,se=this._stacks[te]||[];for(let fe of this._renderableTiles){if(this.pool.isFull()&&(bf(this.painter,this.terrain,this._rttTiles,T),this._rttTiles=[],this.pool.freeAllObjects()),this._rttTiles.push(fe),fe.rtt[te]){let Re=this.pool.getObjectForId(fe.rtt[te].id);if(Re.stamp===fe.rtt[te].stamp){this.pool.useObject(Re);continue}}let ye=this.pool.getOrCreateFreeObject();this.pool.useObject(ye),this.pool.stampObject(ye),fe.rtt[te]={id:ye.id,stamp:ye.stamp},V.context.bindFramebuffer.set(ye.fbo.framebuffer),V.context.clear({color:o.bq.transparent,stencil:0}),V.currentStencilSource=void 0;for(let Re=0;Re{this.startMove(V,U.mousePos(this.element,V)),U.addEventListener(window,"mousemove",this.mousemove),U.addEventListener(window,"mouseup",this.mouseup)},this.mousemove=V=>{this.move(V,U.mousePos(this.element,V))},this.mouseup=V=>{this._rotatePitchHandler.dragEnd(V),this.offTemp()},this.touchstart=V=>{V.targetTouches.length!==1?this.reset():(this._startPos=this._lastPos=U.touchPos(this.element,V.targetTouches)[0],this.startMove(V,this._startPos),U.addEventListener(window,"touchmove",this.touchmove,{passive:!1}),U.addEventListener(window,"touchend",this.touchend))},this.touchmove=V=>{V.targetTouches.length!==1?this.reset():(this._lastPos=U.touchPos(this.element,V.targetTouches)[0],this.move(V,this._lastPos))},this.touchend=V=>{V.targetTouches.length===0&&this._startPos&&this._lastPos&&this._startPos.dist(this._lastPos){this._rotatePitchHandler.reset(),delete this._startPos,delete this._lastPos,this.offTemp()},this._clickTolerance=10,this.element=m;let P=new Si;this._rotatePitchHandler=new dr({clickTolerance:3,move:(V,W)=>{let te=m.getBoundingClientRect(),se=new o.P((te.bottom-te.top)/2,(te.right-te.left)/2);return{bearingDelta:o.cy(new o.P(V.x,W.y),W,se),pitchDelta:T?-.5*(W.y-V.y):void 0}},moveStateManager:P,enable:!0,assignEvents:()=>{}}),this.map=l,U.addEventListener(m,"mousedown",this.mousedown),U.addEventListener(m,"touchstart",this.touchstart,{passive:!1}),U.addEventListener(m,"touchcancel",this.reset)}startMove(l,m){this._rotatePitchHandler.dragStart(l,m),U.disableDrag()}move(l,m){let T=this.map,{bearingDelta:P,pitchDelta:V}=this._rotatePitchHandler.dragMove(l,m)||{};P&&T.setBearing(T.getBearing()+P),V&&T.setPitch(T.getPitch()+V)}off(){let l=this.element;U.removeEventListener(l,"mousedown",this.mousedown),U.removeEventListener(l,"touchstart",this.touchstart,{passive:!1}),U.removeEventListener(window,"touchmove",this.touchmove,{passive:!1}),U.removeEventListener(window,"touchend",this.touchend),U.removeEventListener(l,"touchcancel",this.reset),this.offTemp()}offTemp(){U.enableDrag(),U.removeEventListener(window,"mousemove",this.mousemove),U.removeEventListener(window,"mouseup",this.mouseup),U.removeEventListener(window,"touchmove",this.touchmove,{passive:!1}),U.removeEventListener(window,"touchend",this.touchend)}}let th;function Kf(z,l,m,T=!1){if(T||!m.getCoveringTilesDetailsProvider().allowWorldCopies())return z?.wrap();let P=new o.V(z.lng,z.lat);if(z=new o.V(z.lng,z.lat),l){let V=new o.V(z.lng-360,z.lat),W=new o.V(z.lng+360,z.lat),te=m.locationToScreenPoint(z).distSqr(l);m.locationToScreenPoint(V).distSqr(l)180;){let V=m.locationToScreenPoint(z);if(V.x>=0&&V.y>=0&&V.x<=m.width&&V.y<=m.height)break;z.lng>m.center.lng?z.lng-=360:z.lng+=360}return z.lng!==P.lng&&m.isPointOnMapSurface(m.locationToScreenPoint(z))?z:P}let wf={center:"translate(-50%,-50%)",top:"translate(-50%,0)","top-left":"translate(0,0)","top-right":"translate(-100%,0)",bottom:"translate(-50%,-100%)","bottom-left":"translate(0,-100%)","bottom-right":"translate(-100%,-100%)",left:"translate(0,-50%)",right:"translate(-100%,-50%)"};function tf(z,l,m){let T=z.classList;for(let P in wf)T.remove(`maplibregl-${m}-anchor-${P}`);T.add(`maplibregl-${m}-anchor-${l}`)}class Tf extends o.E{constructor(l){if(super(),this._onKeyPress=m=>{let T=m.code,P=m.charCode||m.keyCode;T!=="Space"&&T!=="Enter"&&P!==32&&P!==13||this.togglePopup()},this._onMapClick=m=>{let T=m.originalEvent.target,P=this._element;this._popup&&(T===P||P.contains(T))&&this.togglePopup()},this._update=m=>{if(!this._map)return;let T=this._map.loaded()&&!this._map.isMoving();(m?.type==="terrain"||m?.type==="render"&&!T)&&this._map.once("render",this._update),this._lngLat=Kf(this._lngLat,this._flatPos,this._map.transform),this._flatPos=this._pos=this._map.project(this._lngLat)._add(this._offset),this._map.terrain&&(this._flatPos=this._map.transform.locationToScreenPoint(this._lngLat)._add(this._offset));let P="";this._rotationAlignment==="viewport"||this._rotationAlignment==="auto"?P=`rotateZ(${this._rotation}deg)`:this._rotationAlignment==="map"&&(P=`rotateZ(${this._rotation-this._map.getBearing()}deg)`);let V="";this._pitchAlignment==="viewport"||this._pitchAlignment==="auto"?V="rotateX(0deg)":this._pitchAlignment==="map"&&(V=`rotateX(${this._map.getPitch()}deg)`),this._subpixelPositioning||m&&m.type!=="moveend"||(this._pos=this._pos.round()),U.setTransform(this._element,`${wf[this._anchor]} translate(${this._pos.x}px, ${this._pos.y}px) ${V} ${P}`),I.frameAsync(new AbortController).then(()=>{this._updateOpacity(m&&m.type==="moveend")}).catch(()=>{})},this._onMove=m=>{if(!this._isDragging){let T=this._clickTolerance||this._map._clickTolerance;this._isDragging=m.point.dist(this._pointerdownPos)>=T}this._isDragging&&(this._pos=m.point.sub(this._positionDelta),this._lngLat=this._map.unproject(this._pos),this.setLngLat(this._lngLat),this._element.style.pointerEvents="none",this._state==="pending"&&(this._state="active",this.fire(new o.l("dragstart"))),this.fire(new o.l("drag")))},this._onUp=()=>{this._element.style.pointerEvents="auto",this._positionDelta=null,this._pointerdownPos=null,this._isDragging=!1,this._map.off("mousemove",this._onMove),this._map.off("touchmove",this._onMove),this._state==="active"&&this.fire(new o.l("dragend")),this._state="inactive"},this._addDragHandler=m=>{this._element.contains(m.originalEvent.target)&&(m.preventDefault(),this._positionDelta=m.point.sub(this._pos).add(this._offset),this._pointerdownPos=m.point,this._state="pending",this._map.on("mousemove",this._onMove),this._map.on("touchmove",this._onMove),this._map.once("mouseup",this._onUp),this._map.once("touchend",this._onUp))},this._anchor=l&&l.anchor||"center",this._color=l&&l.color||"#3FB1CE",this._scale=l&&l.scale||1,this._draggable=l&&l.draggable||!1,this._clickTolerance=l&&l.clickTolerance||0,this._subpixelPositioning=l&&l.subpixelPositioning||!1,this._isDragging=!1,this._state="inactive",this._rotation=l&&l.rotation||0,this._rotationAlignment=l&&l.rotationAlignment||"auto",this._pitchAlignment=l&&l.pitchAlignment&&l.pitchAlignment!=="auto"?l.pitchAlignment:this._rotationAlignment,this.setOpacity(l?.opacity,l?.opacityWhenCovered),l&&l.element)this._element=l.element,this._offset=o.P.convert(l&&l.offset||[0,0]);else{this._defaultMarker=!0,this._element=U.create("div");let m=U.createNS("http://www.w3.org/2000/svg","svg"),T=41,P=27;m.setAttributeNS(null,"display","block"),m.setAttributeNS(null,"height",`${T}px`),m.setAttributeNS(null,"width",`${P}px`),m.setAttributeNS(null,"viewBox",`0 0 ${P} ${T}`);let V=U.createNS("http://www.w3.org/2000/svg","g");V.setAttributeNS(null,"stroke","none"),V.setAttributeNS(null,"stroke-width","1"),V.setAttributeNS(null,"fill","none"),V.setAttributeNS(null,"fill-rule","evenodd");let W=U.createNS("http://www.w3.org/2000/svg","g");W.setAttributeNS(null,"fill-rule","nonzero");let te=U.createNS("http://www.w3.org/2000/svg","g");te.setAttributeNS(null,"transform","translate(3.0, 29.0)"),te.setAttributeNS(null,"fill","#000000");let se=[{rx:"10.5",ry:"5.25002273"},{rx:"10.5",ry:"5.25002273"},{rx:"9.5",ry:"4.77275007"},{rx:"8.5",ry:"4.29549936"},{rx:"7.5",ry:"3.81822308"},{rx:"6.5",ry:"3.34094679"},{rx:"5.5",ry:"2.86367051"},{rx:"4.5",ry:"2.38636864"}];for(let vt of se){let Lt=U.createNS("http://www.w3.org/2000/svg","ellipse");Lt.setAttributeNS(null,"opacity","0.04"),Lt.setAttributeNS(null,"cx","10.5"),Lt.setAttributeNS(null,"cy","5.80029008"),Lt.setAttributeNS(null,"rx",vt.rx),Lt.setAttributeNS(null,"ry",vt.ry),te.appendChild(Lt)}let fe=U.createNS("http://www.w3.org/2000/svg","g");fe.setAttributeNS(null,"fill",this._color);let ye=U.createNS("http://www.w3.org/2000/svg","path");ye.setAttributeNS(null,"d","M27,13.5 C27,19.074644 20.250001,27.000002 14.75,34.500002 C14.016665,35.500004 12.983335,35.500004 12.25,34.500002 C6.7499993,27.000002 0,19.222562 0,13.5 C0,6.0441559 6.0441559,0 13.5,0 C20.955844,0 27,6.0441559 27,13.5 Z"),fe.appendChild(ye);let Re=U.createNS("http://www.w3.org/2000/svg","g");Re.setAttributeNS(null,"opacity","0.25"),Re.setAttributeNS(null,"fill","#000000");let Me=U.createNS("http://www.w3.org/2000/svg","path");Me.setAttributeNS(null,"d","M13.5,0 C6.0441559,0 0,6.0441559 0,13.5 C0,19.222562 6.7499993,27 12.25,34.5 C13,35.522727 14.016664,35.500004 14.75,34.5 C20.250001,27 27,19.074644 27,13.5 C27,6.0441559 20.955844,0 13.5,0 Z M13.5,1 C20.415404,1 26,6.584596 26,13.5 C26,15.898657 24.495584,19.181431 22.220703,22.738281 C19.945823,26.295132 16.705119,30.142167 13.943359,33.908203 C13.743445,34.180814 13.612715,34.322738 13.5,34.441406 C13.387285,34.322738 13.256555,34.180814 13.056641,33.908203 C10.284481,30.127985 7.4148684,26.314159 5.015625,22.773438 C2.6163816,19.232715 1,15.953538 1,13.5 C1,6.584596 6.584596,1 13.5,1 Z"),Re.appendChild(Me);let je=U.createNS("http://www.w3.org/2000/svg","g");je.setAttributeNS(null,"transform","translate(6.0, 7.0)"),je.setAttributeNS(null,"fill","#FFFFFF");let tt=U.createNS("http://www.w3.org/2000/svg","g");tt.setAttributeNS(null,"transform","translate(8.0, 8.0)");let yt=U.createNS("http://www.w3.org/2000/svg","circle");yt.setAttributeNS(null,"fill","#000000"),yt.setAttributeNS(null,"opacity","0.25"),yt.setAttributeNS(null,"cx","5.5"),yt.setAttributeNS(null,"cy","5.5"),yt.setAttributeNS(null,"r","5.4999962");let At=U.createNS("http://www.w3.org/2000/svg","circle");At.setAttributeNS(null,"fill","#FFFFFF"),At.setAttributeNS(null,"cx","5.5"),At.setAttributeNS(null,"cy","5.5"),At.setAttributeNS(null,"r","5.4999962"),tt.appendChild(yt),tt.appendChild(At),W.appendChild(te),W.appendChild(fe),W.appendChild(Re),W.appendChild(je),W.appendChild(tt),m.appendChild(W),m.setAttributeNS(null,"height",T*this._scale+"px"),m.setAttributeNS(null,"width",P*this._scale+"px"),this._element.appendChild(m),this._offset=o.P.convert(l&&l.offset||[0,-14])}if(this._element.classList.add("maplibregl-marker"),this._element.addEventListener("dragstart",m=>{m.preventDefault()}),this._element.addEventListener("mousedown",m=>{m.preventDefault()}),tf(this._element,this._anchor,"marker"),l&&l.className)for(let m of l.className.split(" "))this._element.classList.add(m);this._popup=null}addTo(l){return this.remove(),this._map=l,this._element.hasAttribute("aria-label")||this._element.setAttribute("aria-label",l._getUIString("Marker.Title")),this._element.hasAttribute("role")||this._element.setAttribute("role","button"),l.getCanvasContainer().appendChild(this._element),l.on("move",this._update),l.on("moveend",this._update),l.on("terrain",this._update),l.on("projectiontransition",this._update),this.setDraggable(this._draggable),this._update(),this._map.on("click",this._onMapClick),this}remove(){return this._opacityTimeout&&(clearTimeout(this._opacityTimeout),delete this._opacityTimeout),this._map&&(this._map.off("click",this._onMapClick),this._map.off("move",this._update),this._map.off("moveend",this._update),this._map.off("terrain",this._update),this._map.off("projectiontransition",this._update),this._map.off("mousedown",this._addDragHandler),this._map.off("touchstart",this._addDragHandler),this._map.off("mouseup",this._onUp),this._map.off("touchend",this._onUp),this._map.off("mousemove",this._onMove),this._map.off("touchmove",this._onMove),delete this._map),U.remove(this._element),this._popup&&this._popup.remove(),this}getLngLat(){return this._lngLat}setLngLat(l){return this._lngLat=o.V.convert(l),this._pos=null,this._popup&&this._popup.setLngLat(this._lngLat),this._update(),this}getElement(){return this._element}setPopup(l){if(this._popup&&(this._popup.remove(),this._popup=null,this._element.removeEventListener("keypress",this._onKeyPress),this._originalTabIndex||this._element.removeAttribute("tabindex")),l){if(!("offset"in l.options)){let P=Math.abs(13.5)/Math.SQRT2;l.options.offset=this._defaultMarker?{top:[0,0],"top-left":[0,0],"top-right":[0,0],bottom:[0,-38.1],"bottom-left":[P,-1*(38.1-13.5+P)],"bottom-right":[-P,-1*(38.1-13.5+P)],left:[13.5,-1*(38.1-13.5)],right:[-13.5,-1*(38.1-13.5)]}:this._offset}this._popup=l,this._originalTabIndex=this._element.getAttribute("tabindex"),this._originalTabIndex||this._element.setAttribute("tabindex","0"),this._element.addEventListener("keypress",this._onKeyPress)}return this}setSubpixelPositioning(l){return this._subpixelPositioning=l,this}getPopup(){return this._popup}togglePopup(){let l=this._popup;return this._element.style.opacity===this._opacityWhenCovered?this:l?(l.isOpen()?l.remove():(l.setLngLat(this._lngLat),l.addTo(this._map)),this):this}_updateOpacity(l=!1){var m,T;let P=(m=this._map)===null||m===void 0?void 0:m.terrain,V=this._map.transform.isLocationOccluded(this._lngLat);if(!P||V){let je=V?this._opacityWhenCovered:this._opacity;return void(this._element.style.opacity!==je&&(this._element.style.opacity=je))}if(l)this._opacityTimeout=null;else{if(this._opacityTimeout)return;this._opacityTimeout=setTimeout(()=>{this._opacityTimeout=null},100)}let W=this._map,te=W.terrain.depthAtPoint(this._pos),se=W.terrain.getElevationForLngLat(this._lngLat);if(W.transform.lngLatToCameraDepth(this._lngLat,se)-te<.006)return void(this._element.style.opacity=this._opacity);let fe=-this._offset.y/W.transform.pixelsPerMeter,ye=Math.sin(W.getPitch()*Math.PI/180)*fe,Re=W.terrain.depthAtPoint(new o.P(this._pos.x,this._pos.y-this._offset.y)),Me=W.transform.lngLatToCameraDepth(this._lngLat,se+ye)-Re>.006;!((T=this._popup)===null||T===void 0)&&T.isOpen()&&Me&&this._popup.remove(),this._element.style.opacity=Me?this._opacityWhenCovered:this._opacity}getOffset(){return this._offset}setOffset(l){return this._offset=o.P.convert(l),this._update(),this}addClassName(l){this._element.classList.add(l)}removeClassName(l){this._element.classList.remove(l)}toggleClassName(l){return this._element.classList.toggle(l)}setDraggable(l){return this._draggable=!!l,this._map&&(l?(this._map.on("mousedown",this._addDragHandler),this._map.on("touchstart",this._addDragHandler)):(this._map.off("mousedown",this._addDragHandler),this._map.off("touchstart",this._addDragHandler))),this}isDraggable(){return this._draggable}setRotation(l){return this._rotation=l||0,this._update(),this}getRotation(){return this._rotation}setRotationAlignment(l){return this._rotationAlignment=l||"auto",this._update(),this}getRotationAlignment(){return this._rotationAlignment}setPitchAlignment(l){return this._pitchAlignment=l&&l!=="auto"?l:this._rotationAlignment,this._update(),this}getPitchAlignment(){return this._pitchAlignment}setOpacity(l,m){return(this._opacity===void 0||l===void 0&&m===void 0)&&(this._opacity="1",this._opacityWhenCovered="0.2"),l!==void 0&&(this._opacity=l),m!==void 0&&(this._opacityWhenCovered=m),this._map&&this._updateOpacity(!0),this}}let og={positionOptions:{enableHighAccuracy:!1,maximumAge:0,timeout:6e3},fitBoundsOptions:{maxZoom:15},trackUserLocation:!1,showAccuracyCircle:!0,showUserLocation:!0},Fu=0,Vl=!1,M_={maxWidth:100,unit:"metric"};function sg(z,l,m){let T=m&&m.maxWidth||100,P=z._container.clientHeight/2,V=z._container.clientWidth/2,W=z.unproject([V-T/2,P]),te=z.unproject([V+T/2,P]),se=Math.round(z.project(te).x-z.project(W).x),fe=Math.min(T,se,z._container.clientWidth),ye=W.distanceTo(te);if(m&&m.unit==="imperial"){let Re=3.2808*ye;Re>5280?gm(l,fe,Re/5280,z._getUIString("ScaleControl.Miles")):gm(l,fe,Re,z._getUIString("ScaleControl.Feet"))}else m&&m.unit==="nautical"?gm(l,fe,ye/1852,z._getUIString("ScaleControl.NauticalMiles")):ye>=1e3?gm(l,fe,ye/1e3,z._getUIString("ScaleControl.Kilometers")):gm(l,fe,ye,z._getUIString("ScaleControl.Meters"))}function gm(z,l,m,T){let P=function(V){let W=Math.pow(10,`${Math.floor(V)}`.length-1),te=V/W;return te=te>=10?10:te>=5?5:te>=3?3:te>=2?2:te>=1?1:function(se){let fe=Math.pow(10,Math.ceil(-Math.log(se)/Math.LN10));return Math.round(se*fe)/fe}(te),W*te}(m);z.style.width=l*(P/m)+"px",z.innerHTML=`${P} ${T}`}let P_={closeButton:!0,closeOnClick:!0,focusAfterOpen:!0,className:"",maxWidth:"240px",subpixelPositioning:!1,locationOccludedOpacity:void 0},R_=["a[href]","[tabindex]:not([tabindex='-1'])","[contenteditable]:not([contenteditable='false'])","button:not([disabled])","input:not([disabled])","select:not([disabled])","textarea:not([disabled])"].join(", ");function tA(z){if(z){if(typeof z=="number"){let l=Math.round(Math.abs(z)/Math.SQRT2);return{center:new o.P(0,0),top:new o.P(0,z),"top-left":new o.P(l,l),"top-right":new o.P(-l,l),bottom:new o.P(0,-z),"bottom-left":new o.P(l,-l),"bottom-right":new o.P(-l,-l),left:new o.P(z,0),right:new o.P(-z,0)}}if(z instanceof o.P||Array.isArray(z)){let l=o.P.convert(z);return{center:l,top:l,"top-left":l,"top-right":l,bottom:l,"bottom-left":l,"bottom-right":l,left:l,right:l}}return{center:o.P.convert(z.center||[0,0]),top:o.P.convert(z.top||[0,0]),"top-left":o.P.convert(z["top-left"]||[0,0]),"top-right":o.P.convert(z["top-right"]||[0,0]),bottom:o.P.convert(z.bottom||[0,0]),"bottom-left":o.P.convert(z["bottom-left"]||[0,0]),"bottom-right":o.P.convert(z["bottom-right"]||[0,0]),left:o.P.convert(z.left||[0,0]),right:o.P.convert(z.right||[0,0])}}return tA(new o.P(0,0))}let r0=s;n.AJAXError=o.cJ,n.Event=o.l,n.Evented=o.E,n.LngLat=o.V,n.MercatorCoordinate=o.ab,n.Point=o.P,n.addProtocol=o.cK,n.config=o.c,n.removeProtocol=o.cL,n.AttributionControl=Ou,n.BoxZoomHandler=Pt,n.CanvasSource=Fe,n.CooperativeGesturesHandler=jc,n.DoubleClickZoomHandler=cl,n.DragPanHandler=tn,n.DragRotateHandler=_n,n.EdgeInsets=Pu,n.FullscreenControl=class extends o.E{constructor(z={}){super(),this._onFullscreenChange=()=>{var l;let m=window.document.fullscreenElement||window.document.mozFullScreenElement||window.document.webkitFullscreenElement||window.document.msFullscreenElement;for(;!((l=m?.shadowRoot)===null||l===void 0)&&l.fullscreenElement;)m=m.shadowRoot.fullscreenElement;m===this._container!==this._fullscreen&&this._handleFullscreenChange()},this._onClickFullscreen=()=>{this._isFullscreen()?this._exitFullscreen():this._requestFullscreen()},this._fullscreen=!1,z&&z.container&&(z.container instanceof HTMLElement?this._container=z.container:o.w("Full screen control 'container' must be a DOM element.")),"onfullscreenchange"in document?this._fullscreenchange="fullscreenchange":"onmozfullscreenchange"in document?this._fullscreenchange="mozfullscreenchange":"onwebkitfullscreenchange"in document?this._fullscreenchange="webkitfullscreenchange":"onmsfullscreenchange"in document&&(this._fullscreenchange="MSFullscreenChange")}onAdd(z){return this._map=z,this._container||(this._container=this._map.getContainer()),this._controlContainer=U.create("div","maplibregl-ctrl maplibregl-ctrl-group"),this._setupUI(),this._controlContainer}onRemove(){U.remove(this._controlContainer),this._map=null,window.document.removeEventListener(this._fullscreenchange,this._onFullscreenChange)}_setupUI(){let z=this._fullscreenButton=U.create("button","maplibregl-ctrl-fullscreen",this._controlContainer);U.create("span","maplibregl-ctrl-icon",z).setAttribute("aria-hidden","true"),z.type="button",this._updateTitle(),this._fullscreenButton.addEventListener("click",this._onClickFullscreen),window.document.addEventListener(this._fullscreenchange,this._onFullscreenChange)}_updateTitle(){let z=this._getTitle();this._fullscreenButton.setAttribute("aria-label",z),this._fullscreenButton.title=z}_getTitle(){return this._map._getUIString(this._isFullscreen()?"FullscreenControl.Exit":"FullscreenControl.Enter")}_isFullscreen(){return this._fullscreen}_handleFullscreenChange(){this._fullscreen=!this._fullscreen,this._fullscreenButton.classList.toggle("maplibregl-ctrl-shrink"),this._fullscreenButton.classList.toggle("maplibregl-ctrl-fullscreen"),this._updateTitle(),this._fullscreen?(this.fire(new o.l("fullscreenstart")),this._prevCooperativeGesturesEnabled=this._map.cooperativeGestures.isEnabled(),this._map.cooperativeGestures.disable()):(this.fire(new o.l("fullscreenend")),this._prevCooperativeGesturesEnabled&&this._map.cooperativeGestures.enable())}_exitFullscreen(){window.document.exitFullscreen?window.document.exitFullscreen():window.document.mozCancelFullScreen?window.document.mozCancelFullScreen():window.document.msExitFullscreen?window.document.msExitFullscreen():window.document.webkitCancelFullScreen?window.document.webkitCancelFullScreen():this._togglePseudoFullScreen()}_requestFullscreen(){this._container.requestFullscreen?this._container.requestFullscreen():this._container.mozRequestFullScreen?this._container.mozRequestFullScreen():this._container.msRequestFullscreen?this._container.msRequestFullscreen():this._container.webkitRequestFullscreen?this._container.webkitRequestFullscreen():this._togglePseudoFullScreen()}_togglePseudoFullScreen(){this._container.classList.toggle("maplibregl-pseudo-fullscreen"),this._handleFullscreenChange(),this._map.resize()}},n.GeoJSONSource=ps,n.GeolocateControl=class extends o.E{constructor(z){super(),this._onSuccess=l=>{if(this._map){if(this._isOutOfMapMaxBounds(l))return this._setErrorState(),this.fire(new o.l("outofmaxbounds",l)),this._updateMarker(),void this._finish();if(this.options.trackUserLocation)switch(this._lastKnownPosition=l,this._watchState){case"WAITING_ACTIVE":case"ACTIVE_LOCK":case"ACTIVE_ERROR":this._watchState="ACTIVE_LOCK",this._geolocateButton.classList.remove("maplibregl-ctrl-geolocate-waiting"),this._geolocateButton.classList.remove("maplibregl-ctrl-geolocate-active-error"),this._geolocateButton.classList.add("maplibregl-ctrl-geolocate-active");break;case"BACKGROUND":case"BACKGROUND_ERROR":this._watchState="BACKGROUND",this._geolocateButton.classList.remove("maplibregl-ctrl-geolocate-waiting"),this._geolocateButton.classList.remove("maplibregl-ctrl-geolocate-background-error"),this._geolocateButton.classList.add("maplibregl-ctrl-geolocate-background");break;default:throw new Error(`Unexpected watchState ${this._watchState}`)}this.options.showUserLocation&&this._watchState!=="OFF"&&this._updateMarker(l),this.options.trackUserLocation&&this._watchState!=="ACTIVE_LOCK"||this._updateCamera(l),this.options.showUserLocation&&this._dotElement.classList.remove("maplibregl-user-location-dot-stale"),this.fire(new o.l("geolocate",l)),this._finish()}},this._updateCamera=l=>{let m=new o.V(l.coords.longitude,l.coords.latitude),T=l.coords.accuracy,P=this._map.getBearing(),V=o.e({bearing:P},this.options.fitBoundsOptions),W=Ho.fromLngLat(m,T);this._map.fitBounds(W,V,{geolocateSource:!0})},this._updateMarker=l=>{if(l){let m=new o.V(l.coords.longitude,l.coords.latitude);this._accuracyCircleMarker.setLngLat(m).addTo(this._map),this._userLocationDotMarker.setLngLat(m).addTo(this._map),this._accuracy=l.coords.accuracy,this._updateCircleRadiusIfNeeded()}else this._userLocationDotMarker.remove(),this._accuracyCircleMarker.remove()},this._onUpdate=()=>{this._updateCircleRadiusIfNeeded()},this._onError=l=>{if(this._map){if(l.code===1){this._watchState="OFF",this._geolocateButton.classList.remove("maplibregl-ctrl-geolocate-waiting"),this._geolocateButton.classList.remove("maplibregl-ctrl-geolocate-active"),this._geolocateButton.classList.remove("maplibregl-ctrl-geolocate-active-error"),this._geolocateButton.classList.remove("maplibregl-ctrl-geolocate-background"),this._geolocateButton.classList.remove("maplibregl-ctrl-geolocate-background-error"),this._geolocateButton.disabled=!0;let m=this._map._getUIString("GeolocateControl.LocationNotAvailable");this._geolocateButton.title=m,this._geolocateButton.setAttribute("aria-label",m),this._geolocationWatchID!==void 0&&this._clearWatch()}else{if(l.code===3&&Vl)return;this._setErrorState()}this._watchState!=="OFF"&&this.options.showUserLocation&&this._dotElement.classList.add("maplibregl-user-location-dot-stale"),this.fire(new o.l("error",l)),this._finish()}},this._finish=()=>{this._timeoutId&&clearTimeout(this._timeoutId),this._timeoutId=void 0},this._setupUI=()=>{this._map&&(this._container.addEventListener("contextmenu",l=>l.preventDefault()),this._geolocateButton=U.create("button","maplibregl-ctrl-geolocate",this._container),U.create("span","maplibregl-ctrl-icon",this._geolocateButton).setAttribute("aria-hidden","true"),this._geolocateButton.type="button",this._geolocateButton.disabled=!0)},this._finishSetupUI=l=>{if(this._map){if(l===!1){o.w("Geolocation support is not available so the GeolocateControl will be disabled.");let m=this._map._getUIString("GeolocateControl.LocationNotAvailable");this._geolocateButton.disabled=!0,this._geolocateButton.title=m,this._geolocateButton.setAttribute("aria-label",m)}else{let m=this._map._getUIString("GeolocateControl.FindMyLocation");this._geolocateButton.disabled=!1,this._geolocateButton.title=m,this._geolocateButton.setAttribute("aria-label",m)}this.options.trackUserLocation&&(this._geolocateButton.setAttribute("aria-pressed","false"),this._watchState="OFF"),this.options.showUserLocation&&(this._dotElement=U.create("div","maplibregl-user-location-dot"),this._userLocationDotMarker=new Tf({element:this._dotElement}),this._circleElement=U.create("div","maplibregl-user-location-accuracy-circle"),this._accuracyCircleMarker=new Tf({element:this._circleElement,pitchAlignment:"map"}),this.options.trackUserLocation&&(this._watchState="OFF"),this._map.on("zoom",this._onUpdate),this._map.on("move",this._onUpdate),this._map.on("rotate",this._onUpdate),this._map.on("pitch",this._onUpdate)),this._geolocateButton.addEventListener("click",()=>this.trigger()),this._setup=!0,this.options.trackUserLocation&&this._map.on("movestart",m=>{let T=m?.[0]instanceof ResizeObserverEntry;m.geolocateSource||this._watchState!=="ACTIVE_LOCK"||T||this._map.isZooming()||(this._watchState="BACKGROUND",this._geolocateButton.classList.add("maplibregl-ctrl-geolocate-background"),this._geolocateButton.classList.remove("maplibregl-ctrl-geolocate-active"),this.fire(new o.l("trackuserlocationend")),this.fire(new o.l("userlocationlostfocus")))})}},this.options=o.e({},og,z)}onAdd(z){return this._map=z,this._container=U.create("div","maplibregl-ctrl maplibregl-ctrl-group"),this._setupUI(),function(){return o._(this,arguments,void 0,function*(l=!1){if(th!==void 0&&!l)return th;if(window.navigator.permissions===void 0)return th=!!window.navigator.geolocation,th;try{th=(yield window.navigator.permissions.query({name:"geolocation"})).state!=="denied"}catch{th=!!window.navigator.geolocation}return th})}().then(l=>this._finishSetupUI(l)),this._container}onRemove(){this._geolocationWatchID!==void 0&&(window.navigator.geolocation.clearWatch(this._geolocationWatchID),this._geolocationWatchID=void 0),this.options.showUserLocation&&this._userLocationDotMarker&&this._userLocationDotMarker.remove(),this.options.showAccuracyCircle&&this._accuracyCircleMarker&&this._accuracyCircleMarker.remove(),U.remove(this._container),this._map.off("zoom",this._onUpdate),this._map.off("move",this._onUpdate),this._map.off("rotate",this._onUpdate),this._map.off("pitch",this._onUpdate),this._map=void 0,Fu=0,Vl=!1}_isOutOfMapMaxBounds(z){let l=this._map.getMaxBounds(),m=z.coords;return l&&(m.longitudel.getEast()||m.latitudel.getNorth())}_setErrorState(){switch(this._watchState){case"WAITING_ACTIVE":this._watchState="ACTIVE_ERROR",this._geolocateButton.classList.remove("maplibregl-ctrl-geolocate-active"),this._geolocateButton.classList.add("maplibregl-ctrl-geolocate-active-error");break;case"ACTIVE_LOCK":this._watchState="ACTIVE_ERROR",this._geolocateButton.classList.remove("maplibregl-ctrl-geolocate-active"),this._geolocateButton.classList.add("maplibregl-ctrl-geolocate-active-error"),this._geolocateButton.classList.add("maplibregl-ctrl-geolocate-waiting");break;case"BACKGROUND":this._watchState="BACKGROUND_ERROR",this._geolocateButton.classList.remove("maplibregl-ctrl-geolocate-background"),this._geolocateButton.classList.add("maplibregl-ctrl-geolocate-background-error"),this._geolocateButton.classList.add("maplibregl-ctrl-geolocate-waiting");break;case"ACTIVE_ERROR":case"BACKGROUND_ERROR":case"OFF":case void 0:break;default:throw new Error(`Unexpected watchState ${this._watchState}`)}}_updateCircleRadiusIfNeeded(){let z=this._userLocationDotMarker.getLngLat();if(!(this.options.showUserLocation&&this.options.showAccuracyCircle&&this._accuracy&&z))return;let l=this._map.project(z),m=this._map.unproject([l.x+100,l.y]),T=z.distanceTo(m)/100,P=2*this._accuracy/T;this._circleElement.style.width=`${P.toFixed(2)}px`,this._circleElement.style.height=`${P.toFixed(2)}px`}trigger(){if(!this._setup)return o.w("Geolocate control triggered before added to a map"),!1;if(this.options.trackUserLocation){switch(this._watchState){case"OFF":this._watchState="WAITING_ACTIVE",this.fire(new o.l("trackuserlocationstart"));break;case"WAITING_ACTIVE":case"ACTIVE_LOCK":case"ACTIVE_ERROR":case"BACKGROUND_ERROR":Fu--,Vl=!1,this._watchState="OFF",this._geolocateButton.classList.remove("maplibregl-ctrl-geolocate-waiting"),this._geolocateButton.classList.remove("maplibregl-ctrl-geolocate-active"),this._geolocateButton.classList.remove("maplibregl-ctrl-geolocate-active-error"),this._geolocateButton.classList.remove("maplibregl-ctrl-geolocate-background"),this._geolocateButton.classList.remove("maplibregl-ctrl-geolocate-background-error"),this.fire(new o.l("trackuserlocationend"));break;case"BACKGROUND":this._watchState="ACTIVE_LOCK",this._geolocateButton.classList.remove("maplibregl-ctrl-geolocate-background"),this._lastKnownPosition&&this._updateCamera(this._lastKnownPosition),this.fire(new o.l("trackuserlocationstart")),this.fire(new o.l("userlocationfocus"));break;default:throw new Error(`Unexpected watchState ${this._watchState}`)}switch(this._watchState){case"WAITING_ACTIVE":this._geolocateButton.classList.add("maplibregl-ctrl-geolocate-waiting"),this._geolocateButton.classList.add("maplibregl-ctrl-geolocate-active");break;case"ACTIVE_LOCK":this._geolocateButton.classList.add("maplibregl-ctrl-geolocate-active");break;case"OFF":break;default:throw new Error(`Unexpected watchState ${this._watchState}`)}if(this._watchState==="OFF"&&this._geolocationWatchID!==void 0)this._clearWatch();else if(this._geolocationWatchID===void 0){let z;this._geolocateButton.classList.add("maplibregl-ctrl-geolocate-waiting"),this._geolocateButton.setAttribute("aria-pressed","true"),Fu++,Fu>1?(z={maximumAge:6e5,timeout:0},Vl=!0):(z=this.options.positionOptions,Vl=!1),this._geolocationWatchID=window.navigator.geolocation.watchPosition(this._onSuccess,this._onError,z)}}else window.navigator.geolocation.getCurrentPosition(this._onSuccess,this._onError,this.options.positionOptions),this._timeoutId=setTimeout(this._finish,1e4);return!0}_clearWatch(){window.navigator.geolocation.clearWatch(this._geolocationWatchID),this._geolocationWatchID=void 0,this._geolocateButton.classList.remove("maplibregl-ctrl-geolocate-waiting"),this._geolocateButton.setAttribute("aria-pressed","false"),this.options.showUserLocation&&this._updateMarker(null)}},n.GlobeControl=class{constructor(){this._toggleProjection=()=>{var z;let l=(z=this._map.getProjection())===null||z===void 0?void 0:z.type;this._map.setProjection(l!=="mercator"&&l?{type:"mercator"}:{type:"globe"}),this._updateGlobeIcon()},this._updateGlobeIcon=()=>{var z;this._globeButton.classList.remove("maplibregl-ctrl-globe"),this._globeButton.classList.remove("maplibregl-ctrl-globe-enabled"),((z=this._map.getProjection())===null||z===void 0?void 0:z.type)==="globe"?(this._globeButton.classList.add("maplibregl-ctrl-globe-enabled"),this._globeButton.title=this._map._getUIString("GlobeControl.Disable")):(this._globeButton.classList.add("maplibregl-ctrl-globe"),this._globeButton.title=this._map._getUIString("GlobeControl.Enable"))}}onAdd(z){return this._map=z,this._container=U.create("div","maplibregl-ctrl maplibregl-ctrl-group"),this._globeButton=U.create("button","maplibregl-ctrl-globe",this._container),U.create("span","maplibregl-ctrl-icon",this._globeButton).setAttribute("aria-hidden","true"),this._globeButton.type="button",this._globeButton.addEventListener("click",this._toggleProjection),this._updateGlobeIcon(),this._map.on("styledata",this._updateGlobeIcon),this._container}onRemove(){U.remove(this._container),this._map.off("styledata",this._updateGlobeIcon),this._globeButton.removeEventListener("click",this._toggleProjection),this._map=void 0}},n.Hash=Yf,n.ImageSource=ws,n.KeyboardHandler=Dn,n.LngLatBounds=Ho,n.LogoControl=iu,n.Map=class extends wd{constructor(z){var l,m;o.cH.mark(o.cI.create);let T=Object.assign(Object.assign(Object.assign({},ef),z),{canvasContextAttributes:Object.assign(Object.assign({},ef.canvasContextAttributes),z.canvasContextAttributes)});if(T.minZoom!=null&&T.maxZoom!=null&&T.minZoom>T.maxZoom)throw new Error("maxZoom must be greater than or equal to minZoom");if(T.minPitch!=null&&T.maxPitch!=null&&T.minPitch>T.maxPitch)throw new Error("maxPitch must be greater than or equal to minPitch");if(T.minPitch!=null&&T.minPitch<0)throw new Error("minPitch must be greater than or equal to 0");if(T.maxPitch!=null&&T.maxPitch>180)throw new Error("maxPitch must be less than or equal to 180");let P=new Gf,V=new Af;if(T.minZoom!==void 0&&P.setMinZoom(T.minZoom),T.maxZoom!==void 0&&P.setMaxZoom(T.maxZoom),T.minPitch!==void 0&&P.setMinPitch(T.minPitch),T.maxPitch!==void 0&&P.setMaxPitch(T.maxPitch),T.renderWorldCopies!==void 0&&P.setRenderWorldCopies(T.renderWorldCopies),T.transformConstrain!==null&&P.setConstrainOverride(T.transformConstrain),super(P,V,{bearingSnap:T.bearingSnap}),this._idleTriggered=!1,this._crossFadingFactor=1,this._renderTaskQueue=new Sa,this._controls=[],this._mapId=o.ah(),this._lostContextStyle={style:null,images:null},this._contextLost=te=>{te.preventDefault(),this._frameRequest&&(this._frameRequest.abort(),this._frameRequest=null),this.painter.destroy();for(let se of Object.values(this.style._layers))if(se.type==="custom"&&console.warn(`Custom layer with id '${se.id}' cannot be restored after WebGL context loss. You will need to re-add it manually after context restoration.`),se._listeners)for(let[fe]of Object.entries(se._listeners))console.warn(`Custom layer with id '${se.id}' had event listeners for event '${fe}' which cannot be restored after WebGL context loss. You will need to re-add them manually after context restoration.`);this._lostContextStyle=this._getStyleAndImages(),this.style.destroy(),this.style=null,this.fire(new o.l("webglcontextlost",{originalEvent:te}))},this._contextRestored=te=>{this._lostContextStyle.style&&this.setStyle(this._lostContextStyle.style,{diff:!1}),this._lostContextStyle.images&&(this.style.imageManager.images=this._lostContextStyle.images),this._setupPainter(),this.resize(),this._update(),this.fire(new o.l("webglcontextrestored",{originalEvent:te}))},this._onMapScroll=te=>{if(te.target===this._container)return this._container.scrollTop=0,this._container.scrollLeft=0,!1},this._onWindowOnline=()=>{this._update()},this._interactive=T.interactive,this._maxTileCacheSize=T.maxTileCacheSize,this._maxTileCacheZoomLevels=T.maxTileCacheZoomLevels,this._canvasContextAttributes=Object.assign({},T.canvasContextAttributes),this._trackResize=T.trackResize===!0,this._bearingSnap=T.bearingSnap,this._centerClampedToGround=T.centerClampedToGround,this._refreshExpiredTiles=T.refreshExpiredTiles===!0,this._fadeDuration=T.fadeDuration,this._crossSourceCollisions=T.crossSourceCollisions===!0,this._collectResourceTiming=T.collectResourceTiming===!0,this._locale=Object.assign(Object.assign({},yu),T.locale),this._clickTolerance=T.clickTolerance,this._overridePixelRatio=T.pixelRatio,this._maxCanvasSize=T.maxCanvasSize,this._zoomLevelsToOverscale=T.experimentalZoomLevelsToOverscale,this.transformCameraUpdate=T.transformCameraUpdate,this.transformConstrain=T.transformConstrain,this.cancelPendingTileRequestsWhileZooming=T.cancelPendingTileRequestsWhileZooming===!0,T.reduceMotion!==void 0&&(I.prefersReducedMotion=T.reduceMotion),this._imageQueueHandle=Oe.addThrottleControl(()=>this.isMoving()),this._requestManager=new ne(T.transformRequest),typeof T.container=="string"){if(this._container=document.getElementById(T.container),!this._container)throw new Error(`Container '${T.container}' not found.`)}else{if(!(T.container instanceof HTMLElement))throw new Error("Invalid type: 'container' must be a String or HTMLElement.");this._container=T.container}if(T.maxBounds&&this.setMaxBounds(T.maxBounds),this._setupContainer(),this._setupPainter(),this.on("move",()=>this._update(!1)),this.on("moveend",()=>this._update(!1)),this.on("zoom",()=>this._update(!0)),this.on("terrain",()=>{this.painter.terrainFacilitator.dirty=!0,this._update(!0)}),this.once("idle",()=>{this._idleTriggered=!0}),typeof window<"u"){addEventListener("online",this._onWindowOnline,!1);let te=!1,se=Kd(fe=>{this._trackResize&&!this._removed&&(this.resize(fe),this.redraw())},50);this._resizeObserver=new ResizeObserver(fe=>{te?se(fe):te=!0}),this._resizeObserver.observe(this._container)}this.handlers=new bd(this,T),this._hash=T.hash&&new Yf(typeof T.hash=="string"&&T.hash||void 0).addTo(this),this._hash&&this._hash._onHashChange()||(this.jumpTo({center:T.center,elevation:T.elevation,zoom:T.zoom,bearing:T.bearing,pitch:T.pitch,roll:T.roll}),T.bounds&&(this.resize(),this.fitBounds(T.bounds,o.e({},T.fitBoundsOptions,{duration:0}))));let W=typeof T.style=="string"||((m=(l=T.style)===null||l===void 0?void 0:l.projection)===null||m===void 0?void 0:m.type)!=="globe";this.resize(null,W),this._localIdeographFontFamily=T.localIdeographFontFamily,this._validateStyle=T.validateStyle,T.style&&this.setStyle(T.style,{localIdeographFontFamily:T.localIdeographFontFamily}),T.attributionControl&&this.addControl(new Ou(typeof T.attributionControl=="boolean"?void 0:T.attributionControl)),T.maplibreLogo&&this.addControl(new iu,T.logoPosition),this.on("style.load",()=>{if(W||this._resizeTransform(),this.transform.unmodified){let te=o.U(this.style.stylesheet,["center","zoom","bearing","pitch","roll"]);this.jumpTo(te)}}),this.on("data",te=>{this._update(te.dataType==="style"),this.fire(new o.l(`${te.dataType}data`,te))}),this.on("dataloading",te=>{this.fire(new o.l(`${te.dataType}dataloading`,te))}),this.on("dataabort",te=>{this.fire(new o.l("sourcedataabort",te))})}_getMapId(){return this._mapId}setGlobalStateProperty(z,l){return this.style.setGlobalStateProperty(z,l),this._update(!0)}getGlobalState(){return this.style.getGlobalState()}addControl(z,l){if(l===void 0&&(l=z.getDefaultPosition?z.getDefaultPosition():"top-right"),!z||!z.onAdd)return this.fire(new o.k(new Error("Invalid argument to map.addControl(). Argument must be a control with onAdd and onRemove methods.")));let m=z.onAdd(this);this._controls.push(z);let T=this._controlPositions[l];return l.indexOf("bottom")!==-1?T.insertBefore(m,T.firstChild):T.appendChild(m),this}removeControl(z){if(!z||!z.onRemove)return this.fire(new o.k(new Error("Invalid argument to map.removeControl(). Argument must be a control with onAdd and onRemove methods.")));let l=this._controls.indexOf(z);return l>-1&&this._controls.splice(l,1),z.onRemove(this),this}hasControl(z){return this._controls.indexOf(z)>-1}coveringTiles(z){return Qe(this.transform,z)}calculateCameraOptionsFromTo(z,l,m,T){return T==null&&this.terrain&&(T=this.terrain.getElevationForLngLat(m)),super.calculateCameraOptionsFromTo(z,l,m,T)}resize(z,l=!0){let[m,T]=this._containerDimensions(),P=this._getClampedPixelRatio(m,T);if(this._resizeCanvas(m,T,P),this.painter.resize(m,T,P),this.painter.overLimit()){let W=this.painter.context.gl;this._maxCanvasSize=[W.drawingBufferWidth,W.drawingBufferHeight];let te=this._getClampedPixelRatio(m,T);this._resizeCanvas(m,T,te),this.painter.resize(m,T,te)}this._resizeTransform(l);let V=!this._moving;return V&&(this.stop(),this.fire(new o.l("movestart",z)).fire(new o.l("move",z))),this.fire(new o.l("resize",z)),V&&this.fire(new o.l("moveend",z)),this}_resizeTransform(z=!0){var l;let[m,T]=this._containerDimensions();this.transform.resize(m,T,z),(l=this._requestedCameraState)===null||l===void 0||l.resize(m,T,z)}_getClampedPixelRatio(z,l){let{0:m,1:T}=this._maxCanvasSize,P=this.getPixelRatio(),V=z*P,W=l*P;return Math.min(V>m?m/V:1,W>T?T/W:1)*P}getPixelRatio(){var z;return(z=this._overridePixelRatio)!==null&&z!==void 0?z:devicePixelRatio}setPixelRatio(z){this._overridePixelRatio=z,this.resize()}getBounds(){return this.transform.getBounds()}getMaxBounds(){return this.transform.getMaxBounds()}setMaxBounds(z){return this.transform.setMaxBounds(Ho.convert(z)),this._update()}setMinZoom(z){if((z=z??-2)>=-2&&z<=this.transform.maxZoom)return this.transform.setMinZoom(z),this._update(),this.getZoom()=this.transform.minZoom)return this.transform.setMaxZoom(z),this._update(),this.getZoom()>z&&this.setZoom(z),this;throw new Error("maxZoom must be greater than the current minZoom")}getMaxZoom(){return this.transform.maxZoom}setMinPitch(z){if((z=z??0)<0)throw new Error("minPitch must be greater than or equal to 0");if(z>=0&&z<=this.transform.maxPitch)return this.transform.setMinPitch(z),this._update(),this.getPitch()180)throw new Error("maxPitch must be less than or equal to 180");if(z>=this.transform.minPitch)return this.transform.setMaxPitch(z),this._update(),this.getPitch()>z&&this.setPitch(z),this;throw new Error("maxPitch must be greater than the current minPitch")}getMaxPitch(){return this.transform.maxPitch}getRenderWorldCopies(){return this.transform.renderWorldCopies}setRenderWorldCopies(z){return this.transform.setRenderWorldCopies(z),this._update()}setTransformConstrain(z){return this.transform.setConstrainOverride(z),this._update()}project(z){return this.transform.locationToScreenPoint(o.V.convert(z),this.style&&this.terrain)}unproject(z){return this.transform.screenPointToLocation(o.P.convert(z),this.terrain)}isMoving(){var z;return this._moving||((z=this.handlers)===null||z===void 0?void 0:z.isMoving())}isZooming(){var z;return this._zooming||((z=this.handlers)===null||z===void 0?void 0:z.isZooming())}isRotating(){var z;return this._rotating||((z=this.handlers)===null||z===void 0?void 0:z.isRotating())}_createDelegatedListener(z,l,m){if(z==="mouseenter"||z==="mouseover"){let T=!1;return{layers:l,listener:m,delegates:{mousemove:V=>{let W=l.filter(se=>this.getLayer(se)),te=W.length!==0?this.queryRenderedFeatures(V.point,{layers:W}):[];te.length?T||(T=!0,m.call(this,new Pe(z,this,V.originalEvent,{features:te}))):T=!1},mouseout:()=>{T=!1}}}}if(z==="mouseleave"||z==="mouseout"){let T=!1;return{layers:l,listener:m,delegates:{mousemove:W=>{let te=l.filter(se=>this.getLayer(se));(te.length!==0?this.queryRenderedFeatures(W.point,{layers:te}):[]).length?T=!0:T&&(T=!1,m.call(this,new Pe(z,this,W.originalEvent)))},mouseout:W=>{T&&(T=!1,m.call(this,new Pe(z,this,W.originalEvent)))}}}}{let T=P=>{let V=l.filter(te=>this.getLayer(te)),W=V.length!==0?this.queryRenderedFeatures(P.point,{layers:V}):[];W.length&&(P.features=W,m.call(this,P),delete P.features)};return{layers:l,listener:m,delegates:{[z]:T}}}}_saveDelegatedListener(z,l){this._delegatedListeners=this._delegatedListeners||{},this._delegatedListeners[z]=this._delegatedListeners[z]||[],this._delegatedListeners[z].push(l)}_removeDelegatedListener(z,l,m){if(!this._delegatedListeners||!this._delegatedListeners[z])return;let T=this._delegatedListeners[z];for(let P=0;Pl.includes(W))){for(let W in V.delegates)this.off(W,V.delegates[W]);return void T.splice(P,1)}}}on(z,l,m){if(m===void 0)return super.on(z,l);let T=typeof l=="string"?[l]:l,P=this._createDelegatedListener(z,T,m);this._saveDelegatedListener(z,P);for(let V in P.delegates)this.on(V,P.delegates[V]);return{unsubscribe:()=>{this._removeDelegatedListener(z,T,m)}}}once(z,l,m){if(m===void 0)return super.once(z,l);let T=typeof l=="string"?[l]:l,P=this._createDelegatedListener(z,T,m);for(let V in P.delegates){let W=P.delegates[V];P.delegates[V]=(...te)=>{this._removeDelegatedListener(z,T,m),W(...te)}}this._saveDelegatedListener(z,P);for(let V in P.delegates)this.once(V,P.delegates[V]);return this}off(z,l,m){return m===void 0?super.off(z,l):(this._removeDelegatedListener(z,typeof l=="string"?[l]:l,m),this)}queryRenderedFeatures(z,l){if(!this.style)return[];let m,T=z instanceof o.P||Array.isArray(z),P=T?z:[[0,0],[this.transform.width,this.transform.height]];if(l=l||(T?{}:z)||{},P instanceof o.P||typeof P[0]=="number")m=[o.P.convert(P)];else{let V=o.P.convert(P[0]),W=o.P.convert(P[1]);m=[V,new o.P(W.x,V.y),W,new o.P(V.x,W.y),V]}return this.style.queryRenderedFeatures(m,l,this.transform)}querySourceFeatures(z,l){return this.style.querySourceFeatures(z,l)}setStyle(z,l){return(l=o.e({},{localIdeographFontFamily:this._localIdeographFontFamily,validate:this._validateStyle},l)).diff!==!1&&l.localIdeographFontFamily===this._localIdeographFontFamily&&this.style&&z?(this._diffStyle(z,l),this):(this._localIdeographFontFamily=l.localIdeographFontFamily,this._updateStyle(z,l))}setTransformRequest(z){return this._requestManager.setTransformRequest(z),this}_getUIString(z){let l=this._locale[z];if(l==null)throw new Error(`Missing UI string '${z}'`);return l}_updateStyle(z,l){var m,T;if(l.transformStyle&&this.style&&!this.style._loaded)return void this.style.once("style.load",()=>this._updateStyle(z,l));let P=this.style&&l.transformStyle?this.style.serialize():void 0;return this.style&&(this.style.setEventedParent(null),this.style._remove(!z)),z?(this.style=new Ms(this,l||{}),this.style.setEventedParent(this,{style:this.style}),typeof z=="string"?this.style.loadURL(z,l,P):this.style.loadJSON(z,l,P),this):((T=(m=this.style)===null||m===void 0?void 0:m.projection)===null||T===void 0||T.destroy(),delete this.style,this)}_lazyInitEmptyStyle(){this.style||(this.style=new Ms(this,{}),this.style.setEventedParent(this,{style:this.style}),this.style.loadEmpty())}_diffStyle(z,l){if(typeof z=="string"){let m=this._requestManager.transformRequest(z,"Style");o.j(m,new AbortController).then(T=>{this._updateDiff(T.data,l)}).catch(T=>{T&&this.fire(new o.k(T))})}else typeof z=="object"&&this._updateDiff(z,l)}_updateDiff(z,l){try{this.style.setState(z,l)&&this._update(!0)}catch(m){o.w(`Unable to perform style diff: ${m.message||m.error||m}. Rebuilding the style from scratch.`),this._updateStyle(z,l)}}getStyle(){if(this.style)return this.style.serialize()}_getStyleAndImages(){return this.style?{style:this.style.serialize(),images:this.style.imageManager.cloneImages()}:{style:null,images:{}}}isStyleLoaded(){return this.style?this.style.loaded():o.w("There is no style added to the map.")}addSource(z,l){return this._lazyInitEmptyStyle(),this.style.addSource(z,l),this._update(!0)}isSourceLoaded(z){let l=this.style&&this.style.tileManagers[z];if(l!==void 0)return l.loaded();this.fire(new o.k(new Error(`There is no tile manager with ID '${z}'`)))}setTerrain(z){if(this.style._checkLoaded(),this._terrainDataCallback&&this.style.off("data",this._terrainDataCallback),z){let l=this.style.tileManagers[z.source];if(!l)throw new Error(`cannot load terrain, because there exists no source with ID: ${z.source}`);this.terrain===null&&l.reload();for(let m in this.style._layers){let T=this.style._layers[m];T.type==="hillshade"&&T.source===z.source&&o.w("You are using the same source for a hillshade layer and for 3D terrain. Please consider using two separate sources to improve rendering quality."),T.type==="color-relief"&&T.source===z.source&&o.w("You are using the same source for a color-relief layer and for 3D terrain. Please consider using two separate sources to improve rendering quality.")}this.terrain=new eh(this.painter,l,z),this.painter.renderToTexture=new _s(this.painter,this.terrain),this.transform.setMinElevationForCurrentTile(this.terrain.getMinTileElevationForLngLatZoom(this.transform.center,this.transform.tileZoom)),this.transform.setElevation(this.terrain.getElevationForLngLatZoom(this.transform.center,this.transform.tileZoom)),this._terrainDataCallback=m=>{var T;m.dataType==="style"?this.terrain.tileManager.freeRtt():m.dataType==="source"&&m.tile&&(m.sourceId!==z.source||this._elevationFreeze||(this.transform.setMinElevationForCurrentTile(this.terrain.getMinTileElevationForLngLatZoom(this.transform.center,this.transform.tileZoom)),this._centerClampedToGround&&this.transform.setElevation(this.terrain.getElevationForLngLatZoom(this.transform.center,this.transform.tileZoom))),((T=m.source)===null||T===void 0?void 0:T.type)==="image"?this.terrain.tileManager.freeRtt():this.terrain.tileManager.freeRtt(m.tile.tileID))},this.style.on("data",this._terrainDataCallback)}else this.terrain&&this.terrain.tileManager.destruct(),this.terrain=null,this.painter.renderToTexture&&this.painter.renderToTexture.destruct(),this.painter.renderToTexture=null,this.transform.setMinElevationForCurrentTile(0),this._centerClampedToGround&&this.transform.setElevation(0);return this.fire(new o.l("terrain",{terrain:z})),this}getTerrain(){var z,l;return(l=(z=this.terrain)===null||z===void 0?void 0:z.options)!==null&&l!==void 0?l:null}areTilesLoaded(){let z=this.style&&this.style.tileManagers;for(let l of Object.values(z))if(!l.areTilesLoaded())return!1;return!0}removeSource(z){return this.style.removeSource(z),this._update(!0)}getSource(z){return this.style.getSource(z)}setSourceTileLodParams(z,l,m){if(m){let T=this.getSource(m);if(!T)throw new Error(`There is no source with ID "${m}", cannot set LOD parameters`);T.calculateTileZoom=$e(Math.max(1,z),Math.max(1,l))}else for(let T in this.style.tileManagers)this.style.tileManagers[T].getSource().calculateTileZoom=$e(Math.max(1,z),Math.max(1,l));return this._update(!0),this}refreshTiles(z,l){let m=this.style.tileManagers[z];if(!m)throw new Error(`There is no tile manager with ID "${z}", cannot refresh tile`);l===void 0?m.reload(!0):m.refreshTiles(l.map(T=>new o.ae(T.z,T.x,T.y)))}addImage(z,l,m={}){let{pixelRatio:T=1,sdf:P=!1,stretchX:V,stretchY:W,content:te,textFitWidth:se,textFitHeight:fe}=m;if(this._lazyInitEmptyStyle(),!(l instanceof HTMLImageElement||o.b(l))){if(l.width===void 0||l.height===void 0)return this.fire(new o.k(new Error("Invalid arguments to map.addImage(). The second argument must be an `HTMLImageElement`, `ImageData`, `ImageBitmap`, or object with `width`, `height`, and `data` properties with the same format as `ImageData`")));{let{width:ye,height:Re,data:Me}=l,je=l;return this.style.addImage(z,{data:new o.R({width:ye,height:Re},new Uint8Array(Me)),pixelRatio:T,stretchX:V,stretchY:W,content:te,textFitWidth:se,textFitHeight:fe,sdf:P,version:0,userImage:je}),je.onAdd&&je.onAdd(this,z),this}}{let{width:ye,height:Re,data:Me}=I.getImageData(l);this.style.addImage(z,{data:new o.R({width:ye,height:Re},Me),pixelRatio:T,stretchX:V,stretchY:W,content:te,textFitWidth:se,textFitHeight:fe,sdf:P,version:0})}}updateImage(z,l){let m=this.style.getImage(z);if(!m)return this.fire(new o.k(new Error("The map has no image with that id. If you are adding a new image use `map.addImage(...)` instead.")));let T=l instanceof HTMLImageElement||o.b(l)?I.getImageData(l):l,{width:P,height:V,data:W}=T;if(P===void 0||V===void 0)return this.fire(new o.k(new Error("Invalid arguments to map.updateImage(). The second argument must be an `HTMLImageElement`, `ImageData`, `ImageBitmap`, or object with `width`, `height`, and `data` properties with the same format as `ImageData`")));if(P!==m.data.width||V!==m.data.height)return this.fire(new o.k(new Error("The width and height of the updated image must be that same as the previous version of the image")));let te=!(l instanceof HTMLImageElement||o.b(l));return m.data.replace(W,te),this.style.updateImage(z,m),this}getImage(z){return this.style.getImage(z)}hasImage(z){return z?!!this.style.getImage(z):(this.fire(new o.k(new Error("Missing required image id"))),!1)}removeImage(z){this.style.removeImage(z)}loadImage(z){return Oe.getImage(this._requestManager.transformRequest(z,"Image"),new AbortController)}listImages(){return this.style.listImages()}addLayer(z,l){return this._lazyInitEmptyStyle(),this.style.addLayer(z,l),this._update(!0)}moveLayer(z,l){return this.style.moveLayer(z,l),this._update(!0)}removeLayer(z){return this.style.removeLayer(z),this._update(!0)}getLayer(z){return this.style.getLayer(z)}getLayersOrder(){return this.style.getLayersOrder()}setLayerZoomRange(z,l,m){return this.style.setLayerZoomRange(z,l,m),this._update(!0)}setFilter(z,l,m={}){return this.style.setFilter(z,l,m),this._update(!0)}getFilter(z){return this.style.getFilter(z)}setPaintProperty(z,l,m,T={}){return this.style.setPaintProperty(z,l,m,T),this._update(!0)}getPaintProperty(z,l){return this.style.getPaintProperty(z,l)}setLayoutProperty(z,l,m,T={}){return this.style.setLayoutProperty(z,l,m,T),this._update(!0)}getLayoutProperty(z,l){return this.style.getLayoutProperty(z,l)}setGlyphs(z,l={}){return this._lazyInitEmptyStyle(),this.style.setGlyphs(z,l),this._update(!0)}getGlyphs(){return this.style.getGlyphsUrl()}addSprite(z,l,m={}){return this._lazyInitEmptyStyle(),this.style.addSprite(z,l,m,T=>{T||this._update(!0)}),this}removeSprite(z){return this._lazyInitEmptyStyle(),this.style.removeSprite(z),this._update(!0)}getSprite(){return this.style.getSprite()}setSprite(z,l={}){return this._lazyInitEmptyStyle(),this.style.setSprite(z,l,m=>{m||this._update(!0)}),this}setLight(z,l={}){return this._lazyInitEmptyStyle(),this.style.setLight(z,l),this._update(!0)}getLight(){return this.style.getLight()}setSky(z,l={}){return this._lazyInitEmptyStyle(),this.style.setSky(z,l),this._update(!0)}getSky(){return this.style.getSky()}setFeatureState(z,l){return this.style.setFeatureState(z,l),this._update()}removeFeatureState(z,l){return this.style.removeFeatureState(z,l),this._update()}getFeatureState(z){return this.style.getFeatureState(z)}getContainer(){return this._container}getCanvasContainer(){return this._canvasContainer}getCanvas(){return this._canvas}_containerDimensions(){let z=0,l=0;return this._container&&(z=this._container.clientWidth||400,l=this._container.clientHeight||300),[z,l]}_setupContainer(){let z=this._container;z.classList.add("maplibregl-map");let l=this._canvasContainer=U.create("div","maplibregl-canvas-container",z);this._interactive&&l.classList.add("maplibregl-interactive"),this._canvas=U.create("canvas","maplibregl-canvas",l),this._canvas.addEventListener("webglcontextlost",this._contextLost,!1),this._canvas.addEventListener("webglcontextrestored",this._contextRestored,!1),this._canvas.setAttribute("tabindex",this._interactive?"0":"-1"),this._canvas.setAttribute("aria-label",this._getUIString("Map.Title")),this._canvas.setAttribute("role","region");let m=this._containerDimensions(),T=this._getClampedPixelRatio(m[0],m[1]);this._resizeCanvas(m[0],m[1],T);let P=this._controlContainer=U.create("div","maplibregl-control-container",z),V=this._controlPositions={};["top-left","top-right","bottom-left","bottom-right"].forEach(W=>{V[W]=U.create("div",`maplibregl-ctrl-${W} `,P)}),this._container.addEventListener("scroll",this._onMapScroll,!1)}_resizeCanvas(z,l,m){this._canvas.width=Math.floor(m*z),this._canvas.height=Math.floor(m*l),this._canvas.style.width=`${z}px`,this._canvas.style.height=`${l}px`}_setupPainter(){let z=Object.assign(Object.assign({},this._canvasContextAttributes),{alpha:!0,depth:!0,stencil:!0,premultipliedAlpha:!0}),l=null;this._canvas.addEventListener("webglcontextcreationerror",T=>{l={requestedAttributes:z},T&&(l.statusMessage=T.statusMessage,l.type=T.type)},{once:!0});let m=null;if(m=this._canvasContextAttributes.contextType?this._canvas.getContext(this._canvasContextAttributes.contextType,z):this._canvas.getContext("webgl2",z)||this._canvas.getContext("webgl",z),!m){let T="Failed to initialize WebGL";throw l?(l.message=T,new Error(JSON.stringify(l))):new Error(T)}this.painter=new Bp(m,this.transform),K.testSupport(m)}migrateProjection(z,l){super.migrateProjection(z,l),this.painter.transform=z,this.fire(new o.l("projectiontransition",{newProjection:this.style.projection.name}))}loaded(){return!this._styleDirty&&!this._sourcesDirty&&!!this.style&&this.style.loaded()}_update(z){return this.style&&this.style._loaded?(this._styleDirty=this._styleDirty||z,this._sourcesDirty=!0,this.triggerRepaint(),this):this}_requestRenderFrame(z){return this._update(),this._renderTaskQueue.add(z)}_cancelRenderFrame(z){this._renderTaskQueue.remove(z)}_render(z){var l,m,T,P,V;let W=this._idleTriggered?this._fadeDuration:0,te=((l=this.style.projection)===null||l===void 0?void 0:l.transitionState)>0;if(this.painter.context.setDirty(),this.painter.setBaseState(),this._renderTaskQueue.run(z),this._removed)return;let se=!1;if(this.style&&this._styleDirty){this._styleDirty=!1;let Re=this.transform.zoom,Me=k();this.style.zoomHistory.update(Re,Me);let je=new o.H(Re,{now:Me,fadeDuration:W,zoomHistory:this.style.zoomHistory,transition:this.style.getTransition()}),tt=je.crossFadingFactor();tt===1&&tt===this._crossFadingFactor||(se=!0,this._crossFadingFactor=tt),this.style.update(je)}let fe=((m=this.style.projection)===null||m===void 0?void 0:m.transitionState)>0!==te;(T=this.style.projection)===null||T===void 0||T.setErrorQueryLatitudeDegrees(this.transform.center.lat),this.transform.setTransitionState((P=this.style.projection)===null||P===void 0?void 0:P.transitionState,(V=this.style.projection)===null||V===void 0?void 0:V.latitudeErrorCorrectionRadians),this.style&&(this._sourcesDirty||fe)&&(this._sourcesDirty=!1,this.style._updateSources(this.transform)),this.terrain?(this.terrain.tileManager.update(this.transform,this.terrain),this.transform.setMinElevationForCurrentTile(this.terrain.getMinTileElevationForLngLatZoom(this.transform.center,this.transform.tileZoom)),!this._elevationFreeze&&this._centerClampedToGround&&this.transform.setElevation(this.terrain.getElevationForLngLatZoom(this.transform.center,this.transform.tileZoom))):(this.transform.setMinElevationForCurrentTile(0),this._centerClampedToGround&&this.transform.setElevation(0)),this._placementDirty=this.style&&this.style._updatePlacement(this.transform,this.showCollisionBoxes,W,this._crossSourceCollisions,fe),this.painter.render(this.style,{showTileBoundaries:this.showTileBoundaries,showOverdrawInspector:this._showOverdrawInspector,rotating:this.isRotating(),zooming:this.isZooming(),moving:this.isMoving(),fadeDuration:W,showPadding:this.showPadding}),this.fire(new o.l("render")),this.loaded()&&!this._loaded&&(this._loaded=!0,o.cH.mark(o.cI.load),this.fire(new o.l("load"))),this.style&&(this.style.hasTransitions()||se)&&(this._styleDirty=!0),this.style&&!this._placementDirty&&this.style._releaseSymbolFadeTiles();let ye=this._sourcesDirty||this._styleDirty||this._placementDirty;return ye||this._repaint?this.triggerRepaint():!this.isMoving()&&this.loaded()&&this.fire(new o.l("idle")),!this._loaded||this._fullyLoaded||ye||(this._fullyLoaded=!0,o.cH.mark(o.cI.fullLoad)),this}redraw(){return this.style&&(this._frameRequest&&(this._frameRequest.abort(),this._frameRequest=null),this._render(0)),this}remove(){var z;this._hash&&this._hash.remove();for(let m of this._controls)m.onRemove(this);this._controls=[],this._frameRequest&&(this._frameRequest.abort(),this._frameRequest=null),this._renderTaskQueue.clear(),this.painter.destroy(),this.handlers.destroy(),delete this.handlers,this.setStyle(null),typeof window<"u"&&removeEventListener("online",this._onWindowOnline,!1),Oe.removeThrottleControl(this._imageQueueHandle),(z=this._resizeObserver)===null||z===void 0||z.disconnect();let l=this.painter.context.gl.getExtension("WEBGL_lose_context");l?.loseContext&&l.loseContext(),this._canvas.removeEventListener("webglcontextrestored",this._contextRestored,!1),this._canvas.removeEventListener("webglcontextlost",this._contextLost,!1),U.remove(this._canvasContainer),U.remove(this._controlContainer),this._container.removeEventListener("scroll",this._onMapScroll,!1),this._container.classList.remove("maplibregl-map"),o.cH.clearMetrics(),this._removed=!0,this.fire(new o.l("remove"))}triggerRepaint(){this.style&&!this._frameRequest&&(this._frameRequest=new AbortController,I.frame(this._frameRequest,z=>{o.cH.frame(z),this._frameRequest=null;try{this._render(z)}catch(l){if(!o.Z(l)&&!function(m){return m.message===gu}(l))throw l}},()=>{}))}get showTileBoundaries(){return!!this._showTileBoundaries}set showTileBoundaries(z){this._showTileBoundaries!==z&&(this._showTileBoundaries=z,this._update())}get showPadding(){return!!this._showPadding}set showPadding(z){this._showPadding!==z&&(this._showPadding=z,this._update())}get showCollisionBoxes(){return!!this._showCollisionBoxes}set showCollisionBoxes(z){this._showCollisionBoxes!==z&&(this._showCollisionBoxes=z,z?this.style._generateCollisionBoxes():this._update())}get showOverdrawInspector(){return!!this._showOverdrawInspector}set showOverdrawInspector(z){this._showOverdrawInspector!==z&&(this._showOverdrawInspector=z,this._update())}get repaint(){return!!this._repaint}set repaint(z){this._repaint!==z&&(this._repaint=z,this.triggerRepaint())}get vertices(){return!!this._vertices}set vertices(z){this._vertices=z,this._update()}get version(){return Ml}getCameraTargetElevation(){return this.transform.elevation}getProjection(){return this.style.getProjection()}setProjection(z){return this._lazyInitEmptyStyle(),this.style.setProjection(z),this._update(!0)}},n.MapMouseEvent=Pe,n.MapTouchEvent=Ue,n.MapWheelEvent=ct,n.Marker=Tf,n.NavigationControl=class{constructor(z){this._updateZoomButtons=()=>{let l=this._map.getZoom(),m=l===this._map.getMaxZoom(),T=l===this._map.getMinZoom();this._zoomInButton.disabled=m,this._zoomOutButton.disabled=T,this._zoomInButton.setAttribute("aria-disabled",m.toString()),this._zoomOutButton.setAttribute("aria-disabled",T.toString())},this._rotateCompassArrow=()=>{this._compassIcon.style.transform=this.options.visualizePitch&&this.options.visualizeRoll?`scale(${1/Math.pow(Math.cos(this._map.transform.pitchInRadians),.5)}) rotateZ(${-this._map.transform.roll}deg) rotateX(${this._map.transform.pitch}deg) rotateZ(${-this._map.transform.bearing}deg)`:this.options.visualizePitch?`scale(${1/Math.pow(Math.cos(this._map.transform.pitchInRadians),.5)}) rotateX(${this._map.transform.pitch}deg) rotateZ(${-this._map.transform.bearing}deg)`:this.options.visualizeRoll?`rotate(${-this._map.transform.bearing-this._map.transform.roll}deg)`:`rotate(${-this._map.transform.bearing}deg)`},this._setButtonTitle=(l,m)=>{let T=this._map._getUIString(`NavigationControl.${m}`);l.title=T,l.setAttribute("aria-label",T)},this.options=o.e({},t0,z),this._container=U.create("div","maplibregl-ctrl maplibregl-ctrl-group"),this._container.addEventListener("contextmenu",l=>l.preventDefault()),this.options.showZoom&&(this._zoomInButton=this._createButton("maplibregl-ctrl-zoom-in",l=>this._map.zoomIn({},{originalEvent:l})),U.create("span","maplibregl-ctrl-icon",this._zoomInButton).setAttribute("aria-hidden","true"),this._zoomOutButton=this._createButton("maplibregl-ctrl-zoom-out",l=>this._map.zoomOut({},{originalEvent:l})),U.create("span","maplibregl-ctrl-icon",this._zoomOutButton).setAttribute("aria-hidden","true")),this.options.showCompass&&(this._compass=this._createButton("maplibregl-ctrl-compass",l=>{this.options.visualizePitch?this._map.resetNorthPitch({},{originalEvent:l}):this._map.resetNorth({},{originalEvent:l})}),this._compassIcon=U.create("span","maplibregl-ctrl-icon",this._compass),this._compassIcon.setAttribute("aria-hidden","true"))}onAdd(z){return this._map=z,this.options.showZoom&&(this._setButtonTitle(this._zoomInButton,"ZoomIn"),this._setButtonTitle(this._zoomOutButton,"ZoomOut"),this._map.on("zoom",this._updateZoomButtons),this._updateZoomButtons()),this.options.showCompass&&(this._setButtonTitle(this._compass,"ResetBearing"),this.options.visualizePitch&&this._map.on("pitch",this._rotateCompassArrow),this.options.visualizeRoll&&this._map.on("roll",this._rotateCompassArrow),this._map.on("rotate",this._rotateCompassArrow),this._rotateCompassArrow(),this._handler=new Lp(this._map,this._compass,this.options.visualizePitch)),this._container}onRemove(){U.remove(this._container),this.options.showZoom&&this._map.off("zoom",this._updateZoomButtons),this.options.showCompass&&(this.options.visualizePitch&&this._map.off("pitch",this._rotateCompassArrow),this.options.visualizeRoll&&this._map.off("roll",this._rotateCompassArrow),this._map.off("rotate",this._rotateCompassArrow),this._handler.off(),delete this._handler),delete this._map}_createButton(z,l){let m=U.create("button",z,this._container);return m.type="button",m.addEventListener("click",l),m}},n.Popup=class extends o.E{constructor(z){super(),this._updateOpacity=()=>{this.options.locationOccludedOpacity!==void 0&&(this._container.style.opacity=this._map.transform.isLocationOccluded(this.getLngLat())?`${this.options.locationOccludedOpacity}`:"")},this.remove=()=>(this._content&&U.remove(this._content),this._container&&(U.remove(this._container),delete this._container),this._map&&(this._map.off("move",this._update),this._map.off("move",this._onClose),this._map.off("click",this._onClose),this._map.off("remove",this.remove),this._map.off("mousemove",this._onMouseMove),this._map.off("mouseup",this._onMouseUp),this._map.off("drag",this._onDrag),this._map._canvasContainer.classList.remove("maplibregl-track-pointer"),delete this._map,this.fire(new o.l("close"))),this),this._onMouseUp=l=>{this._update(l.point)},this._onMouseMove=l=>{this._update(l.point)},this._onDrag=l=>{this._update(l.point)},this._update=l=>{if(!this._map||!this._lngLat&&!this._trackPointer||!this._content)return;if(!this._container){if(this._container=U.create("div","maplibregl-popup",this._map.getContainer()),this._tip=U.create("div","maplibregl-popup-tip",this._container),this._container.appendChild(this._content),this.options.className)for(let W of this.options.className.split(" "))this._container.classList.add(W);this._closeButton&&this._closeButton.setAttribute("aria-label",this._map._getUIString("Popup.Close")),this._trackPointer&&this._container.classList.add("maplibregl-popup-track-pointer")}if(this.options.maxWidth&&this._container.style.maxWidth!==this.options.maxWidth&&(this._container.style.maxWidth=this.options.maxWidth),this._lngLat=Kf(this._lngLat,this._flatPos,this._map.transform,this._trackPointer),this._trackPointer&&!l)return;let m=this._flatPos=this._pos=this._trackPointer&&l?l:this._map.project(this._lngLat);this._map.terrain&&(this._flatPos=this._trackPointer&&l?l:this._map.transform.locationToScreenPoint(this._lngLat));let T=this.options.anchor,P=tA(this.options.offset);if(!T){let W=this._container.offsetWidth,te=this._container.offsetHeight,se;se=m.y+P.bottom.ythis._map.transform.height-te?["bottom"]:[],m.xthis._map.transform.width-W/2&&se.push("right"),T=se.length===0?"bottom":se.join("-")}let V=m.add(P[T]);this.options.subpixelPositioning||(V=V.round()),U.setTransform(this._container,`${wf[T]} translate(${V.x}px,${V.y}px)`),tf(this._container,T,"popup"),this._updateOpacity()},this._onClose=()=>{this.remove()},this.options=o.e(Object.create(P_),z)}addTo(z){return this._map&&this.remove(),this._map=z,this.options.closeOnClick&&this._map.on("click",this._onClose),this.options.closeOnMove&&this._map.on("move",this._onClose),this._map.on("remove",this.remove),this._update(),this._focusFirstElement(),this._trackPointer?(this._map.on("mousemove",this._onMouseMove),this._map.on("mouseup",this._onMouseUp),this._container&&this._container.classList.add("maplibregl-popup-track-pointer"),this._map._canvasContainer.classList.add("maplibregl-track-pointer")):this._map.on("move",this._update),this.fire(new o.l("open")),this}isOpen(){return!!this._map}getLngLat(){return this._lngLat}setLngLat(z){return this._lngLat=o.V.convert(z),this._pos=null,this._flatPos=null,this._trackPointer=!1,this._update(),this._map&&(this._map.on("move",this._update),this._map.off("mousemove",this._onMouseMove),this._container&&this._container.classList.remove("maplibregl-popup-track-pointer"),this._map._canvasContainer.classList.remove("maplibregl-track-pointer")),this}trackPointer(){return this._trackPointer=!0,this._pos=null,this._flatPos=null,this._update(),this._map&&(this._map.off("move",this._update),this._map.on("mousemove",this._onMouseMove),this._map.on("drag",this._onDrag),this._container&&this._container.classList.add("maplibregl-popup-track-pointer"),this._map._canvasContainer.classList.add("maplibregl-track-pointer")),this}getElement(){return this._container}setText(z){return this.setDOMContent(document.createTextNode(z))}setHTML(z){let l=document.createDocumentFragment(),m=document.createElement("body"),T;for(m.innerHTML=z;T=m.firstChild,T;)l.appendChild(T);return this.setDOMContent(l)}getMaxWidth(){var z;return(z=this._container)===null||z===void 0?void 0:z.style.maxWidth}setMaxWidth(z){return this.options.maxWidth=z,this._update(),this}setDOMContent(z){if(this._content)for(;this._content.hasChildNodes();)this._content.firstChild&&this._content.removeChild(this._content.firstChild);else this._content=U.create("div","maplibregl-popup-content",this._container);return this._content.appendChild(z),this._createCloseButton(),this._update(),this._focusFirstElement(),this}addClassName(z){return this._container&&this._container.classList.add(z),this}removeClassName(z){return this._container&&this._container.classList.remove(z),this}setOffset(z){return this.options.offset=z,this._update(),this}toggleClassName(z){if(this._container)return this._container.classList.toggle(z)}setSubpixelPositioning(z){this.options.subpixelPositioning=z}_createCloseButton(){this.options.closeButton&&(this._closeButton=U.create("button","maplibregl-popup-close-button",this._content),this._closeButton.type="button",this._closeButton.innerHTML="×",this._closeButton.addEventListener("click",this._onClose))}_focusFirstElement(){if(!this.options.focusAfterOpen||!this._container)return;let z=this._container.querySelector(R_);z&&z.focus()}},n.RasterDEMTileSource=Ba,n.RasterTileSource=zs,n.ScaleControl=class{constructor(z){this._onMove=()=>{sg(this._map,this._container,this.options)},this.setUnit=l=>{this.options.unit=l,sg(this._map,this._container,this.options)},this.options=Object.assign(Object.assign({},M_),z)}getDefaultPosition(){return"bottom-left"}onAdd(z){return this._map=z,this._container=U.create("div","maplibregl-ctrl maplibregl-ctrl-scale",z.getContainer()),this._map.on("move",this._onMove),this._onMove(),this._container}onRemove(){U.remove(this._container),this._map.off("move",this._onMove),this._map=void 0}},n.ScrollZoomHandler=yc,n.Style=Ms,n.TerrainControl=class{constructor(z){this._toggleTerrain=()=>{this._map.getTerrain()?this._map.setTerrain(null):this._map.setTerrain(this.options),this._updateTerrainIcon()},this._updateTerrainIcon=()=>{this._terrainButton.classList.remove("maplibregl-ctrl-terrain"),this._terrainButton.classList.remove("maplibregl-ctrl-terrain-enabled"),this._map.terrain?(this._terrainButton.classList.add("maplibregl-ctrl-terrain-enabled"),this._terrainButton.title=this._map._getUIString("TerrainControl.Disable")):(this._terrainButton.classList.add("maplibregl-ctrl-terrain"),this._terrainButton.title=this._map._getUIString("TerrainControl.Enable"))},this.options=z}onAdd(z){return this._map=z,this._container=U.create("div","maplibregl-ctrl maplibregl-ctrl-group"),this._terrainButton=U.create("button","maplibregl-ctrl-terrain",this._container),U.create("span","maplibregl-ctrl-icon",this._terrainButton).setAttribute("aria-hidden","true"),this._terrainButton.type="button",this._terrainButton.addEventListener("click",this._toggleTerrain),this._updateTerrainIcon(),this._map.on("terrain",this._updateTerrainIcon),this._container}onRemove(){U.remove(this._container),this._map.off("terrain",this._updateTerrainIcon),this._map=void 0}},n.TwoFingersTouchPitchHandler=Hn,n.TwoFingersTouchRotateHandler=$n,n.TwoFingersTouchZoomHandler=qi,n.TwoFingersTouchZoomRotateHandler=Ju,n.VectorTileSource=mo,n.VideoSource=Yt,n.addSourceType=(z,l)=>o._(void 0,void 0,void 0,function*(){if(rt(z))throw new Error(`A source type called "${z}" already exists.`);((m,T)=>{Ne[m]=T})(z,l)}),n.clearPrewarmedResources=function(){let z=Gn;z&&(z.isPreloaded()&&z.numActive()===1?(z.release(Xi),Gn=null):console.warn("Could not clear WebWorkers since there are active Map instances that still reference it. The pre-warmed WebWorker pool can only be cleared when all map instances have been removed with map.remove()"))},n.createTileMesh=be,n.getMaxParallelImageRequests=function(){return o.c.MAX_PARALLEL_IMAGE_REQUESTS},n.getRTLTextPluginStatus=function(){return fr().getRTLTextPluginStatus()},n.getVersion=function(){return r0},n.getWorkerCount=function(){return xi.workerCount},n.getWorkerUrl=function(){return o.c.WORKER_URL},n.importScriptInWorkers=function(z){return mr().broadcast("IS",z)},n.isTimeFrozen=function(){return F.isFrozen()},n.now=k,n.prewarm=function(){nt().acquire(Xi)},n.restoreNow=function(){F.restoreNow()},n.setMaxParallelImageRequests=function(z){o.c.MAX_PARALLEL_IMAGE_REQUESTS=z},n.setNow=function(z){F.setNow(z)},n.setRTLTextPlugin=function(z,l){return fr().setRTLTextPlugin(z,l)},n.setWorkerCount=function(z){xi.workerCount=z},n.setWorkerUrl=function(z){o.c.WORKER_URL=z}});var i=t;return i})});var Nue=Vi((Cjt,b7)=>{"use strict";b7.exports=M4;b7.exports.default=M4;function M4(t,e,r){r=r||2;var i=e&&e.length,n=i?e[0]*r:t.length,o=Oue(t,0,n,r,!0),s=[];if(!o||o.next===o.prev)return s;var c,f,g,y,I,F,k;if(i&&(o=XUe(t,e,o,r)),t.length>80*r){c=g=t[0],f=y=t[1];for(var U=r;Ug&&(g=I),F>y&&(y=F);k=Math.max(g-c,y-f),k=k!==0?32767/k:0}return $3(o,s,r,c,f,k,0),s}function Oue(t,e,r,i,n){var o,s;if(n===x7(t,e,r,i)>0)for(o=e;o=e;o-=i)s=Due(o,t[o],t[o+1],s);return s&&P4(s,s.next)&&(Z3(s),s=s.next),s}function rw(t,e){if(!t)return t;e||(e=t);var r=t,i;do if(i=!1,!r.steiner&&(P4(r,r.next)||Eu(r.prev,r,r.next)===0)){if(Z3(r),r=e=r.prev,r===r.next)break;i=!0}else r=r.next;while(i||r!==e);return e}function $3(t,e,r,i,n,o,s){if(t){!s&&o&&JUe(t,i,n,o);for(var c=t,f,g;t.prev!==t.next;){if(f=t.prev,g=t.next,o?WUe(t,i,n,o):GUe(t)){e.push(f.i/r|0),e.push(t.i/r|0),e.push(g.i/r|0),Z3(t),t=g.next,c=g.next;continue}if(t=g,t===c){s?s===1?(t=qUe(rw(t),e,r),$3(t,e,r,i,n,o,2)):s===2&&$Ue(t,e,r,i,n,o):$3(rw(t),e,r,i,n,o,1);break}}}}function GUe(t){var e=t.prev,r=t,i=t.next;if(Eu(e,r,i)>=0)return!1;for(var n=e.x,o=r.x,s=i.x,c=e.y,f=r.y,g=i.y,y=no?n>s?n:s:o>s?o:s,k=c>f?c>g?c:g:f>g?f:g,U=i.next;U!==e;){if(U.x>=y&&U.x<=F&&U.y>=I&&U.y<=k&&kS(n,c,o,f,s,g,U.x,U.y)&&Eu(U.prev,U,U.next)>=0)return!1;U=U.next}return!0}function WUe(t,e,r,i){var n=t.prev,o=t,s=t.next;if(Eu(n,o,s)>=0)return!1;for(var c=n.x,f=o.x,g=s.x,y=n.y,I=o.y,F=s.y,k=cf?c>g?c:g:f>g?f:g,ee=y>I?y>F?y:F:I>F?I:F,he=y7(k,U,e,r,i),xe=y7(K,ee,e,r,i),me=t.prevZ,Se=t.nextZ;me&&me.z>=he&&Se&&Se.z<=xe;){if(me.x>=k&&me.x<=K&&me.y>=U&&me.y<=ee&&me!==n&&me!==s&&kS(c,y,f,I,g,F,me.x,me.y)&&Eu(me.prev,me,me.next)>=0||(me=me.prevZ,Se.x>=k&&Se.x<=K&&Se.y>=U&&Se.y<=ee&&Se!==n&&Se!==s&&kS(c,y,f,I,g,F,Se.x,Se.y)&&Eu(Se.prev,Se,Se.next)>=0))return!1;Se=Se.nextZ}for(;me&&me.z>=he;){if(me.x>=k&&me.x<=K&&me.y>=U&&me.y<=ee&&me!==n&&me!==s&&kS(c,y,f,I,g,F,me.x,me.y)&&Eu(me.prev,me,me.next)>=0)return!1;me=me.prevZ}for(;Se&&Se.z<=xe;){if(Se.x>=k&&Se.x<=K&&Se.y>=U&&Se.y<=ee&&Se!==n&&Se!==s&&kS(c,y,f,I,g,F,Se.x,Se.y)&&Eu(Se.prev,Se,Se.next)>=0)return!1;Se=Se.nextZ}return!0}function qUe(t,e,r){var i=t;do{var n=i.prev,o=i.next.next;!P4(n,o)&&Fue(n,i,i.next,o)&&X3(n,o)&&X3(o,n)&&(e.push(n.i/r|0),e.push(i.i/r|0),e.push(o.i/r|0),Z3(i),Z3(i.next),i=t=o),i=i.next}while(i!==t);return rw(i)}function $Ue(t,e,r,i,n,o){var s=t;do{for(var c=s.next.next;c!==s.prev;){if(s.i!==c.i&&r6e(s,c)){var f=kue(s,c);s=rw(s,s.next),f=rw(f,f.next),$3(s,e,r,i,n,o,0),$3(f,e,r,i,n,o,0);return}c=c.next}s=s.next}while(s!==t)}function XUe(t,e,r,i){var n=[],o,s,c,f,g;for(o=0,s=e.length;o=r.next.y&&r.next.y!==r.y){var c=r.x+(n-r.y)*(r.next.x-r.x)/(r.next.y-r.y);if(c<=i&&c>o&&(o=c,s=r.x=r.x&&r.x>=g&&i!==r.x&&kS(ns.x||r.x===s.x&&QUe(s,r)))&&(s=r,I=F)),r=r.next;while(r!==f);return s}function QUe(t,e){return Eu(t.prev,t,e.prev)<0&&Eu(e.next,t,t.next)<0}function JUe(t,e,r,i){var n=t;do n.z===0&&(n.z=y7(n.x,n.y,e,r,i)),n.prevZ=n.prev,n.nextZ=n.next,n=n.next;while(n!==t);n.prevZ.nextZ=null,n.prevZ=null,e6e(n)}function e6e(t){var e,r,i,n,o,s,c,f,g=1;do{for(r=t,t=null,o=null,s=0;r;){for(s++,i=r,c=0,e=0;e0||f>0&&i;)c!==0&&(f===0||!i||r.z<=i.z)?(n=r,r=r.nextZ,c--):(n=i,i=i.nextZ,f--),o?o.nextZ=n:t=n,n.prevZ=o,o=n;r=i}o.nextZ=null,g*=2}while(s>1);return t}function y7(t,e,r,i,n){return t=(t-r)*n|0,e=(e-i)*n|0,t=(t|t<<8)&16711935,t=(t|t<<4)&252645135,t=(t|t<<2)&858993459,t=(t|t<<1)&1431655765,e=(e|e<<8)&16711935,e=(e|e<<4)&252645135,e=(e|e<<2)&858993459,e=(e|e<<1)&1431655765,t|e<<1}function t6e(t){var e=t,r=t;do(e.x=(t-s)*(o-c)&&(t-s)*(i-c)>=(r-s)*(e-c)&&(r-s)*(o-c)>=(n-s)*(i-c)}function r6e(t,e){return t.next.i!==e.i&&t.prev.i!==e.i&&!i6e(t,e)&&(X3(t,e)&&X3(e,t)&&n6e(t,e)&&(Eu(t.prev,t,e.prev)||Eu(t,e.prev,e))||P4(t,e)&&Eu(t.prev,t,t.next)>0&&Eu(e.prev,e,e.next)>0)}function Eu(t,e,r){return(e.y-t.y)*(r.x-e.x)-(e.x-t.x)*(r.y-e.y)}function P4(t,e){return t.x===e.x&&t.y===e.y}function Fue(t,e,r,i){var n=I4(Eu(t,e,r)),o=I4(Eu(t,e,i)),s=I4(Eu(r,i,t)),c=I4(Eu(r,i,e));return!!(n!==o&&s!==c||n===0&&C4(t,r,e)||o===0&&C4(t,i,e)||s===0&&C4(r,t,i)||c===0&&C4(r,e,i))}function C4(t,e,r){return e.x<=Math.max(t.x,r.x)&&e.x>=Math.min(t.x,r.x)&&e.y<=Math.max(t.y,r.y)&&e.y>=Math.min(t.y,r.y)}function I4(t){return t>0?1:t<0?-1:0}function i6e(t,e){var r=t;do{if(r.i!==t.i&&r.next.i!==t.i&&r.i!==e.i&&r.next.i!==e.i&&Fue(r,r.next,t,e))return!0;r=r.next}while(r!==t);return!1}function X3(t,e){return Eu(t.prev,t,t.next)<0?Eu(t,e,t.next)>=0&&Eu(t,t.prev,e)>=0:Eu(t,e,t.prev)<0||Eu(t,t.next,e)<0}function n6e(t,e){var r=t,i=!1,n=(t.x+e.x)/2,o=(t.y+e.y)/2;do r.y>o!=r.next.y>o&&r.next.y!==r.y&&n<(r.next.x-r.x)*(o-r.y)/(r.next.y-r.y)+r.x&&(i=!i),r=r.next;while(r!==t);return i}function kue(t,e){var r=new v7(t.i,t.x,t.y),i=new v7(e.i,e.x,e.y),n=t.next,o=e.prev;return t.next=e,e.prev=t,r.next=n,n.prev=r,i.next=r,r.prev=i,o.next=i,i.prev=o,i}function Due(t,e,r,i){var n=new v7(t,e,r);return i?(n.next=i.next,n.prev=i,i.next.prev=n,i.next=n):(n.prev=n,n.next=n),n}function Z3(t){t.next.prev=t.prev,t.prev.next=t.next,t.prevZ&&(t.prevZ.nextZ=t.nextZ),t.nextZ&&(t.nextZ.prevZ=t.prevZ)}function v7(t,e,r){this.i=t,this.x=e,this.y=r,this.prev=null,this.next=null,this.z=0,this.prevZ=null,this.nextZ=null,this.steiner=!1}M4.deviation=function(t,e,r,i){var n=e&&e.length,o=n?e[0]*r:t.length,s=Math.abs(x7(t,0,o,r));if(n)for(var c=0,f=e.length;c0&&(i+=t[n-1].length,r.holes.push(i))}return r}});var fq=Vi((lme,LR)=>{(function(t,e){typeof define=="function"&&define.amd?define([],e):typeof lQ=="function"&&typeof LR=="object"&&LR&&LR.exports?LR.exports=e():(t.dcodeIO=t.dcodeIO||{}).Long=e()})(lme,function(){"use strict";function t(Ce,_e,Je){this.low=Ce|0,this.high=_e|0,this.unsigned=!!Je}t.prototype.__isLong__,Object.defineProperty(t.prototype,"__isLong__",{value:!0,enumerable:!1,configurable:!1});function e(Ce){return(Ce&&Ce.__isLong__)===!0}t.isLong=e;var r={},i={};function n(Ce,_e){var Je,Et,Ze;return _e?(Ce>>>=0,(Ze=0<=Ce&&Ce<256)&&(Et=i[Ce],Et)?Et:(Je=s(Ce,(Ce|0)<0?-1:0,!0),Ze&&(i[Ce]=Je),Je)):(Ce|=0,(Ze=-128<=Ce&&Ce<128)&&(Et=r[Ce],Et)?Et:(Je=s(Ce,Ce<0?-1:0,!1),Ze&&(r[Ce]=Je),Je))}t.fromInt=n;function o(Ce,_e){if(isNaN(Ce)||!isFinite(Ce))return _e?he:ee;if(_e){if(Ce<0)return he;if(Ce>=k)return ne}else{if(Ce<=-U)return Ge;if(Ce+1>=U)return Oe}return Ce<0?o(-Ce,_e).neg():s(Ce%F|0,Ce/F|0,_e)}t.fromNumber=o;function s(Ce,_e,Je){return new t(Ce,_e,Je)}t.fromBits=s;var c=Math.pow;function f(Ce,_e,Je){if(Ce.length===0)throw Error("empty string");if(Ce==="NaN"||Ce==="Infinity"||Ce==="+Infinity"||Ce==="-Infinity")return ee;if(typeof _e=="number"?(Je=_e,_e=!1):_e=!!_e,Je=Je||10,Je<2||360)throw Error("interior hyphen");if(Et===0)return f(Ce.substring(1),_e,Je).neg();for(var Ze=o(c(Je,8)),xt=ee,sr=0;sr>>0:this.low},Xe.toNumber=function(){return this.unsigned?(this.high>>>0)*F+(this.low>>>0):this.high*F+(this.low>>>0)},Xe.toString=function(_e){if(_e=_e||10,_e<2||36<_e)throw RangeError("radix");if(this.isZero())return"0";if(this.isNegative())if(this.eq(Ge)){var Je=o(_e),Et=this.div(Je),Ze=Et.mul(Je).sub(this);return Et.toString(_e)+Ze.toInt().toString(_e)}else return"-"+this.neg().toString(_e);for(var xt=o(c(_e,6),this.unsigned),sr=this,Mr="";;){var hr=sr.div(xt),mi=sr.sub(hr.mul(xt)).toInt()>>>0,bi=mi.toString(_e);if(sr=hr,sr.isZero())return bi+Mr;for(;bi.length<6;)bi="0"+bi;Mr=""+bi+Mr}},Xe.getHighBits=function(){return this.high},Xe.getHighBitsUnsigned=function(){return this.high>>>0},Xe.getLowBits=function(){return this.low},Xe.getLowBitsUnsigned=function(){return this.low>>>0},Xe.getNumBitsAbs=function(){if(this.isNegative())return this.eq(Ge)?64:this.neg().getNumBitsAbs();for(var _e=this.high!=0?this.high:this.low,Je=31;Je>0&&!(_e&1<=0},Xe.isOdd=function(){return(this.low&1)===1},Xe.isEven=function(){return(this.low&1)===0},Xe.equals=function(_e){return e(_e)||(_e=g(_e)),this.unsigned!==_e.unsigned&&this.high>>>31===1&&_e.high>>>31===1?!1:this.high===_e.high&&this.low===_e.low},Xe.eq=Xe.equals,Xe.notEquals=function(_e){return!this.eq(_e)},Xe.neq=Xe.notEquals,Xe.lessThan=function(_e){return this.comp(_e)<0},Xe.lt=Xe.lessThan,Xe.lessThanOrEqual=function(_e){return this.comp(_e)<=0},Xe.lte=Xe.lessThanOrEqual,Xe.greaterThan=function(_e){return this.comp(_e)>0},Xe.gt=Xe.greaterThan,Xe.greaterThanOrEqual=function(_e){return this.comp(_e)>=0},Xe.gte=Xe.greaterThanOrEqual,Xe.compare=function(_e){if(e(_e)||(_e=g(_e)),this.eq(_e))return 0;var Je=this.isNegative(),Et=_e.isNegative();return Je&&!Et?-1:!Je&&Et?1:this.unsigned?_e.high>>>0>this.high>>>0||_e.high===this.high&&_e.low>>>0>this.low>>>0?-1:1:this.sub(_e).isNegative()?-1:1},Xe.comp=Xe.compare,Xe.negate=function(){return!this.unsigned&&this.eq(Ge)?Ge:this.not().add(xe)},Xe.neg=Xe.negate,Xe.add=function(_e){e(_e)||(_e=g(_e));var Je=this.high>>>16,Et=this.high&65535,Ze=this.low>>>16,xt=this.low&65535,sr=_e.high>>>16,Mr=_e.high&65535,hr=_e.low>>>16,mi=_e.low&65535,bi=0,un=0,Yr=0,Xi=0;return Xi+=xt+mi,Yr+=Xi>>>16,Xi&=65535,Yr+=Ze+hr,un+=Yr>>>16,Yr&=65535,un+=Et+Mr,bi+=un>>>16,un&=65535,bi+=Je+sr,bi&=65535,s(Yr<<16|Xi,bi<<16|un,this.unsigned)},Xe.subtract=function(_e){return e(_e)||(_e=g(_e)),this.add(_e.neg())},Xe.sub=Xe.subtract,Xe.multiply=function(_e){if(this.isZero()||(e(_e)||(_e=g(_e)),_e.isZero()))return ee;if(this.eq(Ge))return _e.isOdd()?Ge:ee;if(_e.eq(Ge))return this.isOdd()?Ge:ee;if(this.isNegative())return _e.isNegative()?this.neg().mul(_e.neg()):this.neg().mul(_e).neg();if(_e.isNegative())return this.mul(_e.neg()).neg();if(this.lt(K)&&_e.lt(K))return o(this.toNumber()*_e.toNumber(),this.unsigned);var Je=this.high>>>16,Et=this.high&65535,Ze=this.low>>>16,xt=this.low&65535,sr=_e.high>>>16,Mr=_e.high&65535,hr=_e.low>>>16,mi=_e.low&65535,bi=0,un=0,Yr=0,Xi=0;return Xi+=xt*mi,Yr+=Xi>>>16,Xi&=65535,Yr+=Ze*mi,un+=Yr>>>16,Yr&=65535,Yr+=xt*hr,un+=Yr>>>16,Yr&=65535,un+=Et*mi,bi+=un>>>16,un&=65535,un+=Ze*hr,bi+=un>>>16,un&=65535,un+=xt*Mr,bi+=un>>>16,un&=65535,bi+=Je*mi+Et*hr+Ze*Mr+xt*sr,bi&=65535,s(Yr<<16|Xi,bi<<16|un,this.unsigned)},Xe.mul=Xe.multiply,Xe.divide=function(_e){if(e(_e)||(_e=g(_e)),_e.isZero())throw Error("division by zero");if(this.isZero())return this.unsigned?he:ee;var Je,Et,Ze;if(this.unsigned){if(_e.unsigned||(_e=_e.toUnsigned()),_e.gt(this))return he;if(_e.gt(this.shru(1)))return me;Ze=he}else{if(this.eq(Ge)){if(_e.eq(xe)||_e.eq(Se))return Ge;if(_e.eq(Ge))return xe;var xt=this.shr(1);return Je=xt.div(_e).shl(1),Je.eq(ee)?_e.isNegative()?xe:Se:(Et=this.sub(_e.mul(Je)),Ze=Je.add(Et.div(_e)),Ze)}else if(_e.eq(Ge))return this.unsigned?he:ee;if(this.isNegative())return _e.isNegative()?this.neg().div(_e.neg()):this.neg().div(_e).neg();if(_e.isNegative())return this.div(_e.neg()).neg();Ze=ee}for(Et=this;Et.gte(_e);){Je=Math.max(1,Math.floor(Et.toNumber()/_e.toNumber()));for(var sr=Math.ceil(Math.log(Je)/Math.LN2),Mr=sr<=48?1:c(2,sr-48),hr=o(Je),mi=hr.mul(_e);mi.isNegative()||mi.gt(Et);)Je-=Mr,hr=o(Je,this.unsigned),mi=hr.mul(_e);hr.isZero()&&(hr=xe),Ze=Ze.add(hr),Et=Et.sub(mi)}return Ze},Xe.div=Xe.divide,Xe.modulo=function(_e){return e(_e)||(_e=g(_e)),this.sub(this.div(_e).mul(_e))},Xe.mod=Xe.modulo,Xe.not=function(){return s(~this.low,~this.high,this.unsigned)},Xe.and=function(_e){return e(_e)||(_e=g(_e)),s(this.low&_e.low,this.high&_e.high,this.unsigned)},Xe.or=function(_e){return e(_e)||(_e=g(_e)),s(this.low|_e.low,this.high|_e.high,this.unsigned)},Xe.xor=function(_e){return e(_e)||(_e=g(_e)),s(this.low^_e.low,this.high^_e.high,this.unsigned)},Xe.shiftLeft=function(_e){return e(_e)&&(_e=_e.toInt()),(_e&=63)===0?this:_e<32?s(this.low<<_e,this.high<<_e|this.low>>>32-_e,this.unsigned):s(0,this.low<<_e-32,this.unsigned)},Xe.shl=Xe.shiftLeft,Xe.shiftRight=function(_e){return e(_e)&&(_e=_e.toInt()),(_e&=63)===0?this:_e<32?s(this.low>>>_e|this.high<<32-_e,this.high>>_e,this.unsigned):s(this.high>>_e-32,this.high>=0?0:-1,this.unsigned)},Xe.shr=Xe.shiftRight,Xe.shiftRightUnsigned=function(_e){if(e(_e)&&(_e=_e.toInt()),_e&=63,_e===0)return this;var Je=this.high;if(_e<32){var Et=this.low;return s(Et>>>_e|Je<<32-_e,Je>>>_e,this.unsigned)}else return _e===32?s(Je,0,this.unsigned):s(Je>>>_e-32,0,this.unsigned)},Xe.shru=Xe.shiftRightUnsigned,Xe.toSigned=function(){return this.unsigned?s(this.low,this.high,!1):this},Xe.toUnsigned=function(){return this.unsigned?this:s(this.low,this.high,!0)},Xe.toBytes=function(Ce){return Ce?this.toBytesLE():this.toBytesBE()},Xe.toBytesLE=function(){var Ce=this.high,_e=this.low;return[_e&255,_e>>>8&255,_e>>>16&255,_e>>>24&255,Ce&255,Ce>>>8&255,Ce>>>16&255,Ce>>>24&255]},Xe.toBytesBE=function(){var Ce=this.high,_e=this.low;return[Ce>>>24&255,Ce>>>16&255,Ce>>>8&255,Ce&255,_e>>>24&255,_e>>>16&255,_e>>>8&255,_e&255]},t})});var KAe=Vi(rX=>{rX.read=function(t,e,r,i,n){var o,s,c=n*8-i-1,f=(1<>1,y=-7,I=r?n-1:0,F=r?-1:1,k=t[e+I];for(I+=F,o=k&(1<<-y)-1,k>>=-y,y+=c;y>0;o=o*256+t[e+I],I+=F,y-=8);for(s=o&(1<<-y)-1,o>>=-y,y+=i;y>0;s=s*256+t[e+I],I+=F,y-=8);if(o===0)o=1-g;else{if(o===f)return s?NaN:(k?-1:1)*(1/0);s=s+Math.pow(2,i),o=o-g}return(k?-1:1)*s*Math.pow(2,o-i)};rX.write=function(t,e,r,i,n,o){var s,c,f,g=o*8-n-1,y=(1<>1,F=n===23?Math.pow(2,-24)-Math.pow(2,-77):0,k=i?0:o-1,U=i?1:-1,K=e<0||e===0&&1/e<0?1:0;for(e=Math.abs(e),isNaN(e)||e===1/0?(c=isNaN(e)?1:0,s=y):(s=Math.floor(Math.log(e)/Math.LN2),e*(f=Math.pow(2,-s))<1&&(s--,f*=2),s+I>=1?e+=F/f:e+=F*Math.pow(2,1-I),e*f>=2&&(s++,f/=2),s+I>=y?(c=0,s=y):s+I>=1?(c=(e*f-1)*Math.pow(2,n),s=s+I):(c=e*Math.pow(2,I-1)*Math.pow(2,n),s=0));n>=8;t[r+k]=c&255,k+=U,c/=256,n-=8);for(s=s<0;t[r+k]=s&255,k+=U,s/=256,g-=8);t[r+k-U]|=K*128}});var i_e=Vi((ror,r_e)=>{"use strict";r_e.exports=gl;var ZU=KAe();function gl(t){this.buf=ArrayBuffer.isView&&ArrayBuffer.isView(t)?t:new Uint8Array(t||0),this.pos=0,this.type=0,this.length=this.buf.length}gl.Varint=0;gl.Fixed64=1;gl.Bytes=2;gl.Fixed32=5;var iX=(1<<16)*(1<<16),QAe=1/iX,nYe=12,t_e=typeof TextDecoder>"u"?null:new TextDecoder("utf-8");gl.prototype={destroy:function(){this.buf=null},readFields:function(t,e,r){for(r=r||this.length;this.pos>3,o=this.pos;this.type=i&7,t(n,e,this),this.pos===o&&this.skip(i)}return e},readMessage:function(t,e){return this.readFields(t,e,this.readVarint()+this.pos)},readFixed32:function(){var t=YU(this.buf,this.pos);return this.pos+=4,t},readSFixed32:function(){var t=e_e(this.buf,this.pos);return this.pos+=4,t},readFixed64:function(){var t=YU(this.buf,this.pos)+YU(this.buf,this.pos+4)*iX;return this.pos+=8,t},readSFixed64:function(){var t=YU(this.buf,this.pos)+e_e(this.buf,this.pos+4)*iX;return this.pos+=8,t},readFloat:function(){var t=ZU.read(this.buf,this.pos,!0,23,4);return this.pos+=4,t},readDouble:function(){var t=ZU.read(this.buf,this.pos,!0,52,8);return this.pos+=8,t},readVarint:function(t){var e=this.buf,r,i;return i=e[this.pos++],r=i&127,i<128||(i=e[this.pos++],r|=(i&127)<<7,i<128)||(i=e[this.pos++],r|=(i&127)<<14,i<128)||(i=e[this.pos++],r|=(i&127)<<21,i<128)?r:(i=e[this.pos],r|=(i&15)<<28,oYe(r,t,this))},readVarint64:function(){return this.readVarint(!0)},readSVarint:function(){var t=this.readVarint();return t%2===1?(t+1)/-2:t/2},readBoolean:function(){return Boolean(this.readVarint())},readString:function(){var t=this.readVarint()+this.pos,e=this.pos;return this.pos=t,t-e>=nYe&&t_e?yYe(this.buf,e,t):_Ye(this.buf,e,t)},readBytes:function(){var t=this.readVarint()+this.pos,e=this.buf.subarray(this.pos,t);return this.pos=t,e},readPackedVarint:function(t,e){if(this.type!==gl.Bytes)return t.push(this.readVarint(e));var r=qy(this);for(t=t||[];this.pos127;);else if(e===gl.Bytes)this.pos=this.readVarint()+this.pos;else if(e===gl.Fixed32)this.pos+=4;else if(e===gl.Fixed64)this.pos+=8;else throw new Error("Unimplemented type: "+e)},writeTag:function(t,e){this.writeVarint(t<<3|e)},realloc:function(t){for(var e=this.length||16;e268435455||t<0){sYe(t,this);return}this.realloc(4),this.buf[this.pos++]=t&127|(t>127?128:0),!(t<=127)&&(this.buf[this.pos++]=(t>>>=7)&127|(t>127?128:0),!(t<=127)&&(this.buf[this.pos++]=(t>>>=7)&127|(t>127?128:0),!(t<=127)&&(this.buf[this.pos++]=t>>>7&127)))},writeSVarint:function(t){this.writeVarint(t<0?-t*2-1:t*2)},writeBoolean:function(t){this.writeVarint(Boolean(t))},writeString:function(t){t=String(t),this.realloc(t.length*4),this.pos++;var e=this.pos;this.pos=vYe(this.buf,t,this.pos);var r=this.pos-e;r>=128&&JAe(e,r,this),this.pos=e-1,this.writeVarint(r),this.pos+=r},writeFloat:function(t){this.realloc(4),ZU.write(this.buf,t,this.pos,!0,23,4),this.pos+=4},writeDouble:function(t){this.realloc(8),ZU.write(this.buf,t,this.pos,!0,52,8),this.pos+=8},writeBytes:function(t){var e=t.length;this.writeVarint(e),this.realloc(e);for(var r=0;r=128&&JAe(r,i,this),this.pos=r-1,this.writeVarint(i),this.pos+=i},writeMessage:function(t,e,r){this.writeTag(t,gl.Bytes),this.writeRawMessage(e,r)},writePackedVarint:function(t,e){e.length&&this.writeMessage(t,cYe,e)},writePackedSVarint:function(t,e){e.length&&this.writeMessage(t,uYe,e)},writePackedBoolean:function(t,e){e.length&&this.writeMessage(t,dYe,e)},writePackedFloat:function(t,e){e.length&&this.writeMessage(t,hYe,e)},writePackedDouble:function(t,e){e.length&&this.writeMessage(t,fYe,e)},writePackedFixed32:function(t,e){e.length&&this.writeMessage(t,pYe,e)},writePackedSFixed32:function(t,e){e.length&&this.writeMessage(t,mYe,e)},writePackedFixed64:function(t,e){e.length&&this.writeMessage(t,gYe,e)},writePackedSFixed64:function(t,e){e.length&&this.writeMessage(t,AYe,e)},writeBytesField:function(t,e){this.writeTag(t,gl.Bytes),this.writeBytes(e)},writeFixed32Field:function(t,e){this.writeTag(t,gl.Fixed32),this.writeFixed32(e)},writeSFixed32Field:function(t,e){this.writeTag(t,gl.Fixed32),this.writeSFixed32(e)},writeFixed64Field:function(t,e){this.writeTag(t,gl.Fixed64),this.writeFixed64(e)},writeSFixed64Field:function(t,e){this.writeTag(t,gl.Fixed64),this.writeSFixed64(e)},writeVarintField:function(t,e){this.writeTag(t,gl.Varint),this.writeVarint(e)},writeSVarintField:function(t,e){this.writeTag(t,gl.Varint),this.writeSVarint(e)},writeStringField:function(t,e){this.writeTag(t,gl.Bytes),this.writeString(e)},writeFloatField:function(t,e){this.writeTag(t,gl.Fixed32),this.writeFloat(e)},writeDoubleField:function(t,e){this.writeTag(t,gl.Fixed64),this.writeDouble(e)},writeBooleanField:function(t,e){this.writeVarintField(t,Boolean(e))}};function oYe(t,e,r){var i=r.buf,n,o;if(o=i[r.pos++],n=(o&112)>>4,o<128||(o=i[r.pos++],n|=(o&127)<<3,o<128)||(o=i[r.pos++],n|=(o&127)<<10,o<128)||(o=i[r.pos++],n|=(o&127)<<17,o<128)||(o=i[r.pos++],n|=(o&127)<<24,o<128)||(o=i[r.pos++],n|=(o&1)<<31,o<128))return OE(t,n,e);throw new Error("Expected varint not more than 10 bytes")}function qy(t){return t.type===gl.Bytes?t.readVarint()+t.pos:t.pos+1}function OE(t,e,r){return r?e*4294967296+(t>>>0):(e>>>0)*4294967296+(t>>>0)}function sYe(t,e){var r,i;if(t>=0?(r=t%4294967296|0,i=t/4294967296|0):(r=~(-t%4294967296),i=~(-t/4294967296),r^4294967295?r=r+1|0:(r=0,i=i+1|0)),t>=18446744073709552e3||t<-18446744073709552e3)throw new Error("Given varint doesn't fit into 10 bytes");e.realloc(10),aYe(r,i,e),lYe(i,e)}function aYe(t,e,r){r.buf[r.pos++]=t&127|128,t>>>=7,r.buf[r.pos++]=t&127|128,t>>>=7,r.buf[r.pos++]=t&127|128,t>>>=7,r.buf[r.pos++]=t&127|128,t>>>=7,r.buf[r.pos]=t&127}function lYe(t,e){var r=(t&7)<<4;e.buf[e.pos++]|=r|((t>>>=3)?128:0),t&&(e.buf[e.pos++]=t&127|((t>>>=7)?128:0),t&&(e.buf[e.pos++]=t&127|((t>>>=7)?128:0),t&&(e.buf[e.pos++]=t&127|((t>>>=7)?128:0),t&&(e.buf[e.pos++]=t&127|((t>>>=7)?128:0),t&&(e.buf[e.pos++]=t&127)))))}function JAe(t,e,r){var i=e<=16383?1:e<=2097151?2:e<=268435455?3:Math.floor(Math.log(e)/(Math.LN2*7));r.realloc(i);for(var n=r.pos-1;n>=t;n--)r.buf[n+i]=r.buf[n]}function cYe(t,e){for(var r=0;r>>8,t[r+2]=e>>>16,t[r+3]=e>>>24}function e_e(t,e){return(t[e]|t[e+1]<<8|t[e+2]<<16)+(t[e+3]<<24)}function _Ye(t,e,r){for(var i="",n=e;n239?4:o>223?3:o>191?2:1;if(n+c>r)break;var f,g,y;c===1?o<128&&(s=o):c===2?(f=t[n+1],(f&192)===128&&(s=(o&31)<<6|f&63,s<=127&&(s=null))):c===3?(f=t[n+1],g=t[n+2],(f&192)===128&&(g&192)===128&&(s=(o&15)<<12|(f&63)<<6|g&63,(s<=2047||s>=55296&&s<=57343)&&(s=null))):c===4&&(f=t[n+1],g=t[n+2],y=t[n+3],(f&192)===128&&(g&192)===128&&(y&192)===128&&(s=(o&15)<<18|(f&63)<<12|(g&63)<<6|y&63,(s<=65535||s>=1114112)&&(s=null))),s===null?(s=65533,c=1):s>65535&&(s-=65536,i+=String.fromCharCode(s>>>10&1023|55296),s=56320|s&1023),i+=String.fromCharCode(s),n+=c}return i}function yYe(t,e,r){return t_e.decode(t.subarray(e,r))}function vYe(t,e,r){for(var i=0,n,o;i55295&&n<57344)if(o)if(n<56320){t[r++]=239,t[r++]=191,t[r++]=189,o=n;continue}else n=o-55296<<10|n-56320|65536,o=null;else{n>56319||i+1===e.length?(t[r++]=239,t[r++]=191,t[r++]=189):o=n;continue}else o&&(t[r++]=239,t[r++]=191,t[r++]=189,o=null);n<128?t[r++]=n:(n<2048?t[r++]=n>>6|192:(n<65536?t[r++]=n>>12|224:(t[r++]=n>>18|240,t[r++]=n>>12&63|128),t[r++]=n>>6&63|128),t[r++]=n&63|128)}return r}});var C_e=Vi((dB,e6)=>{(function(t){"use strict";var e="Compound",r="Identifier",i="MemberExpression",n="Literal",o="ThisExpression",s="CallExpression",c="UnaryExpression",f="BinaryExpression",g="LogicalExpression",y="ConditionalExpression",I="ArrayExpression",F=46,k=44,U=39,K=34,ee=40,he=41,xe=91,me=93,Se=63,Oe=59,ne=58,Ge=function(xi,ii){var Gn=new Error(xi+" at character "+ii);throw Gn.index=ii,Gn.description=xi,Gn},Xe=!0,Ce={"-":Xe,"!":Xe,"~":Xe,"+":Xe},_e={"||":1,"&&":2,"|":3,"^":4,"&":5,"==":6,"!=":6,"===":6,"!==":6,"<":7,">":7,"<=":7,">=":7,"<<":8,">>":8,">>>":8,"+":9,"-":9,"*":10,"/":10,"%":10},Je=function(xi){var ii=0,Gn;for(var Ve in xi)(Gn=Ve.length)>ii&&xi.hasOwnProperty(Ve)&&(ii=Gn);return ii},Et=Je(Ce),Ze=Je(_e),xt={true:!0,false:!1,null:null},sr="this",Mr=function(xi){return _e[xi]||0},hr=function(xi,ii,Gn){var Ve=xi==="||"||xi==="&&"?g:f;return{type:Ve,operator:xi,left:ii,right:Gn}},mi=function(xi){return xi>=48&&xi<=57},bi=function(xi){return xi===36||xi===95||xi>=65&&xi<=90||xi>=97&&xi<=122||xi>=128&&!_e[String.fromCharCode(xi)]},un=function(xi){return xi===36||xi===95||xi>=65&&xi<=90||xi>=97&&xi<=122||xi>=48&&xi<=57||xi>=128&&!_e[String.fromCharCode(xi)]},Yr=function(xi){for(var ii=0,Gn=xi.charAt,Ve=xi.charCodeAt,nt=function(Fe){return Gn.call(xi,Fe)},Ft=function(Fe){return Ve.call(xi,Fe)},mr=xi.length,Xr=function(){for(var Fe=Ft(ii);Fe===32||Fe===9||Fe===10||Fe===13;)Fe=Ft(++ii)},zr=function(){var Fe=Nn(),Ne,rt;if(Xr(),Ft(ii)===Se){if(ii++,Ne=zr(),Ne||Ge("Expected expression",ii),Xr(),Ft(ii)===ne)return ii++,rt=zr(),rt||Ge("Expected expression",ii),{type:y,test:Fe,consequent:Ne,alternate:rt};Ge("Expected :",ii)}else return Fe},ln=function(){Xr();for(var Fe,Ne=xi.substr(ii,Ze),rt=Ne.length;rt>0;){if(_e.hasOwnProperty(Ne)&&(!bi(Ft(ii))||ii+Ne.length2&&Vt<=Gt[Gt.length-2].prec;)nr=Gt.pop(),rt=Gt.pop().value,fr=Gt.pop(),Ne=hr(rt,fr,nr),Gt.push(Ne);Ne=Co(),Ne||Ge("Expected expression after "+ti,ii),Gt.push(yr,Ne)}for(xr=Gt.length-1,Ne=Gt[xr];xr>1;)Ne=hr(Gt[xr-1].value,Gt[xr-2],Ne),xr-=2;return Ne},Co=function(){var Fe,Ne,rt;if(Xr(),Fe=Ft(ii),mi(Fe)||Fe===F)return Ho();if(Fe===U||Fe===K)return is();if(Fe===xe)return so();for(Ne=xi.substr(ii,Et),rt=Ne.length;rt>0;){if(Ce.hasOwnProperty(Ne)&&(!bi(Ft(ii))||ii+Ne.length=rt.length&&Ge("Unexpected token "+String.fromCharCode(Fe),ii);break}else if(Ne===k){if(ii++,yr++,yr!==rt.length){if(Fe===he)Ge("Unexpected token ,",ii);else if(Fe===me)for(var fr=rt.length;fr"u"){var Xi=t.jsep;t.jsep=Yr,Yr.noConflict=function(){return t.jsep===Yr&&(t.jsep=Xi),Yr}}else typeof e6<"u"&&e6.exports?dB=e6.exports=Yr:dB.parse=Yr})(dB)});var Kye=Vi(B6=>{"use strict";B6.byteLength=yQe;B6.toByteArray=xQe;B6.fromByteArray=TQe;var T_=[],Qg=[],_Qe=typeof Uint8Array<"u"?Uint8Array:Array,qX="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";for(Ww=0,Zye=qX.length;Ww0)throw new Error("Invalid string. Length must be a multiple of 4");var r=t.indexOf("=");r===-1&&(r=e);var i=r===e?0:4-r%4;return[r,i]}function yQe(t){var e=Yye(t),r=e[0],i=e[1];return(r+i)*3/4-i}function vQe(t,e,r){return(e+r)*3/4-r}function xQe(t){var e,r=Yye(t),i=r[0],n=r[1],o=new _Qe(vQe(t,i,n)),s=0,c=n>0?i-4:i,f;for(f=0;f>16&255,o[s++]=e>>8&255,o[s++]=e&255;return n===2&&(e=Qg[t.charCodeAt(f)]<<2|Qg[t.charCodeAt(f+1)]>>4,o[s++]=e&255),n===1&&(e=Qg[t.charCodeAt(f)]<<10|Qg[t.charCodeAt(f+1)]<<4|Qg[t.charCodeAt(f+2)]>>2,o[s++]=e>>8&255,o[s++]=e&255),o}function bQe(t){return T_[t>>18&63]+T_[t>>12&63]+T_[t>>6&63]+T_[t&63]}function wQe(t,e,r){for(var i,n=[],o=e;oc?c:s+o));return i===1?(e=t[r-1],n.push(T_[e>>2]+T_[e<<4&63]+"==")):i===2&&(e=(t[r-2]<<8)+t[r-1],n.push(T_[e>>10]+T_[e>>4&63]+T_[e<<2&63]+"=")),n.join("")}});var ZE=Vi((L6,Qye)=>{(function(t,e){typeof L6=="object"&&typeof Qye<"u"?e(L6):typeof define=="function"&&define.amd?define(["exports"],e):(t=typeof globalThis<"u"?globalThis:t||self,e(t.lumino_coreutils={}))})(L6,function(t){"use strict";t.JSONExt=void 0,function(s){s.emptyObject=Object.freeze({}),s.emptyArray=Object.freeze([]);function c(ee){return ee===null||typeof ee=="boolean"||typeof ee=="number"||typeof ee=="string"}s.isPrimitive=c;function f(ee){return Array.isArray(ee)}s.isArray=f;function g(ee){return!c(ee)&&!f(ee)}s.isObject=g;function y(ee,he){if(ee===he)return!0;if(c(ee)||c(he))return!1;var xe=f(ee),me=f(he);return xe!==me?!1:xe&&me?F(ee,he):k(ee,he)}s.deepEqual=y;function I(ee){return c(ee)?ee:f(ee)?U(ee):K(ee)}s.deepCopy=I;function F(ee,he){if(ee===he)return!0;if(ee.length!==he.length)return!1;for(var xe=0,me=ee.length;xe>>0),s[f]=c&255,c>>>=8}t.Random=void 0,function(s){s.getRandomValues=function(){var c=typeof window<"u"&&(window.crypto||window.msCrypto)||null;return c&&typeof c.getRandomValues=="function"?function(g){return c.getRandomValues(g)}:n}()}(t.Random||(t.Random={}));function o(s){for(var c=new Uint8Array(16),f=new Array(256),g=0;g<16;++g)f[g]="0"+g.toString(16);for(var g=16;g<256;++g)f[g]=g.toString(16);return function(){return s(c),c[6]=64|c[6]&15,c[8]=128|c[8]&63,f[c[0]]+f[c[1]]+f[c[2]]+f[c[3]]+"-"+f[c[4]]+f[c[5]]+"-"+f[c[6]]+f[c[7]]+"-"+f[c[8]]+f[c[9]]+"-"+f[c[10]]+f[c[11]]+f[c[12]]+f[c[13]]+f[c[14]]+f[c[15]]}}t.UUID=void 0,function(s){s.uuid4=o(t.Random.getRandomValues)}(t.UUID||(t.UUID={})),t.MimeData=e,t.PromiseDelegate=r,t.Token=i,Object.defineProperty(t,"__esModule",{value:!0})})});var eve=Vi((Vur,Jye)=>{function SQe(){this.__data__=[],this.size=0}Jye.exports=SQe});var $X=Vi((jur,tve)=>{function EQe(t,e){return t===e||t!==t&&e!==e}tve.exports=EQe});var UB=Vi((Hur,rve)=>{var CQe=$X();function IQe(t,e){for(var r=t.length;r--;)if(CQe(t[r][0],e))return r;return-1}rve.exports=IQe});var nve=Vi((Gur,ive)=>{var MQe=UB(),PQe=Array.prototype,RQe=PQe.splice;function BQe(t){var e=this.__data__,r=MQe(e,t);if(r<0)return!1;var i=e.length-1;return r==i?e.pop():RQe.call(e,r,1),--this.size,!0}ive.exports=BQe});var sve=Vi((Wur,ove)=>{var LQe=UB();function DQe(t){var e=this.__data__,r=LQe(e,t);return r<0?void 0:e[r][1]}ove.exports=DQe});var lve=Vi((qur,ave)=>{var OQe=UB();function FQe(t){return OQe(this.__data__,t)>-1}ave.exports=FQe});var uve=Vi(($ur,cve)=>{var kQe=UB();function NQe(t,e){var r=this.__data__,i=kQe(r,t);return i<0?(++this.size,r.push([t,e])):r[i][1]=e,this}cve.exports=NQe});var VB=Vi((Xur,hve)=>{var zQe=eve(),UQe=nve(),VQe=sve(),jQe=lve(),HQe=uve();function YE(t){var e=-1,r=t==null?0:t.length;for(this.clear();++e{var GQe=VB();function WQe(){this.__data__=new GQe,this.size=0}fve.exports=WQe});var mve=Vi((Yur,pve)=>{function qQe(t){var e=this.__data__,r=e.delete(t);return this.size=e.size,r}pve.exports=qQe});var Ave=Vi((Kur,gve)=>{function $Qe(t){return this.__data__.get(t)}gve.exports=$Qe});var yve=Vi((Qur,_ve)=>{function XQe(t){return this.__data__.has(t)}_ve.exports=XQe});var XX=Vi((Jur,vve)=>{var ZQe=typeof global=="object"&&global&&global.Object===Object&&global;vve.exports=ZQe});var S_=Vi((ehr,xve)=>{var YQe=XX(),KQe=typeof self=="object"&&self&&self.Object===Object&&self,QQe=YQe||KQe||Function("return this")();xve.exports=QQe});var D6=Vi((thr,bve)=>{var JQe=S_(),eJe=JQe.Symbol;bve.exports=eJe});var Eve=Vi((rhr,Sve)=>{var wve=D6(),Tve=Object.prototype,tJe=Tve.hasOwnProperty,rJe=Tve.toString,jB=wve?wve.toStringTag:void 0;function iJe(t){var e=tJe.call(t,jB),r=t[jB];try{t[jB]=void 0;var i=!0}catch{}var n=rJe.call(t);return i&&(e?t[jB]=r:delete t[jB]),n}Sve.exports=iJe});var Ive=Vi((ihr,Cve)=>{var nJe=Object.prototype,oJe=nJe.toString;function sJe(t){return oJe.call(t)}Cve.exports=sJe});var KE=Vi((nhr,Rve)=>{var Mve=D6(),aJe=Eve(),lJe=Ive(),cJe="[object Null]",uJe="[object Undefined]",Pve=Mve?Mve.toStringTag:void 0;function hJe(t){return t==null?t===void 0?uJe:cJe:Pve&&Pve in Object(t)?aJe(t):lJe(t)}Rve.exports=hJe});var ZX=Vi((ohr,Bve)=>{function fJe(t){var e=typeof t;return t!=null&&(e=="object"||e=="function")}Bve.exports=fJe});var YX=Vi((shr,Lve)=>{var dJe=KE(),pJe=ZX(),mJe="[object AsyncFunction]",gJe="[object Function]",AJe="[object GeneratorFunction]",_Je="[object Proxy]";function yJe(t){if(!pJe(t))return!1;var e=dJe(t);return e==gJe||e==AJe||e==mJe||e==_Je}Lve.exports=yJe});var Ove=Vi((ahr,Dve)=>{var vJe=S_(),xJe=vJe["__core-js_shared__"];Dve.exports=xJe});var Nve=Vi((lhr,kve)=>{var KX=Ove(),Fve=function(){var t=/[^.]+$/.exec(KX&&KX.keys&&KX.keys.IE_PROTO||"");return t?"Symbol(src)_1."+t:""}();function bJe(t){return!!Fve&&Fve in t}kve.exports=bJe});var QX=Vi((chr,zve)=>{var wJe=Function.prototype,TJe=wJe.toString;function SJe(t){if(t!=null){try{return TJe.call(t)}catch{}try{return t+""}catch{}}return""}zve.exports=SJe});var Vve=Vi((uhr,Uve)=>{var EJe=YX(),CJe=Nve(),IJe=ZX(),MJe=QX(),PJe=/[\\^$.*+?()[\]{}|]/g,RJe=/^\[object .+?Constructor\]$/,BJe=Function.prototype,LJe=Object.prototype,DJe=BJe.toString,OJe=LJe.hasOwnProperty,FJe=RegExp("^"+DJe.call(OJe).replace(PJe,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");function kJe(t){if(!IJe(t)||CJe(t))return!1;var e=EJe(t)?FJe:RJe;return e.test(MJe(t))}Uve.exports=kJe});var Hve=Vi((hhr,jve)=>{function NJe(t,e){return t?.[e]}jve.exports=NJe});var qw=Vi((fhr,Gve)=>{var zJe=Vve(),UJe=Hve();function VJe(t,e){var r=UJe(t,e);return zJe(r)?r:void 0}Gve.exports=VJe});var O6=Vi((dhr,Wve)=>{var jJe=qw(),HJe=S_(),GJe=jJe(HJe,"Map");Wve.exports=GJe});var HB=Vi((phr,qve)=>{var WJe=qw(),qJe=WJe(Object,"create");qve.exports=qJe});var Zve=Vi((mhr,Xve)=>{var $ve=HB();function $Je(){this.__data__=$ve?$ve(null):{},this.size=0}Xve.exports=$Je});var Kve=Vi((ghr,Yve)=>{function XJe(t){var e=this.has(t)&&delete this.__data__[t];return this.size-=e?1:0,e}Yve.exports=XJe});var Jve=Vi((Ahr,Qve)=>{var ZJe=HB(),YJe="__lodash_hash_undefined__",KJe=Object.prototype,QJe=KJe.hasOwnProperty;function JJe(t){var e=this.__data__;if(ZJe){var r=e[t];return r===YJe?void 0:r}return QJe.call(e,t)?e[t]:void 0}Qve.exports=JJe});var txe=Vi((_hr,exe)=>{var eet=HB(),tet=Object.prototype,ret=tet.hasOwnProperty;function iet(t){var e=this.__data__;return eet?e[t]!==void 0:ret.call(e,t)}exe.exports=iet});var ixe=Vi((yhr,rxe)=>{var net=HB(),oet="__lodash_hash_undefined__";function set(t,e){var r=this.__data__;return this.size+=this.has(t)?0:1,r[t]=net&&e===void 0?oet:e,this}rxe.exports=set});var oxe=Vi((vhr,nxe)=>{var aet=Zve(),cet=Kve(),uet=Jve(),het=txe(),fet=ixe();function QE(t){var e=-1,r=t==null?0:t.length;for(this.clear();++e{var sxe=oxe(),det=VB(),pet=O6();function met(){this.size=0,this.__data__={hash:new sxe,map:new(pet||det),string:new sxe}}axe.exports=met});var uxe=Vi((bhr,cxe)=>{function get(t){var e=typeof t;return e=="string"||e=="number"||e=="symbol"||e=="boolean"?t!=="__proto__":t===null}cxe.exports=get});var GB=Vi((whr,hxe)=>{var Aet=uxe();function _et(t,e){var r=t.__data__;return Aet(e)?r[typeof e=="string"?"string":"hash"]:r.map}hxe.exports=_et});var dxe=Vi((Thr,fxe)=>{var yet=GB();function vet(t){var e=yet(this,t).delete(t);return this.size-=e?1:0,e}fxe.exports=vet});var mxe=Vi((Shr,pxe)=>{var xet=GB();function bet(t){return xet(this,t).get(t)}pxe.exports=bet});var Axe=Vi((Ehr,gxe)=>{var wet=GB();function Tet(t){return wet(this,t).has(t)}gxe.exports=Tet});var yxe=Vi((Chr,_xe)=>{var Eet=GB();function Cet(t,e){var r=Eet(this,t),i=r.size;return r.set(t,e),this.size+=r.size==i?0:1,this}_xe.exports=Cet});var JX=Vi((Ihr,vxe)=>{var Iet=lxe(),Met=dxe(),Pet=mxe(),Ret=Axe(),Bet=yxe();function JE(t){var e=-1,r=t==null?0:t.length;for(this.clear();++e{var Let=VB(),Det=O6(),Oet=JX(),Fet=200;function ket(t,e){var r=this.__data__;if(r instanceof Let){var i=r.__data__;if(!Det||i.length{var Net=VB(),zet=dve(),Uet=mve(),Vet=Ave(),jet=yve(),Het=bxe();function eC(t){var e=this.__data__=new Net(t);this.size=e.size}eC.prototype.clear=zet;eC.prototype.delete=Uet;eC.prototype.get=Vet;eC.prototype.has=jet;eC.prototype.set=Het;wxe.exports=eC});var Exe=Vi((Rhr,Sxe)=>{var Get="__lodash_hash_undefined__";function Wet(t){return this.__data__.set(t,Get),this}Sxe.exports=Wet});var Ixe=Vi((Bhr,Cxe)=>{function qet(t){return this.__data__.has(t)}Cxe.exports=qet});var Pxe=Vi((Lhr,Mxe)=>{var $et=JX(),Xet=Exe(),Zet=Ixe();function F6(t){var e=-1,r=t==null?0:t.length;for(this.__data__=new $et;++e{function Yet(t,e){for(var r=-1,i=t==null?0:t.length;++r{function Ket(t,e){return t.has(e)}Lxe.exports=Ket});var eZ=Vi((Fhr,Oxe)=>{var Qet=Pxe(),Jet=Bxe(),ett=Dxe(),ttt=1,rtt=2;function itt(t,e,r,i,n,o){var s=r&ttt,c=t.length,f=e.length;if(c!=f&&!(s&&f>c))return!1;var g=o.get(t),y=o.get(e);if(g&&y)return g==e&&y==t;var I=-1,F=!0,k=r&rtt?new Qet:void 0;for(o.set(t,e),o.set(e,t);++I{var ntt=S_(),ott=ntt.Uint8Array;Fxe.exports=ott});var zxe=Vi((Nhr,Nxe)=>{function stt(t){var e=-1,r=Array(t.size);return t.forEach(function(i,n){r[++e]=[n,i]}),r}Nxe.exports=stt});var Vxe=Vi((zhr,Uxe)=>{function att(t){var e=-1,r=Array(t.size);return t.forEach(function(i){r[++e]=i}),r}Uxe.exports=att});var qxe=Vi((Uhr,Wxe)=>{var jxe=D6(),Hxe=kxe(),ltt=$X(),ctt=eZ(),utt=zxe(),htt=Vxe(),ftt=1,dtt=2,ptt="[object Boolean]",mtt="[object Date]",gtt="[object Error]",Att="[object Map]",_tt="[object Number]",ytt="[object RegExp]",vtt="[object Set]",xtt="[object String]",btt="[object Symbol]",wtt="[object ArrayBuffer]",Ttt="[object DataView]",Gxe=jxe?jxe.prototype:void 0,tZ=Gxe?Gxe.valueOf:void 0;function Stt(t,e,r,i,n,o,s){switch(r){case Ttt:if(t.byteLength!=e.byteLength||t.byteOffset!=e.byteOffset)return!1;t=t.buffer,e=e.buffer;case wtt:return!(t.byteLength!=e.byteLength||!o(new Hxe(t),new Hxe(e)));case ptt:case mtt:case _tt:return ltt(+t,+e);case gtt:return t.name==e.name&&t.message==e.message;case ytt:case xtt:return t==e+"";case Att:var c=utt;case vtt:var f=i&ftt;if(c||(c=htt),t.size!=e.size&&!f)return!1;var g=s.get(t);if(g)return g==e;i|=dtt,s.set(t,e);var y=ctt(c(t),c(e),i,n,o,s);return s.delete(t),y;case btt:if(tZ)return tZ.call(t)==tZ.call(e)}return!1}Wxe.exports=Stt});var Xxe=Vi((Vhr,$xe)=>{function Ett(t,e){for(var r=-1,i=e.length,n=t.length;++r{var Ctt=Array.isArray;Zxe.exports=Ctt});var Kxe=Vi((Hhr,Yxe)=>{var Itt=Xxe(),Mtt=k6();function Ptt(t,e,r){var i=e(t);return Mtt(t)?i:Itt(i,r(t))}Yxe.exports=Ptt});var Jxe=Vi((Ghr,Qxe)=>{function Rtt(t,e){for(var r=-1,i=t==null?0:t.length,n=0,o=[];++r{function Btt(){return[]}ebe.exports=Btt});var nbe=Vi((qhr,ibe)=>{var Ltt=Jxe(),Dtt=tbe(),Ott=Object.prototype,Ftt=Ott.propertyIsEnumerable,rbe=Object.getOwnPropertySymbols,ktt=rbe?function(t){return t==null?[]:(t=Object(t),Ltt(rbe(t),function(e){return Ftt.call(t,e)}))}:Dtt;ibe.exports=ktt});var sbe=Vi(($hr,obe)=>{function Ntt(t,e){for(var r=-1,i=Array(t);++r{function ztt(t){return t!=null&&typeof t=="object"}abe.exports=ztt});var cbe=Vi((Zhr,lbe)=>{var Utt=KE(),Vtt=tC(),jtt="[object Arguments]";function Htt(t){return Vtt(t)&&Utt(t)==jtt}lbe.exports=Htt});var dbe=Vi((Yhr,fbe)=>{var ube=cbe(),Gtt=tC(),hbe=Object.prototype,Wtt=hbe.hasOwnProperty,qtt=hbe.propertyIsEnumerable,$tt=ube(function(){return arguments}())?ube:function(t){return Gtt(t)&&Wtt.call(t,"callee")&&!qtt.call(t,"callee")};fbe.exports=$tt});var mbe=Vi((Khr,pbe)=>{function Xtt(){return!1}pbe.exports=Xtt});var rZ=Vi((WB,rC)=>{var Ztt=S_(),Ytt=mbe(),_be=typeof WB=="object"&&WB&&!WB.nodeType&&WB,gbe=_be&&typeof rC=="object"&&rC&&!rC.nodeType&&rC,Ktt=gbe&&gbe.exports===_be,Abe=Ktt?Ztt.Buffer:void 0,Qtt=Abe?Abe.isBuffer:void 0,Jtt=Qtt||Ytt;rC.exports=Jtt});var vbe=Vi((Qhr,ybe)=>{var ert=9007199254740991,trt=/^(?:0|[1-9]\d*)$/;function rrt(t,e){var r=typeof t;return e=e??ert,!!e&&(r=="number"||r!="symbol"&&trt.test(t))&&t>-1&&t%1==0&&t{var irt=9007199254740991;function nrt(t){return typeof t=="number"&&t>-1&&t%1==0&&t<=irt}xbe.exports=nrt});var wbe=Vi((efr,bbe)=>{var ort=KE(),srt=iZ(),art=tC(),lrt="[object Arguments]",crt="[object Array]",urt="[object Boolean]",hrt="[object Date]",frt="[object Error]",drt="[object Function]",prt="[object Map]",mrt="[object Number]",grt="[object Object]",Art="[object RegExp]",_rt="[object Set]",yrt="[object String]",vrt="[object WeakMap]",xrt="[object ArrayBuffer]",brt="[object DataView]",wrt="[object Float32Array]",Trt="[object Float64Array]",Srt="[object Int8Array]",Ert="[object Int16Array]",Crt="[object Int32Array]",Irt="[object Uint8Array]",Mrt="[object Uint8ClampedArray]",Prt="[object Uint16Array]",Rrt="[object Uint32Array]",Qc={};Qc[wrt]=Qc[Trt]=Qc[Srt]=Qc[Ert]=Qc[Crt]=Qc[Irt]=Qc[Mrt]=Qc[Prt]=Qc[Rrt]=!0;Qc[lrt]=Qc[crt]=Qc[xrt]=Qc[urt]=Qc[brt]=Qc[hrt]=Qc[frt]=Qc[drt]=Qc[prt]=Qc[mrt]=Qc[grt]=Qc[Art]=Qc[_rt]=Qc[yrt]=Qc[vrt]=!1;function Brt(t){return art(t)&&srt(t.length)&&!!Qc[ort(t)]}bbe.exports=Brt});var Sbe=Vi((tfr,Tbe)=>{function Lrt(t){return function(e){return t(e)}}Tbe.exports=Lrt});var Cbe=Vi((qB,iC)=>{var Drt=XX(),Ebe=typeof qB=="object"&&qB&&!qB.nodeType&&qB,$B=Ebe&&typeof iC=="object"&&iC&&!iC.nodeType&&iC,Ort=$B&&$B.exports===Ebe,nZ=Ort&&Drt.process,Frt=function(){try{var t=$B&&$B.require&&$B.require("util").types;return t||nZ&&nZ.binding&&nZ.binding("util")}catch{}}();iC.exports=Frt});var oZ=Vi((rfr,Pbe)=>{var krt=wbe(),Nrt=Sbe(),Ibe=Cbe(),Mbe=Ibe&&Ibe.isTypedArray,zrt=Mbe?Nrt(Mbe):krt;Pbe.exports=zrt});var Bbe=Vi((ifr,Rbe)=>{var Urt=sbe(),Vrt=dbe(),jrt=k6(),Hrt=rZ(),Grt=vbe(),Wrt=oZ(),qrt=Object.prototype,$rt=qrt.hasOwnProperty;function Xrt(t,e){var r=jrt(t),i=!r&&Vrt(t),n=!r&&!i&&Hrt(t),o=!r&&!i&&!n&&Wrt(t),s=r||i||n||o,c=s?Urt(t.length,String):[],f=c.length;for(var g in t)(e||$rt.call(t,g))&&!(s&&(g=="length"||n&&(g=="offset"||g=="parent")||o&&(g=="buffer"||g=="byteLength"||g=="byteOffset")||Grt(g,f)))&&c.push(g);return c}Rbe.exports=Xrt});var Dbe=Vi((nfr,Lbe)=>{var Zrt=Object.prototype;function Yrt(t){var e=t&&t.constructor,r=typeof e=="function"&&e.prototype||Zrt;return t===r}Lbe.exports=Yrt});var sZ=Vi((ofr,Obe)=>{function Krt(t,e){return function(r){return t(e(r))}}Obe.exports=Krt});var kbe=Vi((sfr,Fbe)=>{var Qrt=sZ(),Jrt=Qrt(Object.keys,Object);Fbe.exports=Jrt});var zbe=Vi((afr,Nbe)=>{var eit=Dbe(),tit=kbe(),rit=Object.prototype,iit=rit.hasOwnProperty;function nit(t){if(!eit(t))return tit(t);var e=[];for(var r in Object(t))iit.call(t,r)&&r!="constructor"&&e.push(r);return e}Nbe.exports=nit});var Vbe=Vi((lfr,Ube)=>{var oit=YX(),sit=iZ();function ait(t){return t!=null&&sit(t.length)&&!oit(t)}Ube.exports=ait});var Hbe=Vi((cfr,jbe)=>{var lit=Bbe(),cit=zbe(),uit=Vbe();function hit(t){return uit(t)?lit(t):cit(t)}jbe.exports=hit});var Wbe=Vi((ufr,Gbe)=>{var fit=Kxe(),dit=nbe(),pit=Hbe();function mit(t){return fit(t,pit,dit)}Gbe.exports=mit});var Xbe=Vi((hfr,$be)=>{var qbe=Wbe(),git=1,Ait=Object.prototype,_it=Ait.hasOwnProperty;function yit(t,e,r,i,n,o){var s=r&git,c=qbe(t),f=c.length,g=qbe(e),y=g.length;if(f!=y&&!s)return!1;for(var I=f;I--;){var F=c[I];if(!(s?F in e:_it.call(e,F)))return!1}var k=o.get(t),U=o.get(e);if(k&&U)return k==e&&U==t;var K=!0;o.set(t,e),o.set(e,t);for(var ee=s;++I{var vit=qw(),xit=S_(),bit=vit(xit,"DataView");Zbe.exports=bit});var Qbe=Vi((dfr,Kbe)=>{var wit=qw(),Tit=S_(),Sit=wit(Tit,"Promise");Kbe.exports=Sit});var e1e=Vi((pfr,Jbe)=>{var Eit=qw(),Cit=S_(),Iit=Eit(Cit,"Set");Jbe.exports=Iit});var r1e=Vi((mfr,t1e)=>{var Mit=qw(),Pit=S_(),Rit=Mit(Pit,"WeakMap");t1e.exports=Rit});var u1e=Vi((gfr,c1e)=>{var aZ=Ybe(),lZ=O6(),cZ=Qbe(),uZ=e1e(),hZ=r1e(),l1e=KE(),nC=QX(),i1e="[object Map]",Bit="[object Object]",n1e="[object Promise]",o1e="[object Set]",s1e="[object WeakMap]",a1e="[object DataView]",Lit=nC(aZ),Dit=nC(lZ),Oit=nC(cZ),Fit=nC(uZ),kit=nC(hZ),$w=l1e;(aZ&&$w(new aZ(new ArrayBuffer(1)))!=a1e||lZ&&$w(new lZ)!=i1e||cZ&&$w(cZ.resolve())!=n1e||uZ&&$w(new uZ)!=o1e||hZ&&$w(new hZ)!=s1e)&&($w=function(t){var e=l1e(t),r=e==Bit?t.constructor:void 0,i=r?nC(r):"";if(i)switch(i){case Lit:return a1e;case Dit:return i1e;case Oit:return n1e;case Fit:return o1e;case kit:return s1e}return e});c1e.exports=$w});var _1e=Vi((Afr,A1e)=>{var fZ=Txe(),Nit=eZ(),zit=qxe(),Uit=Xbe(),h1e=u1e(),f1e=k6(),d1e=rZ(),Vit=oZ(),jit=1,p1e="[object Arguments]",m1e="[object Array]",N6="[object Object]",Hit=Object.prototype,g1e=Hit.hasOwnProperty;function Git(t,e,r,i,n,o){var s=f1e(t),c=f1e(e),f=s?m1e:h1e(t),g=c?m1e:h1e(e);f=f==p1e?N6:f,g=g==p1e?N6:g;var y=f==N6,I=g==N6,F=f==g;if(F&&d1e(t)){if(!d1e(e))return!1;s=!0,y=!1}if(F&&!y)return o||(o=new fZ),s||Vit(t)?Nit(t,e,r,i,n,o):zit(t,e,f,r,i,n,o);if(!(r&jit)){var k=y&&g1e.call(t,"__wrapped__"),U=I&&g1e.call(e,"__wrapped__");if(k||U){var K=k?t.value():t,ee=U?e.value():e;return o||(o=new fZ),n(K,ee,r,i,o)}}return F?(o||(o=new fZ),Uit(t,e,r,i,n,o)):!1}A1e.exports=Git});var b1e=Vi((_fr,x1e)=>{var Wit=_1e(),y1e=tC();function v1e(t,e,r,i,n){return t===e?!0:t==null||e==null||!y1e(t)&&!y1e(e)?t!==t&&e!==e:Wit(t,e,r,i,v1e,n)}x1e.exports=v1e});var T1e=Vi((yfr,w1e)=>{var qit=b1e();function $it(t,e){return qit(t,e)}w1e.exports=$it});var E1e=Vi((vfr,S1e)=>{var Xit=sZ(),Zit=Xit(Object.getPrototypeOf,Object);S1e.exports=Zit});var M1e=Vi((xfr,I1e)=>{var Yit=KE(),Kit=E1e(),Qit=tC(),Jit="[object Object]",ent=Function.prototype,tnt=Object.prototype,C1e=ent.toString,rnt=tnt.hasOwnProperty,int=C1e.call(Object);function nnt(t){if(!Qit(t)||Yit(t)!=Jit)return!1;var e=Kit(t);if(e===null)return!0;var r=rnt.call(e,"constructor")&&e.constructor;return typeof r=="function"&&r instanceof r&&C1e.call(r)==int}I1e.exports=nnt});var KB,_Z,QB,H6,yZ,U1e,C_,ev,V1e,vZ,j1e,H1e,xZ,bZ,wZ,G1e,W1e,G6,TZ,q1e,Jc=Nt(()=>{KB="1.13.7",_Z=typeof self=="object"&&self.self===self&&self||typeof global=="object"&&global.global===global&&global||Function("return this")()||{},QB=Array.prototype,H6=Object.prototype,yZ=typeof Symbol<"u"?Symbol.prototype:null,U1e=QB.push,C_=QB.slice,ev=H6.toString,V1e=H6.hasOwnProperty,vZ=typeof ArrayBuffer<"u",j1e=typeof DataView<"u",H1e=Array.isArray,xZ=Object.keys,bZ=Object.create,wZ=vZ&&ArrayBuffer.isView,G1e=isNaN,W1e=isFinite,G6=!{toString:null}.propertyIsEnumerable("toString"),TZ=["valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"],q1e=Math.pow(2,53)-1});function Yl(t,e){return e=e==null?t.length-1:+e,function(){for(var r=Math.max(arguments.length-e,0),i=Array(r),n=0;n{});function Ud(t){var e=typeof t;return e==="function"||e==="object"&&!!t}var zx=Nt(()=>{});function W6(t){return t===null}var $1e=Nt(()=>{});function aC(t){return t===void 0}var SZ=Nt(()=>{});function lC(t){return t===!0||t===!1||ev.call(t)==="[object Boolean]"}var EZ=Nt(()=>{Jc()});function q6(t){return!!(t&&t.nodeType===1)}var X1e=Nt(()=>{});function Xa(t){var e="[object "+t+"]";return function(r){return ev.call(r)===e}}var dd=Nt(()=>{Jc()});var Xw,$6=Nt(()=>{dd();Xw=Xa("String")});var JB,CZ=Nt(()=>{dd();JB=Xa("Number")});var IZ,Z1e=Nt(()=>{dd();IZ=Xa("Date")});var MZ,Y1e=Nt(()=>{dd();MZ=Xa("RegExp")});var PZ,K1e=Nt(()=>{dd();PZ=Xa("Error")});var eL,RZ=Nt(()=>{dd();eL=Xa("Symbol")});var tL,BZ=Nt(()=>{dd();tL=Xa("ArrayBuffer")});var Q1e,lnt,dc,$m=Nt(()=>{dd();Jc();Q1e=Xa("Function"),lnt=_Z.document&&_Z.document.childNodes;typeof/./!="function"&&typeof Int8Array!="object"&&typeof lnt!="function"&&(Q1e=function(t){return typeof t=="function"||!1});dc=Q1e});var LZ,J1e=Nt(()=>{dd();LZ=Xa("Object")});var X6,cC,uC=Nt(()=>{Jc();J1e();X6=j1e&&(!/\[native code\]/.test(String(DataView))||LZ(new DataView(new ArrayBuffer(8)))),cC=typeof Map<"u"&&LZ(new Map)});function unt(t){return t!=null&&dc(t.getInt8)&&tL(t.buffer)}var cnt,Ux,Z6=Nt(()=>{dd();$m();BZ();uC();cnt=Xa("DataView");Ux=X6?unt:cnt});var yp,Vx=Nt(()=>{Jc();dd();yp=H1e||Xa("Array")});function pd(t,e){return t!=null&&V1e.call(t,e)}var tv=Nt(()=>{Jc()});var DZ,Zw,Y6=Nt(()=>{dd();tv();DZ=Xa("Arguments");(function(){DZ(arguments)||(DZ=function(t){return pd(t,"callee")})})();Zw=DZ});function K6(t){return!eL(t)&&W1e(t)&&!isNaN(parseFloat(t))}var ewe=Nt(()=>{Jc();RZ()});function hC(t){return JB(t)&&G1e(t)}var OZ=Nt(()=>{Jc();CZ()});function fC(t){return function(){return t}}var FZ=Nt(()=>{});function rL(t){return function(e){var r=t(e);return typeof r=="number"&&r>=0&&r<=q1e}}var kZ=Nt(()=>{Jc()});function iL(t){return function(e){return e?.[t]}}var NZ=Nt(()=>{});var Yw,Q6=Nt(()=>{NZ();Yw=iL("byteLength")});var twe,rwe=Nt(()=>{kZ();Q6();twe=rL(Yw)});function fnt(t){return wZ?wZ(t)&&!Ux(t):twe(t)&&hnt.test(ev.call(t))}var hnt,nL,zZ=Nt(()=>{Jc();Z6();FZ();rwe();hnt=/\[object ((I|Ui)nt(8|16|32)|Float(32|64)|Uint8Clamped|Big(I|Ui)nt64)Array\]/;nL=vZ?fnt:fC(!1)});var kc,Xm=Nt(()=>{NZ();kc=iL("length")});function dnt(t){for(var e={},r=t.length,i=0;i{Jc();$m();tv()});function ba(t){if(!Ud(t))return[];if(xZ)return xZ(t);var e=[];for(var r in t)pd(t,r)&&e.push(r);return G6&&oL(t,e),e}var Uf=Nt(()=>{zx();Jc();tv();UZ()});function J6(t){if(t==null)return!0;var e=kc(t);return typeof e=="number"&&(yp(t)||Xw(t)||Zw(t))?e===0:kc(ba(t))===0}var iwe=Nt(()=>{Xm();Vx();$6();Y6();Uf()});function dC(t,e){var r=ba(e),i=r.length;if(t==null)return!i;for(var n=Object(t),o=0;o{Uf()});function Ns(t){if(t instanceof Ns)return t;if(!(this instanceof Ns))return new Ns(t);this._wrapped=t}var cm=Nt(()=>{Jc();Ns.VERSION=KB;Ns.prototype.value=function(){return this._wrapped};Ns.prototype.valueOf=Ns.prototype.toJSON=Ns.prototype.value;Ns.prototype.toString=function(){return String(this._wrapped)}});function e5(t){return new Uint8Array(t.buffer||t,t.byteOffset||0,Yw(t))}var nwe=Nt(()=>{Q6()});function jZ(t,e,r,i){if(t===e)return t!==0||1/t===1/e;if(t==null||e==null)return!1;if(t!==t)return e!==e;var n=typeof t;return n!=="function"&&n!=="object"&&typeof e!="object"?!1:swe(t,e,r,i)}function swe(t,e,r,i){t instanceof Ns&&(t=t._wrapped),e instanceof Ns&&(e=e._wrapped);var n=ev.call(t);if(n!==ev.call(e))return!1;if(X6&&n=="[object Object]"&&Ux(t)){if(!Ux(e))return!1;n=owe}switch(n){case"[object RegExp]":case"[object String]":return""+t==""+e;case"[object Number]":return+t!=+t?+e!=+e:+t==0?1/+t===1/e:+t==+e;case"[object Date]":case"[object Boolean]":return+t==+e;case"[object Symbol]":return yZ.valueOf.call(t)===yZ.valueOf.call(e);case"[object ArrayBuffer]":case owe:return swe(e5(t),e5(e),r,i)}var o=n==="[object Array]";if(!o&&nL(t)){var s=Yw(t);if(s!==Yw(e))return!1;if(t.buffer===e.buffer&&t.byteOffset===e.byteOffset)return!0;o=!0}if(!o){if(typeof t!="object"||typeof e!="object")return!1;var c=t.constructor,f=e.constructor;if(c!==f&&!(dc(c)&&c instanceof c&&dc(f)&&f instanceof f)&&"constructor"in t&&"constructor"in e)return!1}r=r||[],i=i||[];for(var g=r.length;g--;)if(r[g]===t)return i[g]===e;if(r.push(t),i.push(e),o){if(g=t.length,g!==e.length)return!1;for(;g--;)if(!jZ(t[g],e[g],r,i))return!1}else{var y=ba(t),I;if(g=y.length,ba(e).length!==g)return!1;for(;g--;)if(I=y[g],!(pd(e,I)&&jZ(t[I],e[I],r,i)))return!1}return r.pop(),i.pop(),!0}function t5(t,e){return jZ(t,e)}var owe,awe=Nt(()=>{cm();Jc();Q6();zZ();$m();uC();Z6();Uf();tv();nwe();owe="[object DataView]"});function Jg(t){if(!Ud(t))return[];var e=[];for(var r in t)e.push(r);return G6&&oL(t,e),e}var pC=Nt(()=>{zx();Jc();UZ()});function mC(t){var e=kc(t);return function(r){if(r==null)return!1;var i=Jg(r);if(kc(i))return!1;for(var n=0;n{Xm();$m();pC();HZ="forEach",lwe="has",GZ=["clear","delete"],cwe=["get",lwe,"set"],uwe=GZ.concat(HZ,cwe),WZ=GZ.concat(cwe),hwe=["add"].concat(GZ,HZ,lwe)});var qZ,fwe=Nt(()=>{dd();uC();r5();qZ=cC?mC(uwe):Xa("Map")});var $Z,dwe=Nt(()=>{dd();uC();r5();$Z=cC?mC(WZ):Xa("WeakMap")});var XZ,pwe=Nt(()=>{dd();uC();r5();XZ=cC?mC(hwe):Xa("Set")});var ZZ,mwe=Nt(()=>{dd();ZZ=Xa("WeakSet")});function um(t){for(var e=ba(t),r=e.length,i=Array(r),n=0;n{Uf()});function i5(t){for(var e=ba(t),r=e.length,i=Array(r),n=0;n{Uf()});function gC(t){for(var e={},r=ba(t),i=0,n=r.length;i{Uf()});function Qw(t){var e=[];for(var r in t)dc(t[r])&&e.push(r);return e.sort()}var KZ=Nt(()=>{$m()});function Jw(t,e){return function(r){var i=arguments.length;if(e&&(r=Object(r)),i<2||r==null)return r;for(var n=1;n{});var sL,QZ=Nt(()=>{n5();pC();sL=Jw(Jg)});var jx,o5=Nt(()=>{n5();Uf();jx=Jw(ba)});var aL,JZ=Nt(()=>{n5();pC();aL=Jw(Jg,!0)});function pnt(){return function(){}}function lL(t){if(!Ud(t))return{};if(bZ)return bZ(t);var e=pnt();e.prototype=t;var r=new e;return e.prototype=null,r}var eY=Nt(()=>{zx();Jc()});function s5(t,e){var r=lL(t);return e&&jx(r,e),r}var Awe=Nt(()=>{eY();o5()});function a5(t){return Ud(t)?yp(t)?t.slice():sL({},t):t}var _we=Nt(()=>{zx();Vx();QZ()});function l5(t,e){return e(t),t}var ywe=Nt(()=>{});function cL(t){return yp(t)?t:[t]}var tY=Nt(()=>{cm();Vx();Ns.toPath=cL});function Z0(t){return Ns.toPath(t)}var AC=Nt(()=>{cm();tY()});function e2(t,e){for(var r=e.length,i=0;i{});function _C(t,e,r){var i=e2(t,Z0(e));return aC(i)?r:i}var rY=Nt(()=>{AC();c5();SZ()});function u5(t,e){e=Z0(e);for(var r=e.length,i=0;i{tv();AC()});function Hx(t){return t}var h5=Nt(()=>{});function Y0(t){return t=jx({},t),function(e){return dC(e,t)}}var uL=Nt(()=>{o5();VZ()});function Gx(t){return t=Z0(t),function(e){return e2(e,t)}}var f5=Nt(()=>{c5();AC()});function K0(t,e,r){if(e===void 0)return t;switch(r??3){case 1:return function(i){return t.call(e,i)};case 3:return function(i,n,o){return t.call(e,i,n,o)};case 4:return function(i,n,o,s){return t.call(e,i,n,o,s)}}return function(){return t.apply(e,arguments)}}var yC=Nt(()=>{});function hL(t,e,r){return t==null?Hx:dc(t)?K0(t,e,r):Ud(t)&&!yp(t)?Y0(t):Gx(t)}var iY=Nt(()=>{h5();$m();zx();Vx();uL();f5();yC()});function t2(t,e){return hL(t,e,1/0)}var nY=Nt(()=>{cm();iY();Ns.iteratee=t2});function Kl(t,e,r){return Ns.iteratee!==t2?Ns.iteratee(t,e):hL(t,e,r)}var vp=Nt(()=>{cm();iY();nY()});function d5(t,e,r){e=Kl(e,r);for(var i=ba(t),n=i.length,o={},s=0;s{vp();Uf()});function vC(){}var oY=Nt(()=>{});function p5(t){return t==null?vC:function(e){return _C(t,e)}}var bwe=Nt(()=>{oY();rY()});function m5(t,e,r){var i=Array(Math.max(0,t));e=K0(e,r,1);for(var n=0;n{yC()});function r2(t,e){return e==null&&(e=t,t=0),t+Math.floor(Math.random()*(e-t+1))}var sY=Nt(()=>{});var rv,g5=Nt(()=>{rv=Date.now||function(){return new Date().getTime()}});function fL(t){var e=function(o){return t[o]},r="(?:"+ba(t).join("|")+")",i=RegExp(r),n=RegExp(r,"g");return function(o){return o=o==null?"":""+o,i.test(o)?o.replace(n,e):o}}var aY=Nt(()=>{Uf()});var A5,lY=Nt(()=>{A5={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"}});var cY,Twe=Nt(()=>{aY();lY();cY=fL(A5)});var Swe,Ewe=Nt(()=>{YZ();lY();Swe=gC(A5)});var uY,Cwe=Nt(()=>{aY();Ewe();uY=fL(Swe)});var hY,fY=Nt(()=>{cm();hY=Ns.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g}});function Ant(t){return"\\"+mnt[t]}function _5(t,e,r){!e&&r&&(e=r),e=aL({},e,Ns.templateSettings);var i=RegExp([(e.escape||dY).source,(e.interpolate||dY).source,(e.evaluate||dY).source].join("|")+"|$","g"),n=0,o="__p+='";t.replace(i,function(g,y,I,F,k){return o+=t.slice(n,k).replace(gnt,Ant),n=k+g.length,y?o+=`'+ +((__t=(`+y+`))==null?'':_.escape(__t))+ +'`:I?o+=`'+ +((__t=(`+I+`))==null?'':__t)+ +'`:F&&(o+=`'; +`+F+` +__p+='`),g}),o+=`'; +`;var s=e.variable;if(s){if(!_nt.test(s))throw new Error("variable is not a bare identifier: "+s)}else o=`with(obj||{}){ +`+o+`} +`,s="obj";o=`var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');}; +`+o+`return __p; +`;var c;try{c=new Function(s,"_",o)}catch(g){throw g.source=o,g}var f=function(g){return c.call(this,g,Ns)};return f.source="function("+s+`){ +`+o+"}",f}var dY,mnt,gnt,_nt,Iwe=Nt(()=>{JZ();cm();fY();dY=/(.)^/,mnt={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},gnt=/\\|'|\r|\n|\u2028|\u2029/g;_nt=/^\s*(\w|\$)+\s*$/});function y5(t,e,r){e=Z0(e);var i=e.length;if(!i)return dc(r)?r.call(t):r;for(var n=0;n{$m();AC()});function v5(t){var e=++ynt+"";return t?t+e:e}var ynt,Pwe=Nt(()=>{ynt=0});function x5(t){var e=Ns(t);return e._chain=!0,e}var Rwe=Nt(()=>{cm()});function dL(t,e,r,i,n){if(!(i instanceof e))return t.apply(r,n);var o=lL(t.prototype),s=t.apply(o,n);return Ud(s)?s:o}var pY=Nt(()=>{eY();zx()});var mY,iv,pL=Nt(()=>{lm();pY();cm();mY=Yl(function(t,e){var r=mY.placeholder,i=function(){for(var n=0,o=e.length,s=Array(o),c=0;c{lm();$m();pY();mL=Yl(function(t,e,r){if(!dc(t))throw new TypeError("Bind must be called on a function");var i=Yl(function(n){return dL(t,i,e,this,r.concat(n))});return i})});var Nc,hm=Nt(()=>{kZ();Xm();Nc=rL(kc)});function fm(t,e,r,i){if(i=i||[],!e&&e!==0)e=1/0;else if(e<=0)return i.concat(t);for(var n=i.length,o=0,s=kc(t);o1)fm(c,e-1,r,i),n=i.length;else for(var f=0,g=c.length;f{Xm();hm();Vx();Y6()});var AY,Bwe=Nt(()=>{lm();i2();gY();AY=Yl(function(t,e){e=fm(e,!1,!1);var r=e.length;if(r<1)throw new Error("bindAll must be passed function names");for(;r--;){var i=e[r];t[i]=mL(t[i],t)}return t})});function b5(t,e){var r=function(i){var n=r.cache,o=""+(e?e.apply(this,arguments):i);return pd(n,o)||(n[o]=t.apply(this,arguments)),n[o]};return r.cache={},r}var Lwe=Nt(()=>{tv()});var gL,_Y=Nt(()=>{lm();gL=Yl(function(t,e,r){return setTimeout(function(){return t.apply(null,r)},e)})});var yY,Dwe=Nt(()=>{pL();_Y();cm();yY=iv(gL,Ns,1)});function w5(t,e,r){var i,n,o,s,c=0;r||(r={});var f=function(){c=r.leading===!1?0:rv(),i=null,s=t.apply(n,o),i||(n=o=null)},g=function(){var y=rv();!c&&r.leading===!1&&(c=y);var I=e-(y-c);return n=this,o=arguments,I<=0||I>e?(i&&(clearTimeout(i),i=null),c=y,s=t.apply(n,o),i||(n=o=null)):!i&&r.trailing!==!1&&(i=setTimeout(f,I)),s};return g.cancel=function(){clearTimeout(i),c=0,i=n=o=null},g}var Owe=Nt(()=>{g5()});function T5(t,e,r){var i,n,o,s,c,f=function(){var y=rv()-n;e>y?i=setTimeout(f,e-y):(i=null,r||(s=t.apply(c,o)),i||(o=c=null))},g=Yl(function(y){return c=this,o=y,n=rv(),i||(i=setTimeout(f,e),r&&(s=t.apply(c,o))),s});return g.cancel=function(){clearTimeout(i),i=o=c=null},g}var Fwe=Nt(()=>{lm();g5()});function S5(t,e){return iv(e,t)}var kwe=Nt(()=>{pL()});function Wx(t){return function(){return!t.apply(this,arguments)}}var E5=Nt(()=>{});function C5(){var t=arguments,e=t.length-1;return function(){for(var r=e,i=t[e].apply(this,arguments);r--;)i=t[r].call(this,i);return i}}var Nwe=Nt(()=>{});function I5(t,e){return function(){if(--t<1)return e.apply(this,arguments)}}var zwe=Nt(()=>{});function xC(t,e){var r;return function(){return--t>0&&(r=e.apply(this,arguments)),t<=1&&(e=null),r}}var vY=Nt(()=>{});var xY,Uwe=Nt(()=>{pL();vY();xY=iv(xC,2)});function bC(t,e,r){e=Kl(e,r);for(var i=ba(t),n,o=0,s=i.length;o{vp();Uf()});function AL(t){return function(e,r,i){r=Kl(r,i);for(var n=kc(e),o=t>0?0:n-1;o>=0&&o{vp();Xm()});var n2,M5=Nt(()=>{wY();n2=AL(1)});var _L,TY=Nt(()=>{wY();_L=AL(-1)});function wC(t,e,r,i){r=Kl(r,i,1);for(var n=r(e),o=0,s=kc(t);o{vp();Xm()});function yL(t,e,r){return function(i,n,o){var s=0,c=kc(i);if(typeof o=="number")t>0?s=o>=0?o:Math.max(o+c,s):c=o>=0?Math.min(o+1,c):o+c+1;else if(r&&o&&c)return o=r(i,n),i[o]===n?o:-1;if(n!==n)return o=e(C_.call(i,s,c),hC),o>=0?o+s:-1;for(o=t>0?s:c-1;o>=0&&o{Xm();Jc();OZ()});var vL,CY=Nt(()=>{SY();M5();EY();vL=yL(1,n2,wC)});var IY,Vwe=Nt(()=>{TY();EY();IY=yL(-1,_L)});function o2(t,e,r){var i=Nc(t)?n2:bC,n=i(t,e,r);if(n!==void 0&&n!==-1)return t[n]}var MY=Nt(()=>{hm();M5();bY()});function P5(t,e){return o2(t,Y0(e))}var jwe=Nt(()=>{MY();uL()});function Vf(t,e,r){e=K0(e,r);var i,n;if(Nc(t))for(i=0,n=t.length;i{yC();hm();Uf()});function xp(t,e,r){e=Kl(e,r);for(var i=!Nc(t)&&ba(t),n=(i||t).length,o=Array(n),s=0;s{vp();hm();Uf()});function xL(t){var e=function(r,i,n,o){var s=!Nc(r)&&ba(r),c=(s||r).length,f=t>0?0:c-1;for(o||(n=r[s?s[f]:f],f+=t);f>=0&&f=3;return e(r,K0(i,o,4),n,s)}}var PY=Nt(()=>{hm();Uf();yC()});var bL,Hwe=Nt(()=>{PY();bL=xL(1)});var R5,Gwe=Nt(()=>{PY();R5=xL(-1)});function Zm(t,e,r){var i=[];return e=Kl(e,r),Vf(t,function(n,o,s){e(n,o,s)&&i.push(n)}),i}var TC=Nt(()=>{vp();qx()});function B5(t,e,r){return Zm(t,Wx(Kl(e)),r)}var Wwe=Nt(()=>{TC();E5();vp()});function wL(t,e,r){e=Kl(e,r);for(var i=!Nc(t)&&ba(t),n=(i||t).length,o=0;o{vp();hm();Uf()});function TL(t,e,r){e=Kl(e,r);for(var i=!Nc(t)&&ba(t),n=(i||t).length,o=0;o{vp();hm();Uf()});function Vd(t,e,r,i){return Nc(t)||(t=um(t)),(typeof r!="number"||i)&&(r=0),vL(t,e,r)>=0}var SC=Nt(()=>{hm();Kw();CY()});var RY,Xwe=Nt(()=>{lm();$m();s2();c5();AC();RY=Yl(function(t,e,r){var i,n;return dc(e)?n=e:(e=Z0(e),i=e.slice(0,-1),e=e[e.length-1]),xp(t,function(o){var s=n;if(!s){if(i&&i.length&&(o=e2(o,i)),o==null)return;s=o[e]}return s==null?s:s.apply(o,r)})})});function $x(t,e){return xp(t,Gx(e))}var L5=Nt(()=>{s2();f5()});function D5(t,e){return Zm(t,Y0(e))}var Zwe=Nt(()=>{TC();uL()});function EC(t,e,r){var i=-1/0,n=-1/0,o,s;if(e==null||typeof e=="number"&&typeof t[0]!="object"&&t!=null){t=Nc(t)?t:um(t);for(var c=0,f=t.length;ci&&(i=o)}else e=Kl(e,r),Vf(t,function(g,y,I){s=e(g,y,I),(s>n||s===-1/0&&i===-1/0)&&(i=g,n=s)});return i}var BY=Nt(()=>{hm();Kw();vp();qx()});function O5(t,e,r){var i=1/0,n=1/0,o,s;if(e==null||typeof e=="number"&&typeof t[0]!="object"&&t!=null){t=Nc(t)?t:um(t);for(var c=0,f=t.length;c{hm();Kw();vp();qx()});function CC(t){return t?yp(t)?C_.call(t):Xw(t)?t.match(vnt):Nc(t)?xp(t,Hx):um(t):[]}var vnt,LY=Nt(()=>{Vx();Jc();$6();hm();s2();h5();Kw();vnt=/[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g});function IC(t,e,r){if(e==null||r)return Nc(t)||(t=um(t)),t[r2(t.length-1)];var i=CC(t),n=kc(i);e=Math.max(Math.min(e,n),0);for(var o=n-1,s=0;s{hm();Kw();Xm();sY();LY()});function F5(t){return IC(t,1/0)}var Kwe=Nt(()=>{DY()});function k5(t,e,r){var i=0;return e=Kl(e,r),$x(xp(t,function(n,o,s){return{value:n,index:i++,criteria:e(n,o,s)}}).sort(function(n,o){var s=n.criteria,c=o.criteria;if(s!==c){if(s>c||s===void 0)return 1;if(s{vp();L5();s2()});function nv(t,e){return function(r,i,n){var o=e?[[],[]]:{};return i=Kl(i,n),Vf(r,function(s,c){var f=i(s,c,r);t(o,s,f)}),o}}var SL=Nt(()=>{vp();qx()});var OY,Jwe=Nt(()=>{SL();tv();OY=nv(function(t,e,r){pd(t,r)?t[r].push(e):t[r]=[e]})});var FY,e2e=Nt(()=>{SL();FY=nv(function(t,e,r){t[r]=e})});var kY,t2e=Nt(()=>{SL();tv();kY=nv(function(t,e,r){pd(t,r)?t[r]++:t[r]=1})});var NY,r2e=Nt(()=>{SL();NY=nv(function(t,e,r){t[r?0:1].push(e)},!0)});function N5(t){return t==null?0:Nc(t)?t.length:ba(t).length}var i2e=Nt(()=>{hm();Uf()});function zY(t,e,r){return e in r}var n2e=Nt(()=>{});var EL,UY=Nt(()=>{lm();$m();yC();pC();n2e();i2();EL=Yl(function(t,e){var r={},i=e[0];if(t==null)return r;dc(i)?(e.length>1&&(i=K0(i,e[1])),e=Jg(t)):(i=zY,e=fm(e,!1,!1),t=Object(t));for(var n=0,o=e.length;n{lm();$m();E5();s2();i2();SC();UY();VY=Yl(function(t,e){var r=e[0],i;return dc(r)?(r=Wx(r),e.length>1&&(i=e[1])):(e=xp(fm(e,!1,!1),String),r=function(n,o){return!Vd(e,o)}),EL(t,r,i)})});function MC(t,e,r){return C_.call(t,0,Math.max(0,t.length-(e==null||r?1:e)))}var jY=Nt(()=>{Jc()});function PC(t,e,r){return t==null||t.length<1?e==null||r?void 0:[]:e==null||r?t[0]:MC(t,t.length-e)}var s2e=Nt(()=>{jY()});function Xx(t,e,r){return C_.call(t,e==null||r?1:e)}var HY=Nt(()=>{Jc()});function z5(t,e,r){return t==null||t.length<1?e==null||r?void 0:[]:e==null||r?t[t.length-1]:Xx(t,Math.max(0,t.length-e))}var a2e=Nt(()=>{HY()});function U5(t){return Zm(t,Boolean)}var l2e=Nt(()=>{TC()});function V5(t,e){return fm(t,e,!1)}var c2e=Nt(()=>{i2()});var CL,GY=Nt(()=>{lm();i2();TC();SC();CL=Yl(function(t,e){return e=fm(e,!0,!0),Zm(t,function(r){return!Vd(e,r)})})});var WY,u2e=Nt(()=>{lm();GY();WY=Yl(function(t,e){return CL(t,e)})});function a2(t,e,r,i){lC(e)||(i=r,r=e,e=!1),r!=null&&(r=Kl(r,i));for(var n=[],o=[],s=0,c=kc(t);s{EZ();vp();Xm();SC()});var $Y,h2e=Nt(()=>{lm();qY();i2();$Y=Yl(function(t){return a2(fm(t,!0,!0))})});function j5(t){for(var e=[],r=arguments.length,i=0,n=kc(t);i{Xm();SC()});function l2(t){for(var e=t&&EC(t,kc).length||0,r=Array(e),i=0;i{BY();Xm();L5()});var ZY,d2e=Nt(()=>{lm();XY();ZY=Yl(l2)});function H5(t,e){for(var r={},i=0,n=kc(t);i{Xm()});function G5(t,e,r){e==null&&(e=t||0,t=0),r||(r=e{});function W5(t,e){if(e==null||e<1)return[];for(var r=[],i=0,n=t.length;i{Jc()});function RC(t,e){return t._chain?Ns(e).chain():e}var YY=Nt(()=>{cm()});function BC(t){return Vf(Qw(t),function(e){var r=Ns[e]=t[e];Ns.prototype[e]=function(){var i=[this._wrapped];return U1e.apply(i,arguments),RC(this,r.apply(Ns,i))}}),Ns}var A2e=Nt(()=>{cm();qx();KZ();Jc();YY()});var _2e,y2e=Nt(()=>{cm();qx();Jc();YY();Vf(["pop","push","reverse","shift","sort","splice","unshift"],function(t){var e=QB[t];Ns.prototype[t]=function(){var r=this._wrapped;return r!=null&&(e.apply(r,arguments),(t==="shift"||t==="splice")&&r.length===0&&delete r[0]),RC(this,r)}});Vf(["concat","join","slice"],function(t){var e=QB[t];Ns.prototype[t]=function(){var r=this._wrapped;return r!=null&&(r=e.apply(r,arguments)),RC(this,r)}});_2e=Ns});var KY={};Ua(KY,{VERSION:()=>KB,after:()=>I5,all:()=>wL,allKeys:()=>Jg,any:()=>TL,assign:()=>jx,before:()=>xC,bind:()=>mL,bindAll:()=>AY,chain:()=>x5,chunk:()=>W5,clone:()=>a5,collect:()=>xp,compact:()=>U5,compose:()=>C5,constant:()=>fC,contains:()=>Vd,countBy:()=>kY,create:()=>s5,debounce:()=>T5,default:()=>_2e,defaults:()=>aL,defer:()=>yY,delay:()=>gL,detect:()=>o2,difference:()=>CL,drop:()=>Xx,each:()=>Vf,escape:()=>cY,every:()=>wL,extend:()=>sL,extendOwn:()=>jx,filter:()=>Zm,find:()=>o2,findIndex:()=>n2,findKey:()=>bC,findLastIndex:()=>_L,findWhere:()=>P5,first:()=>PC,flatten:()=>V5,foldl:()=>bL,foldr:()=>R5,forEach:()=>Vf,functions:()=>Qw,get:()=>_C,groupBy:()=>OY,has:()=>u5,head:()=>PC,identity:()=>Hx,include:()=>Vd,includes:()=>Vd,indexBy:()=>FY,indexOf:()=>vL,initial:()=>MC,inject:()=>bL,intersection:()=>j5,invert:()=>gC,invoke:()=>RY,isArguments:()=>Zw,isArray:()=>yp,isArrayBuffer:()=>tL,isBoolean:()=>lC,isDataView:()=>Ux,isDate:()=>IZ,isElement:()=>q6,isEmpty:()=>J6,isEqual:()=>t5,isError:()=>PZ,isFinite:()=>K6,isFunction:()=>dc,isMap:()=>qZ,isMatch:()=>dC,isNaN:()=>hC,isNull:()=>W6,isNumber:()=>JB,isObject:()=>Ud,isRegExp:()=>MZ,isSet:()=>XZ,isString:()=>Xw,isSymbol:()=>eL,isTypedArray:()=>nL,isUndefined:()=>aC,isWeakMap:()=>$Z,isWeakSet:()=>ZZ,iteratee:()=>t2,keys:()=>ba,last:()=>z5,lastIndexOf:()=>IY,map:()=>xp,mapObject:()=>d5,matcher:()=>Y0,matches:()=>Y0,max:()=>EC,memoize:()=>b5,methods:()=>Qw,min:()=>O5,mixin:()=>BC,negate:()=>Wx,noop:()=>vC,now:()=>rv,object:()=>H5,omit:()=>VY,once:()=>xY,pairs:()=>i5,partial:()=>iv,partition:()=>NY,pick:()=>EL,pluck:()=>$x,property:()=>Gx,propertyOf:()=>p5,random:()=>r2,range:()=>G5,reduce:()=>bL,reduceRight:()=>R5,reject:()=>B5,rest:()=>Xx,restArguments:()=>Yl,result:()=>y5,sample:()=>IC,select:()=>Zm,shuffle:()=>F5,size:()=>N5,some:()=>TL,sortBy:()=>k5,sortedIndex:()=>wC,tail:()=>Xx,take:()=>PC,tap:()=>l5,template:()=>_5,templateSettings:()=>hY,throttle:()=>w5,times:()=>m5,toArray:()=>CC,toPath:()=>cL,transpose:()=>l2,unescape:()=>uY,union:()=>$Y,uniq:()=>a2,unique:()=>a2,uniqueId:()=>v5,unzip:()=>l2,values:()=>um,where:()=>D5,without:()=>WY,wrap:()=>S5,zip:()=>ZY});var q5=Nt(()=>{Jc();lm();zx();$1e();SZ();EZ();X1e();$6();CZ();Z1e();Y1e();K1e();RZ();BZ();Z6();Vx();$m();Y6();ewe();OZ();zZ();iwe();VZ();awe();fwe();dwe();pwe();mwe();Uf();pC();Kw();gwe();YZ();KZ();QZ();o5();JZ();Awe();_we();ywe();rY();vwe();xwe();h5();FZ();oY();tY();f5();bwe();uL();wwe();sY();g5();Twe();Cwe();fY();Iwe();Mwe();Pwe();Rwe();nY();pL();gY();Bwe();Lwe();_Y();Dwe();Owe();Fwe();kwe();E5();Nwe();zwe();vY();Uwe();bY();M5();TY();SY();CY();Vwe();MY();jwe();qx();s2();Hwe();Gwe();TC();Wwe();qwe();$we();SC();Xwe();L5();Zwe();BY();Ywe();Kwe();DY();Qwe();Jwe();e2e();t2e();r2e();LY();i2e();UY();o2e();s2e();jY();a2e();HY();l2e();c2e();u2e();qY();h2e();f2e();GY();XY();d2e();p2e();m2e();g2e();A2e();y2e()});var QY,v2e,x2e=Nt(()=>{q5();q5();QY=BC(KY);QY._=QY;v2e=QY});var b2e={};Ua(b2e,{VERSION:()=>KB,after:()=>I5,all:()=>wL,allKeys:()=>Jg,any:()=>TL,assign:()=>jx,before:()=>xC,bind:()=>mL,bindAll:()=>AY,chain:()=>x5,chunk:()=>W5,clone:()=>a5,collect:()=>xp,compact:()=>U5,compose:()=>C5,constant:()=>fC,contains:()=>Vd,countBy:()=>kY,create:()=>s5,debounce:()=>T5,default:()=>v2e,defaults:()=>aL,defer:()=>yY,delay:()=>gL,detect:()=>o2,difference:()=>CL,drop:()=>Xx,each:()=>Vf,escape:()=>cY,every:()=>wL,extend:()=>sL,extendOwn:()=>jx,filter:()=>Zm,find:()=>o2,findIndex:()=>n2,findKey:()=>bC,findLastIndex:()=>_L,findWhere:()=>P5,first:()=>PC,flatten:()=>V5,foldl:()=>bL,foldr:()=>R5,forEach:()=>Vf,functions:()=>Qw,get:()=>_C,groupBy:()=>OY,has:()=>u5,head:()=>PC,identity:()=>Hx,include:()=>Vd,includes:()=>Vd,indexBy:()=>FY,indexOf:()=>vL,initial:()=>MC,inject:()=>bL,intersection:()=>j5,invert:()=>gC,invoke:()=>RY,isArguments:()=>Zw,isArray:()=>yp,isArrayBuffer:()=>tL,isBoolean:()=>lC,isDataView:()=>Ux,isDate:()=>IZ,isElement:()=>q6,isEmpty:()=>J6,isEqual:()=>t5,isError:()=>PZ,isFinite:()=>K6,isFunction:()=>dc,isMap:()=>qZ,isMatch:()=>dC,isNaN:()=>hC,isNull:()=>W6,isNumber:()=>JB,isObject:()=>Ud,isRegExp:()=>MZ,isSet:()=>XZ,isString:()=>Xw,isSymbol:()=>eL,isTypedArray:()=>nL,isUndefined:()=>aC,isWeakMap:()=>$Z,isWeakSet:()=>ZZ,iteratee:()=>t2,keys:()=>ba,last:()=>z5,lastIndexOf:()=>IY,map:()=>xp,mapObject:()=>d5,matcher:()=>Y0,matches:()=>Y0,max:()=>EC,memoize:()=>b5,methods:()=>Qw,min:()=>O5,mixin:()=>BC,negate:()=>Wx,noop:()=>vC,now:()=>rv,object:()=>H5,omit:()=>VY,once:()=>xY,pairs:()=>i5,partial:()=>iv,partition:()=>NY,pick:()=>EL,pluck:()=>$x,property:()=>Gx,propertyOf:()=>p5,random:()=>r2,range:()=>G5,reduce:()=>bL,reduceRight:()=>R5,reject:()=>B5,rest:()=>Xx,restArguments:()=>Yl,result:()=>y5,sample:()=>IC,select:()=>Zm,shuffle:()=>F5,size:()=>N5,some:()=>TL,sortBy:()=>k5,sortedIndex:()=>wC,tail:()=>Xx,take:()=>PC,tap:()=>l5,template:()=>_5,templateSettings:()=>hY,throttle:()=>w5,times:()=>m5,toArray:()=>CC,toPath:()=>cL,transpose:()=>l2,unescape:()=>uY,union:()=>$Y,uniq:()=>a2,unique:()=>a2,uniqueId:()=>v5,unzip:()=>l2,values:()=>um,where:()=>D5,without:()=>WY,wrap:()=>S5,zip:()=>ZY});var w2e=Nt(()=>{x2e();q5()});var JY=Vi((T2e,$5)=>{(function(t,e){"use strict";typeof $5=="object"&&typeof $5.exports=="object"?$5.exports=t.document?e(t,!0):function(r){if(!r.document)throw new Error("jQuery requires a window with a document");return e(r)}:e(t)})(typeof window<"u"?window:T2e,function(t,e){"use strict";var r=[],i=Object.getPrototypeOf,n=r.slice,o=r.flat?function(q){return r.flat.call(q)}:function(q){return r.concat.apply([],q)},s=r.push,c=r.indexOf,f={},g=f.toString,y=f.hasOwnProperty,I=y.toString,F=I.call(Object),k={},U=function(oe){return typeof oe=="function"&&typeof oe.nodeType!="number"&&typeof oe.item!="function"},K=function(oe){return oe!=null&&oe===oe.window},ee=t.document,he={type:!0,src:!0,nonce:!0,noModule:!0};function xe(q,oe,pe){pe=pe||ee;var be,He,We=pe.createElement("script");if(We.text=q,oe)for(be in he)He=oe[be]||oe.getAttribute&&oe.getAttribute(be),He&&We.setAttribute(be,He);pe.head.appendChild(We).parentNode.removeChild(We)}function me(q){return q==null?q+"":typeof q=="object"||typeof q=="function"?f[g.call(q)]||"object":typeof q}var Se="3.7.1",Oe=/HTML$/i,ne=function(q,oe){return new ne.fn.init(q,oe)};ne.fn=ne.prototype={jquery:Se,constructor:ne,length:0,toArray:function(){return n.call(this)},get:function(q){return q==null?n.call(this):q<0?this[q+this.length]:this[q]},pushStack:function(q){var oe=ne.merge(this.constructor(),q);return oe.prevObject=this,oe},each:function(q){return ne.each(this,q)},map:function(q){return this.pushStack(ne.map(this,function(oe,pe){return q.call(oe,pe,oe)}))},slice:function(){return this.pushStack(n.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(ne.grep(this,function(q,oe){return(oe+1)%2}))},odd:function(){return this.pushStack(ne.grep(this,function(q,oe){return oe%2}))},eq:function(q){var oe=this.length,pe=+q+(q<0?oe:0);return this.pushStack(pe>=0&&pe0&&oe-1 in q}function Xe(q,oe){return q.nodeName&&q.nodeName.toLowerCase()===oe.toLowerCase()}var Ce=r.pop,_e=r.sort,Je=r.splice,Et="[\\x20\\t\\r\\n\\f]",Ze=new RegExp("^"+Et+"+|((?:^|[^\\\\])(?:\\\\.)*)"+Et+"+$","g");ne.contains=function(q,oe){var pe=oe&&oe.parentNode;return q===pe||!!(pe&&pe.nodeType===1&&(q.contains?q.contains(pe):q.compareDocumentPosition&&q.compareDocumentPosition(pe)&16))};var xt=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g;function sr(q,oe){return oe?q==="\0"?"\uFFFD":q.slice(0,-1)+"\\"+q.charCodeAt(q.length-1).toString(16)+" ":"\\"+q}ne.escapeSelector=function(q){return(q+"").replace(xt,sr)};var Mr=ee,hr=s;(function(){var q,oe,pe,be,He,We=hr,ot,rr,Ut,cr,Fr,li=ne.expando,vr=0,Bi=0,gn=Ah(),gs=Ah(),Mo=Ah(),bl=Ah(),al=function(Bt,ar){return Bt===ar&&(He=!0),0},Da="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",Ka="(?:\\\\[\\da-fA-F]{1,6}"+Et+"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",Yn="\\["+Et+"*("+Ka+")(?:"+Et+"*([*^$|!~]?=)"+Et+`*(?:'((?:\\\\.|[^\\\\'])*)'|"((?:\\\\.|[^\\\\"])*)"|(`+Ka+"))|)"+Et+"*\\]",Er=":("+Ka+`)(?:\\((('((?:\\\\.|[^\\\\'])*)'|"((?:\\\\.|[^\\\\"])*)")|((?:\\\\.|[^\\\\()[\\]]|`+Yn+")*)|.*)\\)|)",Gr=new RegExp(Et+"+","g"),wi=new RegExp("^"+Et+"*,"+Et+"*"),ni=new RegExp("^"+Et+"*([>+~]|"+Et+")"+Et+"*"),b=new RegExp(Et+"|>"),Po=new RegExp(Er),_o=new RegExp("^"+Ka+"$"),Ye={ID:new RegExp("^#("+Ka+")"),CLASS:new RegExp("^\\.("+Ka+")"),TAG:new RegExp("^("+Ka+"|[*])"),ATTR:new RegExp("^"+Yn),PSEUDO:new RegExp("^"+Er),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+Et+"*(even|odd|(([+-]|)(\\d*)n|)"+Et+"*(?:([+-]|)"+Et+"*(\\d+)|))"+Et+"*\\)|)","i"),bool:new RegExp("^(?:"+Da+")$","i"),needsContext:new RegExp("^"+Et+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+Et+"*((?:-\\d)?\\d*)"+Et+"*\\)|)(?=[^-]|$)","i")},Ms=/^(?:input|select|textarea|button)$/i,ao=/^h\d$/i,Ps=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,Rs=/[+~]/,Go=new RegExp("\\\\[\\da-fA-F]{1,6}"+Et+"?|\\\\([^\\r\\n\\f])","g"),Qs=function(Bt,ar){var Br="0x"+Bt.slice(1)-65536;return ar||(Br<0?String.fromCharCode(Br+65536):String.fromCharCode(Br>>10|55296,Br&1023|56320))},Ts=function(){qn()},Os=_f(function(Bt){return Bt.disabled===!0&&Xe(Bt,"fieldset")},{dir:"parentNode",next:"legend"});function gh(){try{return ot.activeElement}catch{}}try{We.apply(r=n.call(Mr.childNodes),Mr.childNodes),r[Mr.childNodes.length].nodeType}catch{We={apply:function(ar,Br){hr.apply(ar,n.call(Br))},call:function(ar){hr.apply(ar,n.call(arguments,1))}}}function Ss(Bt,ar,Br,Ur){var ci,Li,yi,Pn,sn,To,Hi,Ti=ar&&ar.ownerDocument,Kn=ar?ar.nodeType:9;if(Br=Br||[],typeof Bt!="string"||!Bt||Kn!==1&&Kn!==9&&Kn!==11)return Br;if(!Ur&&(qn(ar),ar=ar||ot,Ut)){if(Kn!==11&&(sn=Ps.exec(Bt)))if(ci=sn[1]){if(Kn===9)if(yi=ar.getElementById(ci)){if(yi.id===ci)return We.call(Br,yi),Br}else return Br;else if(Ti&&(yi=Ti.getElementById(ci))&&Ss.contains(ar,yi)&&yi.id===ci)return We.call(Br,yi),Br}else{if(sn[2])return We.apply(Br,ar.getElementsByTagName(Bt)),Br;if((ci=sn[3])&&ar.getElementsByClassName)return We.apply(Br,ar.getElementsByClassName(ci)),Br}if(!bl[Bt+" "]&&(!cr||!cr.test(Bt))){if(Hi=Bt,Ti=ar,Kn===1&&(b.test(Bt)||ni.test(Bt))){for(Ti=Rs.test(Bt)&&Ac(ar.parentNode)||ar,(Ti!=ar||!k.scope)&&((Pn=ar.getAttribute("id"))?Pn=ne.escapeSelector(Pn):ar.setAttribute("id",Pn=li)),To=Fn(Bt),Li=To.length;Li--;)To[Li]=(Pn?"#"+Pn:":scope")+" "+$h(To[Li]);Hi=To.join(",")}try{return We.apply(Br,Ti.querySelectorAll(Hi)),Br}catch{bl(Bt,!0)}finally{Pn===li&&ar.removeAttribute("id")}}}return qf(Bt.replace(Ze,"$1"),ar,Br,Ur)}function Ah(){var Bt=[];function ar(Br,Ur){return Bt.push(Br+" ")>oe.cacheLength&&delete ar[Bt.shift()],ar[Br+" "]=Ur}return ar}function mc(Bt){return Bt[li]=!0,Bt}function Qa(Bt){var ar=ot.createElement("fieldset");try{return!!Bt(ar)}catch{return!1}finally{ar.parentNode&&ar.parentNode.removeChild(ar),ar=null}}function Ru(Bt){return function(ar){return Xe(ar,"input")&&ar.type===Bt}}function gc(Bt){return function(ar){return(Xe(ar,"input")||Xe(ar,"button"))&&ar.type===Bt}}function _h(Bt){return function(ar){return"form"in ar?ar.parentNode&&ar.disabled===!1?"label"in ar?"label"in ar.parentNode?ar.parentNode.disabled===Bt:ar.disabled===Bt:ar.isDisabled===Bt||ar.isDisabled!==!Bt&&Os(ar)===Bt:ar.disabled===Bt:"label"in ar?ar.disabled===Bt:!1}}function Fl(Bt){return mc(function(ar){return ar=+ar,mc(function(Br,Ur){for(var ci,Li=Bt([],Br.length,ar),yi=Li.length;yi--;)Br[ci=Li[yi]]&&(Br[ci]=!(Ur[ci]=Br[ci]))})})}function Ac(Bt){return Bt&&typeof Bt.getElementsByTagName<"u"&&Bt}function qn(Bt){var ar,Br=Bt?Bt.ownerDocument||Bt:Mr;return Br==ot||Br.nodeType!==9||!Br.documentElement||(ot=Br,rr=ot.documentElement,Ut=!ne.isXMLDoc(ot),Fr=rr.matches||rr.webkitMatchesSelector||rr.msMatchesSelector,rr.msMatchesSelector&&Mr!=ot&&(ar=ot.defaultView)&&ar.top!==ar&&ar.addEventListener("unload",Ts),k.getById=Qa(function(Ur){return rr.appendChild(Ur).id=ne.expando,!ot.getElementsByName||!ot.getElementsByName(ne.expando).length}),k.disconnectedMatch=Qa(function(Ur){return Fr.call(Ur,"*")}),k.scope=Qa(function(){return ot.querySelectorAll(":scope")}),k.cssHas=Qa(function(){try{return ot.querySelector(":has(*,:jqfake)"),!1}catch{return!0}}),k.getById?(oe.filter.ID=function(Ur){var ci=Ur.replace(Go,Qs);return function(Li){return Li.getAttribute("id")===ci}},oe.find.ID=function(Ur,ci){if(typeof ci.getElementById<"u"&&Ut){var Li=ci.getElementById(Ur);return Li?[Li]:[]}}):(oe.filter.ID=function(Ur){var ci=Ur.replace(Go,Qs);return function(Li){var yi=typeof Li.getAttributeNode<"u"&&Li.getAttributeNode("id");return yi&&yi.value===ci}},oe.find.ID=function(Ur,ci){if(typeof ci.getElementById<"u"&&Ut){var Li,yi,Pn,sn=ci.getElementById(Ur);if(sn){if(Li=sn.getAttributeNode("id"),Li&&Li.value===Ur)return[sn];for(Pn=ci.getElementsByName(Ur),yi=0;sn=Pn[yi++];)if(Li=sn.getAttributeNode("id"),Li&&Li.value===Ur)return[sn]}return[]}}),oe.find.TAG=function(Ur,ci){return typeof ci.getElementsByTagName<"u"?ci.getElementsByTagName(Ur):ci.querySelectorAll(Ur)},oe.find.CLASS=function(Ur,ci){if(typeof ci.getElementsByClassName<"u"&&Ut)return ci.getElementsByClassName(Ur)},cr=[],Qa(function(Ur){var ci;rr.appendChild(Ur).innerHTML="",Ur.querySelectorAll("[selected]").length||cr.push("\\["+Et+"*(?:value|"+Da+")"),Ur.querySelectorAll("[id~="+li+"-]").length||cr.push("~="),Ur.querySelectorAll("a#"+li+"+*").length||cr.push(".#.+[+~]"),Ur.querySelectorAll(":checked").length||cr.push(":checked"),ci=ot.createElement("input"),ci.setAttribute("type","hidden"),Ur.appendChild(ci).setAttribute("name","D"),rr.appendChild(Ur).disabled=!0,Ur.querySelectorAll(":disabled").length!==2&&cr.push(":enabled",":disabled"),ci=ot.createElement("input"),ci.setAttribute("name",""),Ur.appendChild(ci),Ur.querySelectorAll("[name='']").length||cr.push("\\["+Et+"*name"+Et+"*="+Et+`*(?:''|"")`)}),k.cssHas||cr.push(":has"),cr=cr.length&&new RegExp(cr.join("|")),al=function(Ur,ci){if(Ur===ci)return He=!0,0;var Li=!Ur.compareDocumentPosition-!ci.compareDocumentPosition;return Li||(Li=(Ur.ownerDocument||Ur)==(ci.ownerDocument||ci)?Ur.compareDocumentPosition(ci):1,Li&1||!k.sortDetached&&ci.compareDocumentPosition(Ur)===Li?Ur===ot||Ur.ownerDocument==Mr&&Ss.contains(Mr,Ur)?-1:ci===ot||ci.ownerDocument==Mr&&Ss.contains(Mr,ci)?1:be?c.call(be,Ur)-c.call(be,ci):0:Li&4?-1:1)}),ot}Ss.matches=function(Bt,ar){return Ss(Bt,null,null,ar)},Ss.matchesSelector=function(Bt,ar){if(qn(Bt),Ut&&!bl[ar+" "]&&(!cr||!cr.test(ar)))try{var Br=Fr.call(Bt,ar);if(Br||k.disconnectedMatch||Bt.document&&Bt.document.nodeType!==11)return Br}catch{bl(ar,!0)}return Ss(ar,ot,null,[Bt]).length>0},Ss.contains=function(Bt,ar){return(Bt.ownerDocument||Bt)!=ot&&qn(Bt),ne.contains(Bt,ar)},Ss.attr=function(Bt,ar){(Bt.ownerDocument||Bt)!=ot&&qn(Bt);var Br=oe.attrHandle[ar.toLowerCase()],Ur=Br&&y.call(oe.attrHandle,ar.toLowerCase())?Br(Bt,ar,!Ut):void 0;return Ur!==void 0?Ur:Bt.getAttribute(ar)},Ss.error=function(Bt){throw new Error("Syntax error, unrecognized expression: "+Bt)},ne.uniqueSort=function(Bt){var ar,Br=[],Ur=0,ci=0;if(He=!k.sortStable,be=!k.sortStable&&n.call(Bt,0),_e.call(Bt,al),He){for(;ar=Bt[ci++];)ar===Bt[ci]&&(Ur=Br.push(ci));for(;Ur--;)Je.call(Bt,Br[Ur],1)}return be=null,Bt},ne.fn.uniqueSort=function(){return this.pushStack(ne.uniqueSort(n.apply(this)))},oe=ne.expr={cacheLength:50,createPseudo:mc,match:Ye,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(Bt){return Bt[1]=Bt[1].replace(Go,Qs),Bt[3]=(Bt[3]||Bt[4]||Bt[5]||"").replace(Go,Qs),Bt[2]==="~="&&(Bt[3]=" "+Bt[3]+" "),Bt.slice(0,4)},CHILD:function(Bt){return Bt[1]=Bt[1].toLowerCase(),Bt[1].slice(0,3)==="nth"?(Bt[3]||Ss.error(Bt[0]),Bt[4]=+(Bt[4]?Bt[5]+(Bt[6]||1):2*(Bt[3]==="even"||Bt[3]==="odd")),Bt[5]=+(Bt[7]+Bt[8]||Bt[3]==="odd")):Bt[3]&&Ss.error(Bt[0]),Bt},PSEUDO:function(Bt){var ar,Br=!Bt[6]&&Bt[2];return Ye.CHILD.test(Bt[0])?null:(Bt[3]?Bt[2]=Bt[4]||Bt[5]||"":Br&&Po.test(Br)&&(ar=Fn(Br,!0))&&(ar=Br.indexOf(")",Br.length-ar)-Br.length)&&(Bt[0]=Bt[0].slice(0,ar),Bt[2]=Br.slice(0,ar)),Bt.slice(0,3))}},filter:{TAG:function(Bt){var ar=Bt.replace(Go,Qs).toLowerCase();return Bt==="*"?function(){return!0}:function(Br){return Xe(Br,ar)}},CLASS:function(Bt){var ar=gn[Bt+" "];return ar||(ar=new RegExp("(^|"+Et+")"+Bt+"("+Et+"|$)"))&&gn(Bt,function(Br){return ar.test(typeof Br.className=="string"&&Br.className||typeof Br.getAttribute<"u"&&Br.getAttribute("class")||"")})},ATTR:function(Bt,ar,Br){return function(Ur){var ci=Ss.attr(Ur,Bt);return ci==null?ar==="!=":ar?(ci+="",ar==="="?ci===Br:ar==="!="?ci!==Br:ar==="^="?Br&&ci.indexOf(Br)===0:ar==="*="?Br&&ci.indexOf(Br)>-1:ar==="$="?Br&&ci.slice(-Br.length)===Br:ar==="~="?(" "+ci.replace(Gr," ")+" ").indexOf(Br)>-1:ar==="|="?ci===Br||ci.slice(0,Br.length+1)===Br+"-":!1):!0}},CHILD:function(Bt,ar,Br,Ur,ci){var Li=Bt.slice(0,3)!=="nth",yi=Bt.slice(-4)!=="last",Pn=ar==="of-type";return Ur===1&&ci===0?function(sn){return!!sn.parentNode}:function(sn,To,Hi){var Ti,Kn,zn,Fs,wl,yo=Li!==yi?"nextSibling":"previousSibling",tc=sn.parentNode,Tl=Pn&&sn.nodeName.toLowerCase(),ll=!Hi&&!Pn,Oa=!1;if(tc){if(Li){for(;yo;){for(zn=sn;zn=zn[yo];)if(Pn?Xe(zn,Tl):zn.nodeType===1)return!1;wl=yo=Bt==="only"&&!wl&&"nextSibling"}return!0}if(wl=[yi?tc.firstChild:tc.lastChild],yi&&ll){for(Kn=tc[li]||(tc[li]={}),Ti=Kn[Bt]||[],Fs=Ti[0]===vr&&Ti[1],Oa=Fs&&Ti[2],zn=Fs&&tc.childNodes[Fs];zn=++Fs&&zn&&zn[yo]||(Oa=Fs=0)||wl.pop();)if(zn.nodeType===1&&++Oa&&zn===sn){Kn[Bt]=[vr,Fs,Oa];break}}else if(ll&&(Kn=sn[li]||(sn[li]={}),Ti=Kn[Bt]||[],Fs=Ti[0]===vr&&Ti[1],Oa=Fs),Oa===!1)for(;(zn=++Fs&&zn&&zn[yo]||(Oa=Fs=0)||wl.pop())&&!((Pn?Xe(zn,Tl):zn.nodeType===1)&&++Oa&&(ll&&(Kn=zn[li]||(zn[li]={}),Kn[Bt]=[vr,Oa]),zn===sn)););return Oa-=ci,Oa===Ur||Oa%Ur===0&&Oa/Ur>=0}}},PSEUDO:function(Bt,ar){var Br,Ur=oe.pseudos[Bt]||oe.setFilters[Bt.toLowerCase()]||Ss.error("unsupported pseudo: "+Bt);return Ur[li]?Ur(ar):Ur.length>1?(Br=[Bt,Bt,"",ar],oe.setFilters.hasOwnProperty(Bt.toLowerCase())?mc(function(ci,Li){for(var yi,Pn=Ur(ci,ar),sn=Pn.length;sn--;)yi=c.call(ci,Pn[sn]),ci[yi]=!(Li[yi]=Pn[sn])}):function(ci){return Ur(ci,0,Br)}):Ur}},pseudos:{not:mc(function(Bt){var ar=[],Br=[],Ur=Wf(Bt.replace(Ze,"$1"));return Ur[li]?mc(function(ci,Li,yi,Pn){for(var sn,To=Ur(ci,null,Pn,[]),Hi=ci.length;Hi--;)(sn=To[Hi])&&(ci[Hi]=!(Li[Hi]=sn))}):function(ci,Li,yi){return ar[0]=ci,Ur(ar,null,yi,Br),ar[0]=null,!Br.pop()}}),has:mc(function(Bt){return function(ar){return Ss(Bt,ar).length>0}}),contains:mc(function(Bt){return Bt=Bt.replace(Go,Qs),function(ar){return(ar.textContent||ne.text(ar)).indexOf(Bt)>-1}}),lang:mc(function(Bt){return _o.test(Bt||"")||Ss.error("unsupported lang: "+Bt),Bt=Bt.replace(Go,Qs).toLowerCase(),function(ar){var Br;do if(Br=Ut?ar.lang:ar.getAttribute("xml:lang")||ar.getAttribute("lang"))return Br=Br.toLowerCase(),Br===Bt||Br.indexOf(Bt+"-")===0;while((ar=ar.parentNode)&&ar.nodeType===1);return!1}}),target:function(Bt){var ar=t.location&&t.location.hash;return ar&&ar.slice(1)===Bt.id},root:function(Bt){return Bt===rr},focus:function(Bt){return Bt===gh()&&ot.hasFocus()&&!!(Bt.type||Bt.href||~Bt.tabIndex)},enabled:_h(!1),disabled:_h(!0),checked:function(Bt){return Xe(Bt,"input")&&!!Bt.checked||Xe(Bt,"option")&&!!Bt.selected},selected:function(Bt){return Bt.parentNode&&Bt.parentNode.selectedIndex,Bt.selected===!0},empty:function(Bt){for(Bt=Bt.firstChild;Bt;Bt=Bt.nextSibling)if(Bt.nodeType<6)return!1;return!0},parent:function(Bt){return!oe.pseudos.empty(Bt)},header:function(Bt){return ao.test(Bt.nodeName)},input:function(Bt){return Ms.test(Bt.nodeName)},button:function(Bt){return Xe(Bt,"input")&&Bt.type==="button"||Xe(Bt,"button")},text:function(Bt){var ar;return Xe(Bt,"input")&&Bt.type==="text"&&((ar=Bt.getAttribute("type"))==null||ar.toLowerCase()==="text")},first:Fl(function(){return[0]}),last:Fl(function(Bt,ar){return[ar-1]}),eq:Fl(function(Bt,ar,Br){return[Br<0?Br+ar:Br]}),even:Fl(function(Bt,ar){for(var Br=0;Brar?Ur=ar:Ur=Br;--Ur>=0;)Bt.push(Ur);return Bt}),gt:Fl(function(Bt,ar,Br){for(var Ur=Br<0?Br+ar:Br;++Ur1?function(ar,Br,Ur){for(var ci=Bt.length;ci--;)if(!Bt[ci](ar,Br,Ur))return!1;return!0}:Bt[0]}function Wd(Bt,ar,Br){for(var Ur=0,ci=ar.length;Ur-1&&(yi[Hi]=!(Pn[Hi]=Kn))}}else zn=Ad(zn===Pn?zn.splice(yo,zn.length):zn),ci?ci(null,Pn,zn,To):We.apply(Pn,zn)})}function yf(Bt){for(var ar,Br,Ur,ci=Bt.length,Li=oe.relative[Bt[0].type],yi=Li||oe.relative[" "],Pn=Li?1:0,sn=_f(function(Ti){return Ti===ar},yi,!0),To=_f(function(Ti){return c.call(ar,Ti)>-1},yi,!0),Hi=[function(Ti,Kn,zn){var Fs=!Li&&(zn||Kn!=pe)||((ar=Kn).nodeType?sn(Ti,Kn,zn):To(Ti,Kn,zn));return ar=null,Fs}];Pn1&&Xh(Hi),Pn>1&&$h(Bt.slice(0,Pn-1).concat({value:Bt[Pn-2].type===" "?"*":""})).replace(Ze,"$1"),Br,Pn0,Ur=Bt.length>0,ci=function(Li,yi,Pn,sn,To){var Hi,Ti,Kn,zn=0,Fs="0",wl=Li&&[],yo=[],tc=pe,Tl=Li||Ur&&oe.find.TAG("*",To),ll=vr+=tc==null?1:Math.random()||.1,Oa=Tl.length;for(To&&(pe=yi==ot||yi||To);Fs!==Oa&&(Hi=Tl[Fs])!=null;Fs++){if(Ur&&Hi){for(Ti=0,!yi&&Hi.ownerDocument!=ot&&(qn(Hi),Pn=!Ut);Kn=Bt[Ti++];)if(Kn(Hi,yi||ot,Pn)){We.call(sn,Hi);break}To&&(vr=ll)}Br&&((Hi=!Kn&&Hi)&&zn--,Li&&wl.push(Hi))}if(zn+=Fs,Br&&Fs!==zn){for(Ti=0;Kn=ar[Ti++];)Kn(wl,yo,yi,Pn);if(Li){if(zn>0)for(;Fs--;)wl[Fs]||yo[Fs]||(yo[Fs]=Ce.call(sn));yo=Ad(yo)}We.apply(sn,yo),To&&!Li&&yo.length>0&&zn+ar.length>1&&ne.uniqueSort(sn)}return To&&(vr=ll,pe=tc),wl};return Br?mc(ci):ci}function Wf(Bt,ar){var Br,Ur=[],ci=[],Li=Mo[Bt+" "];if(!Li){for(ar||(ar=Fn(Bt)),Br=ar.length;Br--;)Li=yf(ar[Br]),Li[li]?Ur.push(Li):ci.push(Li);Li=Mo(Bt,Bu(ci,Ur)),Li.selector=Bt}return Li}function qf(Bt,ar,Br,Ur){var ci,Li,yi,Pn,sn,To=typeof Bt=="function"&&Bt,Hi=!Ur&&Fn(Bt=To.selector||Bt);if(Br=Br||[],Hi.length===1){if(Li=Hi[0]=Hi[0].slice(0),Li.length>2&&(yi=Li[0]).type==="ID"&&ar.nodeType===9&&Ut&&oe.relative[Li[1].type]){if(ar=(oe.find.ID(yi.matches[0].replace(Go,Qs),ar)||[])[0],ar)To&&(ar=ar.parentNode);else return Br;Bt=Bt.slice(Li.shift().value.length)}for(ci=Ye.needsContext.test(Bt)?0:Li.length;ci--&&(yi=Li[ci],!oe.relative[Pn=yi.type]);)if((sn=oe.find[Pn])&&(Ur=sn(yi.matches[0].replace(Go,Qs),Rs.test(Li[0].type)&&Ac(ar.parentNode)||ar))){if(Li.splice(ci,1),Bt=Ur.length&&$h(Li),!Bt)return We.apply(Br,Ur),Br;break}}return(To||Wf(Bt,Hi))(Ur,ar,!Ut,Br,!ar||Rs.test(Bt)&&Ac(ar.parentNode)||ar),Br}k.sortStable=li.split("").sort(al).join("")===li,qn(),k.sortDetached=Qa(function(Bt){return Bt.compareDocumentPosition(ot.createElement("fieldset"))&1}),ne.find=Ss,ne.expr[":"]=ne.expr.pseudos,ne.unique=ne.uniqueSort,Ss.compile=Wf,Ss.select=qf,Ss.setDocument=qn,Ss.tokenize=Fn,Ss.escape=ne.escapeSelector,Ss.getText=ne.text,Ss.isXML=ne.isXMLDoc,Ss.selectors=ne.expr,Ss.support=ne.support,Ss.uniqueSort=ne.uniqueSort})();var mi=function(q,oe,pe){for(var be=[],He=pe!==void 0;(q=q[oe])&&q.nodeType!==9;)if(q.nodeType===1){if(He&&ne(q).is(pe))break;be.push(q)}return be},bi=function(q,oe){for(var pe=[];q;q=q.nextSibling)q.nodeType===1&&q!==oe&&pe.push(q);return pe},un=ne.expr.match.needsContext,Yr=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function Xi(q,oe,pe){return U(oe)?ne.grep(q,function(be,He){return!!oe.call(be,He,be)!==pe}):oe.nodeType?ne.grep(q,function(be){return be===oe!==pe}):typeof oe!="string"?ne.grep(q,function(be){return c.call(oe,be)>-1!==pe}):ne.filter(oe,q,pe)}ne.filter=function(q,oe,pe){var be=oe[0];return pe&&(q=":not("+q+")"),oe.length===1&&be.nodeType===1?ne.find.matchesSelector(be,q)?[be]:[]:ne.find.matches(q,ne.grep(oe,function(He){return He.nodeType===1}))},ne.fn.extend({find:function(q){var oe,pe,be=this.length,He=this;if(typeof q!="string")return this.pushStack(ne(q).filter(function(){for(oe=0;oe1?ne.uniqueSort(pe):pe},filter:function(q){return this.pushStack(Xi(this,q||[],!1))},not:function(q){return this.pushStack(Xi(this,q||[],!0))},is:function(q){return!!Xi(this,typeof q=="string"&&un.test(q)?ne(q):q||[],!1).length}});var xi,ii=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,Gn=ne.fn.init=function(q,oe,pe){var be,He;if(!q)return this;if(pe=pe||xi,typeof q=="string")if(q[0]==="<"&&q[q.length-1]===">"&&q.length>=3?be=[null,q,null]:be=ii.exec(q),be&&(be[1]||!oe))if(be[1]){if(oe=oe instanceof ne?oe[0]:oe,ne.merge(this,ne.parseHTML(be[1],oe&&oe.nodeType?oe.ownerDocument||oe:ee,!0)),Yr.test(be[1])&&ne.isPlainObject(oe))for(be in oe)U(this[be])?this[be](oe[be]):this.attr(be,oe[be]);return this}else return He=ee.getElementById(be[2]),He&&(this[0]=He,this.length=1),this;else return!oe||oe.jquery?(oe||pe).find(q):this.constructor(oe).find(q);else{if(q.nodeType)return this[0]=q,this.length=1,this;if(U(q))return pe.ready!==void 0?pe.ready(q):q(ne)}return ne.makeArray(q,this)};Gn.prototype=ne.fn,xi=ne(ee);var Ve=/^(?:parents|prev(?:Until|All))/,nt={children:!0,contents:!0,next:!0,prev:!0};ne.fn.extend({has:function(q){var oe=ne(q,this),pe=oe.length;return this.filter(function(){for(var be=0;be-1:pe.nodeType===1&&ne.find.matchesSelector(pe,q))){We.push(pe);break}}return this.pushStack(We.length>1?ne.uniqueSort(We):We)},index:function(q){return q?typeof q=="string"?c.call(ne(q),this[0]):c.call(this,q.jquery?q[0]:q):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(q,oe){return this.pushStack(ne.uniqueSort(ne.merge(this.get(),ne(q,oe))))},addBack:function(q){return this.add(q==null?this.prevObject:this.prevObject.filter(q))}});function Ft(q,oe){for(;(q=q[oe])&&q.nodeType!==1;);return q}ne.each({parent:function(q){var oe=q.parentNode;return oe&&oe.nodeType!==11?oe:null},parents:function(q){return mi(q,"parentNode")},parentsUntil:function(q,oe,pe){return mi(q,"parentNode",pe)},next:function(q){return Ft(q,"nextSibling")},prev:function(q){return Ft(q,"previousSibling")},nextAll:function(q){return mi(q,"nextSibling")},prevAll:function(q){return mi(q,"previousSibling")},nextUntil:function(q,oe,pe){return mi(q,"nextSibling",pe)},prevUntil:function(q,oe,pe){return mi(q,"previousSibling",pe)},siblings:function(q){return bi((q.parentNode||{}).firstChild,q)},children:function(q){return bi(q.firstChild)},contents:function(q){return q.contentDocument!=null&&i(q.contentDocument)?q.contentDocument:(Xe(q,"template")&&(q=q.content||q),ne.merge([],q.childNodes))}},function(q,oe){ne.fn[q]=function(pe,be){var He=ne.map(this,oe,pe);return q.slice(-5)!=="Until"&&(be=pe),be&&typeof be=="string"&&(He=ne.filter(be,He)),this.length>1&&(nt[q]||ne.uniqueSort(He),Ve.test(q)&&He.reverse()),this.pushStack(He)}});var mr=/[^\x20\t\r\n\f]+/g;function Xr(q){var oe={};return ne.each(q.match(mr)||[],function(pe,be){oe[be]=!0}),oe}ne.Callbacks=function(q){q=typeof q=="string"?Xr(q):ne.extend({},q);var oe,pe,be,He,We=[],ot=[],rr=-1,Ut=function(){for(He=He||q.once,be=oe=!0;ot.length;rr=-1)for(pe=ot.shift();++rr-1;)We.splice(vr,1),vr<=rr&&rr--}),this},has:function(Fr){return Fr?ne.inArray(Fr,We)>-1:We.length>0},empty:function(){return We&&(We=[]),this},disable:function(){return He=ot=[],We=pe="",this},disabled:function(){return!We},lock:function(){return He=ot=[],!pe&&!oe&&(We=pe=""),this},locked:function(){return!!He},fireWith:function(Fr,li){return He||(li=li||[],li=[Fr,li.slice?li.slice():li],ot.push(li),oe||Ut()),this},fire:function(){return cr.fireWith(this,arguments),this},fired:function(){return!!be}};return cr};function zr(q){return q}function ln(q){throw q}function Nn(q,oe,pe,be){var He;try{q&&U(He=q.promise)?He.call(q).done(oe).fail(pe):q&&U(He=q.then)?He.call(q,oe,pe):oe.apply(void 0,[q].slice(be))}catch(We){pe.apply(void 0,[We])}}ne.extend({Deferred:function(q){var oe=[["notify","progress",ne.Callbacks("memory"),ne.Callbacks("memory"),2],["resolve","done",ne.Callbacks("once memory"),ne.Callbacks("once memory"),0,"resolved"],["reject","fail",ne.Callbacks("once memory"),ne.Callbacks("once memory"),1,"rejected"]],pe="pending",be={state:function(){return pe},always:function(){return He.done(arguments).fail(arguments),this},catch:function(We){return be.then(null,We)},pipe:function(){var We=arguments;return ne.Deferred(function(ot){ne.each(oe,function(rr,Ut){var cr=U(We[Ut[4]])&&We[Ut[4]];He[Ut[1]](function(){var Fr=cr&&cr.apply(this,arguments);Fr&&U(Fr.promise)?Fr.promise().progress(ot.notify).done(ot.resolve).fail(ot.reject):ot[Ut[0]+"With"](this,cr?[Fr]:arguments)})}),We=null}).promise()},then:function(We,ot,rr){var Ut=0;function cr(Fr,li,vr,Bi){return function(){var gn=this,gs=arguments,Mo=function(){var al,Da;if(!(Fr=Ut&&(vr!==ln&&(gn=void 0,gs=[al]),li.rejectWith(gn,gs))}};Fr?bl():(ne.Deferred.getErrorHook?bl.error=ne.Deferred.getErrorHook():ne.Deferred.getStackHook&&(bl.error=ne.Deferred.getStackHook()),t.setTimeout(bl))}}return ne.Deferred(function(Fr){oe[0][3].add(cr(0,Fr,U(rr)?rr:zr,Fr.notifyWith)),oe[1][3].add(cr(0,Fr,U(We)?We:zr)),oe[2][3].add(cr(0,Fr,U(ot)?ot:ln))}).promise()},promise:function(We){return We!=null?ne.extend(We,be):be}},He={};return ne.each(oe,function(We,ot){var rr=ot[2],Ut=ot[5];be[ot[1]]=rr.add,Ut&&rr.add(function(){pe=Ut},oe[3-We][2].disable,oe[3-We][3].disable,oe[0][2].lock,oe[0][3].lock),rr.add(ot[3].fire),He[ot[0]]=function(){return He[ot[0]+"With"](this===He?void 0:this,arguments),this},He[ot[0]+"With"]=rr.fireWith}),be.promise(He),q&&q.call(He,He),He},when:function(q){var oe=arguments.length,pe=oe,be=Array(pe),He=n.call(arguments),We=ne.Deferred(),ot=function(rr){return function(Ut){be[rr]=this,He[rr]=arguments.length>1?n.call(arguments):Ut,--oe||We.resolveWith(be,He)}};if(oe<=1&&(Nn(q,We.done(ot(pe)).resolve,We.reject,!oe),We.state()==="pending"||U(He[pe]&&He[pe].then)))return We.then();for(;pe--;)Nn(He[pe],ot(pe),We.reject);return We.promise()}});var Co=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;ne.Deferred.exceptionHook=function(q,oe){t.console&&t.console.warn&&q&&Co.test(q.name)&&t.console.warn("jQuery.Deferred exception: "+q.message,q.stack,oe)},ne.readyException=function(q){t.setTimeout(function(){throw q})};var Ho=ne.Deferred();ne.fn.ready=function(q){return Ho.then(q).catch(function(oe){ne.readyException(oe)}),this},ne.extend({isReady:!1,readyWait:1,ready:function(q){(q===!0?--ne.readyWait:ne.isReady)||(ne.isReady=!0,!(q!==!0&&--ne.readyWait>0)&&Ho.resolveWith(ee,[ne]))}}),ne.ready.then=Ho.then;function is(){ee.removeEventListener("DOMContentLoaded",is),t.removeEventListener("load",is),ne.ready()}ee.readyState==="complete"||ee.readyState!=="loading"&&!ee.documentElement.doScroll?t.setTimeout(ne.ready):(ee.addEventListener("DOMContentLoaded",is),t.addEventListener("load",is));var mo=function(q,oe,pe,be,He,We,ot){var rr=0,Ut=q.length,cr=pe==null;if(me(pe)==="object"){He=!0;for(rr in pe)mo(q,oe,rr,pe[rr],!0,We,ot)}else if(be!==void 0&&(He=!0,U(be)||(ot=!0),cr&&(ot?(oe.call(q,be),oe=null):(cr=oe,oe=function(Fr,li,vr){return cr.call(ne(Fr),vr)})),oe))for(;rr1,null,!0)},removeData:function(q){return this.each(function(){Fe.remove(this,q)})}}),ne.extend({queue:function(q,oe,pe){var be;if(q)return oe=(oe||"fx")+"queue",be=Yt.get(q,oe),pe&&(!be||Array.isArray(pe)?be=Yt.access(q,oe,ne.makeArray(pe)):be.push(pe)),be||[]},dequeue:function(q,oe){oe=oe||"fx";var pe=ne.queue(q,oe),be=pe.length,He=pe.shift(),We=ne._queueHooks(q,oe),ot=function(){ne.dequeue(q,oe)};He==="inprogress"&&(He=pe.shift(),be--),He&&(oe==="fx"&&pe.unshift("inprogress"),delete We.stop,He.call(q,ot,We)),!be&&We&&We.empty.fire()},_queueHooks:function(q,oe){var pe=oe+"queueHooks";return Yt.get(q,pe)||Yt.access(q,pe,{empty:ne.Callbacks("once memory").add(function(){Yt.remove(q,[oe+"queue",pe])})})}}),ne.fn.extend({queue:function(q,oe){var pe=2;return typeof q!="string"&&(oe=q,q="fx",pe--),arguments.length\x20\t\r\n\f]*)/i,ns=/^$|^module$|\/(?:java|ecma)script/i;(function(){var q=ee.createDocumentFragment(),oe=q.appendChild(ee.createElement("div")),pe=ee.createElement("input");pe.setAttribute("type","radio"),pe.setAttribute("checked","checked"),pe.setAttribute("name","t"),oe.appendChild(pe),k.checkClone=oe.cloneNode(!0).cloneNode(!0).lastChild.checked,oe.innerHTML="",k.noCloneChecked=!!oe.cloneNode(!0).lastChild.defaultValue,oe.innerHTML="",k.option=!!oe.lastChild})();var Be={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};Be.tbody=Be.tfoot=Be.colgroup=Be.caption=Be.thead,Be.th=Be.td,k.option||(Be.optgroup=Be.option=[1,""]);function $e(q,oe){var pe;return typeof q.getElementsByTagName<"u"?pe=q.getElementsByTagName(oe||"*"):typeof q.querySelectorAll<"u"?pe=q.querySelectorAll(oe||"*"):pe=[],oe===void 0||oe&&Xe(q,oe)?ne.merge([q],pe):pe}function it(q,oe){for(var pe=0,be=q.length;pe-1){He&&He.push(We);continue}if(cr=ti(We),ot=$e(li.appendChild(We),"script"),cr&&it(ot),pe)for(Fr=0;We=ot[Fr++];)ns.test(We.type||"")&&pe.push(We)}return li}var $t=/^([^.]*)(?:\.(.+)|)/;function Jt(){return!0}function ht(){return!1}function Ot(q,oe,pe,be,He,We){var ot,rr;if(typeof oe=="object"){typeof pe!="string"&&(be=be||pe,pe=void 0);for(rr in oe)Ot(q,rr,pe,be,oe[rr],We);return q}if(be==null&&He==null?(He=pe,be=pe=void 0):He==null&&(typeof pe=="string"?(He=be,be=void 0):(He=be,be=pe,pe=void 0)),He===!1)He=ht;else if(!He)return q;return We===1&&(ot=He,He=function(Ut){return ne().off(Ut),ot.apply(this,arguments)},He.guid=ot.guid||(ot.guid=ne.guid++)),q.each(function(){ne.event.add(this,oe,He,be,pe)})}ne.event={global:{},add:function(q,oe,pe,be,He){var We,ot,rr,Ut,cr,Fr,li,vr,Bi,gn,gs,Mo=Yt.get(q);if(ps(q))for(pe.handler&&(We=pe,pe=We.handler,He=We.selector),He&&ne.find.matchesSelector(xr,He),pe.guid||(pe.guid=ne.guid++),(Ut=Mo.events)||(Ut=Mo.events=Object.create(null)),(ot=Mo.handle)||(ot=Mo.handle=function(bl){return typeof ne<"u"&&ne.event.triggered!==bl.type?ne.event.dispatch.apply(q,arguments):void 0}),oe=(oe||"").match(mr)||[""],cr=oe.length;cr--;)rr=$t.exec(oe[cr])||[],Bi=gs=rr[1],gn=(rr[2]||"").split(".").sort(),Bi&&(li=ne.event.special[Bi]||{},Bi=(He?li.delegateType:li.bindType)||Bi,li=ne.event.special[Bi]||{},Fr=ne.extend({type:Bi,origType:gs,data:be,handler:pe,guid:pe.guid,selector:He,needsContext:He&&ne.expr.match.needsContext.test(He),namespace:gn.join(".")},We),(vr=Ut[Bi])||(vr=Ut[Bi]=[],vr.delegateCount=0,(!li.setup||li.setup.call(q,be,gn,ot)===!1)&&q.addEventListener&&q.addEventListener(Bi,ot)),li.add&&(li.add.call(q,Fr),Fr.handler.guid||(Fr.handler.guid=pe.guid)),He?vr.splice(vr.delegateCount++,0,Fr):vr.push(Fr),ne.event.global[Bi]=!0)},remove:function(q,oe,pe,be,He){var We,ot,rr,Ut,cr,Fr,li,vr,Bi,gn,gs,Mo=Yt.hasData(q)&&Yt.get(q);if(!(!Mo||!(Ut=Mo.events))){for(oe=(oe||"").match(mr)||[""],cr=oe.length;cr--;){if(rr=$t.exec(oe[cr])||[],Bi=gs=rr[1],gn=(rr[2]||"").split(".").sort(),!Bi){for(Bi in Ut)ne.event.remove(q,Bi+oe[cr],pe,be,!0);continue}for(li=ne.event.special[Bi]||{},Bi=(be?li.delegateType:li.bindType)||Bi,vr=Ut[Bi]||[],rr=rr[2]&&new RegExp("(^|\\.)"+gn.join("\\.(?:.*\\.|)")+"(\\.|$)"),ot=We=vr.length;We--;)Fr=vr[We],(He||gs===Fr.origType)&&(!pe||pe.guid===Fr.guid)&&(!rr||rr.test(Fr.namespace))&&(!be||be===Fr.selector||be==="**"&&Fr.selector)&&(vr.splice(We,1),Fr.selector&&vr.delegateCount--,li.remove&&li.remove.call(q,Fr));ot&&!vr.length&&((!li.teardown||li.teardown.call(q,gn,Mo.handle)===!1)&&ne.removeEvent(q,Bi,Mo.handle),delete Ut[Bi])}ne.isEmptyObject(Ut)&&Yt.remove(q,"handle events")}},dispatch:function(q){var oe,pe,be,He,We,ot,rr=new Array(arguments.length),Ut=ne.event.fix(q),cr=(Yt.get(this,"events")||Object.create(null))[Ut.type]||[],Fr=ne.event.special[Ut.type]||{};for(rr[0]=Ut,oe=1;oe=1)){for(;cr!==this;cr=cr.parentNode||this)if(cr.nodeType===1&&!(q.type==="click"&&cr.disabled===!0)){for(We=[],ot={},pe=0;pe-1:ne.find(He,this,null,[cr]).length),ot[He]&&We.push(be);We.length&&rr.push({elem:cr,handlers:We})}}return cr=this,Ut\s*$/g;function si(q,oe){return Xe(q,"table")&&Xe(oe.nodeType!==11?oe:oe.firstChild,"tr")&&ne(q).children("tbody")[0]||q}function Or(q){return q.type=(q.getAttribute("type")!==null)+"/"+q.type,q}function fi(q){return(q.type||"").slice(0,5)==="true/"?q.type=q.type.slice(5):q.removeAttribute("type"),q}function pr(q,oe){var pe,be,He,We,ot,rr,Ut;if(oe.nodeType===1){if(Yt.hasData(q)&&(We=Yt.get(q),Ut=We.events,Ut)){Yt.remove(oe,"handle events");for(He in Ut)for(pe=0,be=Ut[He].length;pe1&&typeof Bi=="string"&&!k.checkClone&&ui.test(Bi))return q.each(function(gs){var Mo=q.eq(gs);gn&&(oe[0]=Bi.call(this,gs,Mo.html())),Ii(Mo,oe,pe,be)});if(li&&(He=Qe(oe,q[0].ownerDocument,!1,q,be),We=He.firstChild,He.childNodes.length===1&&(He=We),We||be)){for(ot=ne.map($e(He,"script"),Or),rr=ot.length;Fr0&&it(ot,!Ut&&$e(q,"script")),rr},cleanData:function(q){for(var oe,pe,be,He=ne.event.special,We=0;(pe=q[We])!==void 0;We++)if(ps(pe)){if(oe=pe[Yt.expando]){if(oe.events)for(be in oe.events)He[be]?ne.event.remove(pe,be):ne.removeEvent(pe,be,oe.handle);pe[Yt.expando]=void 0}pe[Fe.expando]&&(pe[Fe.expando]=void 0)}}}),ne.fn.extend({detach:function(q){return Mi(this,q,!0)},remove:function(q){return Mi(this,q)},text:function(q){return mo(this,function(oe){return oe===void 0?ne.text(this):this.empty().each(function(){(this.nodeType===1||this.nodeType===11||this.nodeType===9)&&(this.textContent=oe)})},null,q,arguments.length)},append:function(){return Ii(this,arguments,function(q){if(this.nodeType===1||this.nodeType===11||this.nodeType===9){var oe=si(this,q);oe.appendChild(q)}})},prepend:function(){return Ii(this,arguments,function(q){if(this.nodeType===1||this.nodeType===11||this.nodeType===9){var oe=si(this,q);oe.insertBefore(q,oe.firstChild)}})},before:function(){return Ii(this,arguments,function(q){this.parentNode&&this.parentNode.insertBefore(q,this)})},after:function(){return Ii(this,arguments,function(q){this.parentNode&&this.parentNode.insertBefore(q,this.nextSibling)})},empty:function(){for(var q,oe=0;(q=this[oe])!=null;oe++)q.nodeType===1&&(ne.cleanData($e(q,!1)),q.textContent="");return this},clone:function(q,oe){return q=q??!1,oe=oe??q,this.map(function(){return ne.clone(this,q,oe)})},html:function(q){return mo(this,function(oe){var pe=this[0]||{},be=0,He=this.length;if(oe===void 0&&pe.nodeType===1)return pe.innerHTML;if(typeof oe=="string"&&!ei.test(oe)&&!Be[(Us.exec(oe)||["",""])[1].toLowerCase()]){oe=ne.htmlPrefilter(oe);try{for(;be=0&&(Ut+=Math.max(0,Math.ceil(q["offset"+oe[0].toUpperCase()+oe.slice(1)]-We-Ut-rr-.5))||0),Ut+cr}function md(q,oe,pe){var be=po(q),He=!k.boxSizingReliable()||pe,We=He&&ne.css(q,"boxSizing",!1,be)==="border-box",ot=We,rr=No(q,oe,be),Ut="offset"+oe[0].toUpperCase()+oe.slice(1);if(Ni.test(rr)){if(!pe)return rr;rr="auto"}return(!k.boxSizingReliable()&&We||!k.reliableTrDimensions()&&Xe(q,"tr")||rr==="auto"||!parseFloat(rr)&&ne.css(q,"display",!1,be)==="inline")&&q.getClientRects().length&&(We=ne.css(q,"boxSizing",!1,be)==="border-box",ot=Ut in q,ot&&(rr=q[Ut])),rr=parseFloat(rr)||0,rr+Ya(q,oe,pe||(We?"border":"content"),ot,be,rr)+"px"}ne.extend({cssHooks:{opacity:{get:function(q,oe){if(oe){var pe=No(q,"opacity");return pe===""?"1":pe}}}},cssNumber:{animationIterationCount:!0,aspectRatio:!0,borderImageSlice:!0,columnCount:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,scale:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeMiterlimit:!0,strokeOpacity:!0},cssProps:{},style:function(q,oe,pe,be){if(!(!q||q.nodeType===3||q.nodeType===8||!q.style)){var He,We,ot,rr=so(oe),Ut=zi.test(oe),cr=q.style;if(Ut||(oe=ho(rr)),ot=ne.cssHooks[oe]||ne.cssHooks[rr],pe!==void 0){if(We=typeof pe,We==="string"&&(He=fr.exec(pe))&&He[1]&&(pe=fn(q,oe,He),We="number"),pe==null||pe!==pe)return;We==="number"&&!Ut&&(pe+=He&&He[3]||(ne.cssNumber[rr]?"":"px")),!k.clearCloneStyle&&pe===""&&oe.indexOf("background")===0&&(cr[oe]="inherit"),(!ot||!("set"in ot)||(pe=ot.set(q,pe,be))!==void 0)&&(Ut?cr.setProperty(oe,pe):cr[oe]=pe)}else return ot&&"get"in ot&&(He=ot.get(q,!1,be))!==void 0?He:cr[oe]}},css:function(q,oe,pe,be){var He,We,ot,rr=so(oe),Ut=zi.test(oe);return Ut||(oe=ho(rr)),ot=ne.cssHooks[oe]||ne.cssHooks[rr],ot&&"get"in ot&&(He=ot.get(q,!0,pe)),He===void 0&&(He=No(q,oe,be)),He==="normal"&&oe in zc&&(He=zc[oe]),pe===""||pe?(We=parseFloat(He),pe===!0||isFinite(We)?We||0:He):He}}),ne.each(["height","width"],function(q,oe){ne.cssHooks[oe]={get:function(pe,be,He){if(be)return cs.test(ne.css(pe,"display"))&&(!pe.getClientRects().length||!pe.getBoundingClientRect().width)?Ls(pe,_l,function(){return md(pe,oe,He)}):md(pe,oe,He)},set:function(pe,be,He){var We,ot=po(pe),rr=!k.scrollboxSize()&&ot.position==="absolute",Ut=rr||He,cr=Ut&&ne.css(pe,"boxSizing",!1,ot)==="border-box",Fr=He?Ya(pe,oe,He,cr,ot):0;return cr&&rr&&(Fr-=Math.ceil(pe["offset"+oe[0].toUpperCase()+oe.slice(1)]-parseFloat(ot[oe])-Ya(pe,oe,"border",!1,ot)-.5)),Fr&&(We=fr.exec(be))&&(We[3]||"px")!=="px"&&(pe.style[oe]=be,be=ne.css(pe,oe)),yl(pe,be,Fr)}}}),ne.cssHooks.marginLeft=wo(k.reliableMarginLeft,function(q,oe){if(oe)return(parseFloat(No(q,"marginLeft"))||q.getBoundingClientRect().left-Ls(q,{marginLeft:0},function(){return q.getBoundingClientRect().left}))+"px"}),ne.each({margin:"",padding:"",border:"Width"},function(q,oe){ne.cssHooks[q+oe]={expand:function(pe){for(var be=0,He={},We=typeof pe=="string"?pe.split(" "):[pe];be<4;be++)He[q+nr[be]+oe]=We[be]||We[be-2]||We[0];return He}},q!=="margin"&&(ne.cssHooks[q+oe].set=yl)}),ne.fn.extend({css:function(q,oe){return mo(this,function(pe,be,He){var We,ot,rr={},Ut=0;if(Array.isArray(be)){for(We=po(pe),ot=be.length;Ut1)}});function os(q,oe,pe,be,He){return new os.prototype.init(q,oe,pe,be,He)}ne.Tween=os,os.prototype={constructor:os,init:function(q,oe,pe,be,He,We){this.elem=q,this.prop=pe,this.easing=He||ne.easing._default,this.options=oe,this.start=this.now=this.cur(),this.end=be,this.unit=We||(ne.cssNumber[pe]?"":"px")},cur:function(){var q=os.propHooks[this.prop];return q&&q.get?q.get(this):os.propHooks._default.get(this)},run:function(q){var oe,pe=os.propHooks[this.prop];return this.options.duration?this.pos=oe=ne.easing[this.easing](q,this.options.duration*q,0,1,this.options.duration):this.pos=oe=q,this.now=(this.end-this.start)*oe+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),pe&&pe.set?pe.set(this):os.propHooks._default.set(this),this}},os.prototype.init.prototype=os.prototype,os.propHooks={_default:{get:function(q){var oe;return q.elem.nodeType!==1||q.elem[q.prop]!=null&&q.elem.style[q.prop]==null?q.elem[q.prop]:(oe=ne.css(q.elem,q.prop,""),!oe||oe==="auto"?0:oe)},set:function(q){ne.fx.step[q.prop]?ne.fx.step[q.prop](q):q.elem.nodeType===1&&(ne.cssHooks[q.prop]||q.elem.style[ho(q.prop)]!=null)?ne.style(q.elem,q.prop,q.now+q.unit):q.elem[q.prop]=q.now}}},os.propHooks.scrollTop=os.propHooks.scrollLeft={set:function(q){q.elem.nodeType&&q.elem.parentNode&&(q.elem[q.prop]=q.now)}},ne.easing={linear:function(q){return q},swing:function(q){return .5-Math.cos(q*Math.PI)/2},_default:"swing"},ne.fx=os.prototype.init,ne.fx.step={};var ca,mf,Ll=/^(?:toggle|show|hide)$/,Dl=/queueHooks$/;function eu(){mf&&(ee.hidden===!1&&t.requestAnimationFrame?t.requestAnimationFrame(eu):t.setTimeout(eu,ne.fx.interval),ne.fx.tick())}function ua(){return t.setTimeout(function(){ca=void 0}),ca=Date.now()}function Tc(q,oe){var pe,be=0,He={height:q};for(oe=oe?1:0;be<4;be+=2-oe)pe=nr[be],He["margin"+pe]=He["padding"+pe]=q;return oe&&(He.opacity=He.width=q),He}function Uc(q,oe,pe){for(var be,He=(Iu.tweeners[oe]||[]).concat(Iu.tweeners["*"]),We=0,ot=He.length;We1)},removeAttr:function(q){return this.each(function(){ne.removeAttr(this,q)})}}),ne.extend({attr:function(q,oe,pe){var be,He,We=q.nodeType;if(!(We===3||We===8||We===2)){if(typeof q.getAttribute>"u")return ne.prop(q,oe,pe);if((We!==1||!ne.isXMLDoc(q))&&(He=ne.attrHooks[oe.toLowerCase()]||(ne.expr.match.bool.test(oe)?Vh:void 0)),pe!==void 0){if(pe===null){ne.removeAttr(q,oe);return}return He&&"set"in He&&(be=He.set(q,pe,oe))!==void 0?be:(q.setAttribute(oe,pe+""),pe)}return He&&"get"in He&&(be=He.get(q,oe))!==null?be:(be=ne.find.attr(q,oe),be??void 0)}},attrHooks:{type:{set:function(q,oe){if(!k.radioValue&&oe==="radio"&&Xe(q,"input")){var pe=q.value;return q.setAttribute("type",oe),pe&&(q.value=pe),oe}}}},removeAttr:function(q,oe){var pe,be=0,He=oe&&oe.match(mr);if(He&&q.nodeType===1)for(;pe=He[be++];)q.removeAttribute(pe)}}),Vh={set:function(q,oe,pe){return oe===!1?ne.removeAttr(q,pe):q.setAttribute(pe,pe),pe}},ne.each(ne.expr.match.bool.source.match(/\w+/g),function(q,oe){var pe=Ma[oe]||ne.find.attr;Ma[oe]=function(be,He,We){var ot,rr,Ut=He.toLowerCase();return We||(rr=Ma[Ut],Ma[Ut]=ot,ot=pe(be,He,We)!=null?Ut:null,Ma[Ut]=rr),ot}});var Mu=/^(?:input|select|textarea|button)$/i,Sc=/^(?:a|area)$/i;ne.fn.extend({prop:function(q,oe){return mo(this,ne.prop,q,oe,arguments.length>1)},removeProp:function(q){return this.each(function(){delete this[ne.propFix[q]||q]})}}),ne.extend({prop:function(q,oe,pe){var be,He,We=q.nodeType;if(!(We===3||We===8||We===2))return(We!==1||!ne.isXMLDoc(q))&&(oe=ne.propFix[oe]||oe,He=ne.propHooks[oe]),pe!==void 0?He&&"set"in He&&(be=He.set(q,pe,oe))!==void 0?be:q[oe]=pe:He&&"get"in He&&(be=He.get(q,oe))!==null?be:q[oe]},propHooks:{tabIndex:{get:function(q){var oe=ne.find.attr(q,"tabindex");return oe?parseInt(oe,10):Mu.test(q.nodeName)||Sc.test(q.nodeName)&&q.href?0:-1}}},propFix:{for:"htmlFor",class:"className"}}),k.optSelected||(ne.propHooks.selected={get:function(q){var oe=q.parentNode;return oe&&oe.parentNode&&oe.parentNode.selectedIndex,null},set:function(q){var oe=q.parentNode;oe&&(oe.selectedIndex,oe.parentNode&&oe.parentNode.selectedIndex)}}),ne.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){ne.propFix[this.toLowerCase()]=this});function pc(q){var oe=q.match(mr)||[];return oe.join(" ")}function gf(q){return q.getAttribute&&q.getAttribute("class")||""}function gd(q){return Array.isArray(q)?q:typeof q=="string"?q.match(mr)||[]:[]}ne.fn.extend({addClass:function(q){var oe,pe,be,He,We,ot;return U(q)?this.each(function(rr){ne(this).addClass(q.call(this,rr,gf(this)))}):(oe=gd(q),oe.length?this.each(function(){if(be=gf(this),pe=this.nodeType===1&&" "+pc(be)+" ",pe){for(We=0;We-1;)pe=pe.replace(" "+He+" "," ");ot=pc(pe),be!==ot&&this.setAttribute("class",ot)}}):this):this.attr("class","")},toggleClass:function(q,oe){var pe,be,He,We,ot=typeof q,rr=ot==="string"||Array.isArray(q);return U(q)?this.each(function(Ut){ne(this).toggleClass(q.call(this,Ut,gf(this),oe),oe)}):typeof oe=="boolean"&&rr?oe?this.addClass(q):this.removeClass(q):(pe=gd(q),this.each(function(){if(rr)for(We=ne(this),He=0;He-1)return!0;return!1}});var jh=/\r/g;ne.fn.extend({val:function(q){var oe,pe,be,He=this[0];return arguments.length?(be=U(q),this.each(function(We){var ot;this.nodeType===1&&(be?ot=q.call(this,We,ne(this).val()):ot=q,ot==null?ot="":typeof ot=="number"?ot+="":Array.isArray(ot)&&(ot=ne.map(ot,function(rr){return rr==null?"":rr+""})),oe=ne.valHooks[this.type]||ne.valHooks[this.nodeName.toLowerCase()],(!oe||!("set"in oe)||oe.set(this,ot,"value")===void 0)&&(this.value=ot))})):He?(oe=ne.valHooks[He.type]||ne.valHooks[He.nodeName.toLowerCase()],oe&&"get"in oe&&(pe=oe.get(He,"value"))!==void 0?pe:(pe=He.value,typeof pe=="string"?pe.replace(jh,""):pe??"")):void 0}}),ne.extend({valHooks:{option:{get:function(q){var oe=ne.find.attr(q,"value");return oe??pc(ne.text(q))}},select:{get:function(q){var oe,pe,be,He=q.options,We=q.selectedIndex,ot=q.type==="select-one",rr=ot?null:[],Ut=ot?We+1:He.length;for(We<0?be=Ut:be=ot?We:0;be-1)&&(pe=!0);return pe||(q.selectedIndex=-1),We}}}}),ne.each(["radio","checkbox"],function(){ne.valHooks[this]={set:function(q,oe){if(Array.isArray(oe))return q.checked=ne.inArray(ne(q).val(),oe)>-1}},k.checkOn||(ne.valHooks[this].get=function(q){return q.getAttribute("value")===null?"on":q.value})});var Hh=t.location,Io={guid:Date.now()},Sp=/\?/;ne.parseXML=function(q){var oe,pe;if(!q||typeof q!="string")return null;try{oe=new t.DOMParser().parseFromString(q,"text/xml")}catch{}return pe=oe&&oe.getElementsByTagName("parsererror")[0],(!oe||pe)&&ne.error("Invalid XML: "+(pe?ne.map(pe.childNodes,function(be){return be.textContent}).join(` +`):q)),oe};var eg=/^(?:focusinfocus|focusoutblur)$/,Ep=function(q){q.stopPropagation()};ne.extend(ne.event,{trigger:function(q,oe,pe,be){var He,We,ot,rr,Ut,cr,Fr,li,vr=[pe||ee],Bi=y.call(q,"type")?q.type:q,gn=y.call(q,"namespace")?q.namespace.split("."):[];if(We=li=ot=pe=pe||ee,!(pe.nodeType===3||pe.nodeType===8)&&!eg.test(Bi+ne.event.triggered)&&(Bi.indexOf(".")>-1&&(gn=Bi.split("."),Bi=gn.shift(),gn.sort()),Ut=Bi.indexOf(":")<0&&"on"+Bi,q=q[ne.expando]?q:new ne.Event(Bi,typeof q=="object"&&q),q.isTrigger=be?2:3,q.namespace=gn.join("."),q.rnamespace=q.namespace?new RegExp("(^|\\.)"+gn.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,q.result=void 0,q.target||(q.target=pe),oe=oe==null?[q]:ne.makeArray(oe,[q]),Fr=ne.event.special[Bi]||{},!(!be&&Fr.trigger&&Fr.trigger.apply(pe,oe)===!1))){if(!be&&!Fr.noBubble&&!K(pe)){for(rr=Fr.delegateType||Bi,eg.test(rr+Bi)||(We=We.parentNode);We;We=We.parentNode)vr.push(We),ot=We;ot===(pe.ownerDocument||ee)&&vr.push(ot.defaultView||ot.parentWindow||t)}for(He=0;(We=vr[He++])&&!q.isPropagationStopped();)li=We,q.type=He>1?rr:Fr.bindType||Bi,cr=(Yt.get(We,"events")||Object.create(null))[q.type]&&Yt.get(We,"handle"),cr&&cr.apply(We,oe),cr=Ut&&We[Ut],cr&&cr.apply&&ps(We)&&(q.result=cr.apply(We,oe),q.result===!1&&q.preventDefault());return q.type=Bi,!be&&!q.isDefaultPrevented()&&(!Fr._default||Fr._default.apply(vr.pop(),oe)===!1)&&ps(pe)&&Ut&&U(pe[Bi])&&!K(pe)&&(ot=pe[Ut],ot&&(pe[Ut]=null),ne.event.triggered=Bi,q.isPropagationStopped()&&li.addEventListener(Bi,Ep),pe[Bi](),q.isPropagationStopped()&&li.removeEventListener(Bi,Ep),ne.event.triggered=void 0,ot&&(pe[Ut]=ot)),q.result}},simulate:function(q,oe,pe){var be=ne.extend(new ne.Event,pe,{type:q,isSimulated:!0});ne.event.trigger(be,null,oe)}}),ne.fn.extend({trigger:function(q,oe){return this.each(function(){ne.event.trigger(q,oe,this)})},triggerHandler:function(q,oe){var pe=this[0];if(pe)return ne.event.trigger(q,oe,pe,!0)}});var Ql=/\[\]$/,Jl=/\r?\n/g,_a=/^(?:submit|button|image|reset|file)$/i,Zn=/^(?:input|select|textarea|keygen)/i;function Gs(q,oe,pe,be){var He;if(Array.isArray(oe))ne.each(oe,function(We,ot){pe||Ql.test(q)?be(q,ot):Gs(q+"["+(typeof ot=="object"&&ot!=null?We:"")+"]",ot,pe,be)});else if(!pe&&me(oe)==="object")for(He in oe)Gs(q+"["+He+"]",oe[He],pe,be);else be(q,oe)}ne.param=function(q,oe){var pe,be=[],He=function(We,ot){var rr=U(ot)?ot():ot;be[be.length]=encodeURIComponent(We)+"="+encodeURIComponent(rr??"")};if(q==null)return"";if(Array.isArray(q)||q.jquery&&!ne.isPlainObject(q))ne.each(q,function(){He(this.name,this.value)});else for(pe in q)Gs(pe,q[pe],oe,He);return be.join("&")},ne.fn.extend({serialize:function(){return ne.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var q=ne.prop(this,"elements");return q?ne.makeArray(q):this}).filter(function(){var q=this.type;return this.name&&!ne(this).is(":disabled")&&Zn.test(this.nodeName)&&!_a.test(q)&&(this.checked||!wr.test(q))}).map(function(q,oe){var pe=ne(this).val();return pe==null?null:Array.isArray(pe)?ne.map(pe,function(be){return{name:oe.name,value:be.replace(Jl,`\r +`)}}):{name:oe.name,value:pe.replace(Jl,`\r +`)}}).get()}});var ec=/%20/g,sl=/#.*$/,Ol=/([?&])_=[^&]*/,vl=/^(.*?):[ \t]*([^\r\n]*)$/mg,Pu=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,tu=/^(?:GET|HEAD)$/,La=/^\/\//,xl={},Ws={},Gh="*/".concat("*"),Ec=ee.createElement("a");Ec.href=Hh.href;function Gf(q){return function(oe,pe){typeof oe!="string"&&(pe=oe,oe="*");var be,He=0,We=oe.toLowerCase().match(mr)||[];if(U(pe))for(;be=We[He++];)be[0]==="+"?(be=be.slice(1)||"*",(q[be]=q[be]||[]).unshift(pe)):(q[be]=q[be]||[]).push(pe)}}function Wh(q,oe,pe,be){var He={},We=q===Ws;function ot(rr){var Ut;return He[rr]=!0,ne.each(q[rr]||[],function(cr,Fr){var li=Fr(oe,pe,be);if(typeof li=="string"&&!We&&!He[li])return oe.dataTypes.unshift(li),ot(li),!1;if(We)return!(Ut=li)}),Ut}return ot(oe.dataTypes[0])||!He["*"]&&ot("*")}function Hd(q,oe){var pe,be,He=ne.ajaxSettings.flatOptions||{};for(pe in oe)oe[pe]!==void 0&&((He[pe]?q:be||(be={}))[pe]=oe[pe]);return be&&ne.extend(!0,q,be),q}function Cp(q,oe,pe){for(var be,He,We,ot,rr=q.contents,Ut=q.dataTypes;Ut[0]==="*";)Ut.shift(),be===void 0&&(be=q.mimeType||oe.getResponseHeader("Content-Type"));if(be){for(He in rr)if(rr[He]&&rr[He].test(be)){Ut.unshift(He);break}}if(Ut[0]in pe)We=Ut[0];else{for(He in pe){if(!Ut[0]||q.converters[He+" "+Ut[0]]){We=He;break}ot||(ot=He)}We=We||ot}if(We)return We!==Ut[0]&&Ut.unshift(We),pe[We]}function Af(q,oe,pe,be){var He,We,ot,rr,Ut,cr={},Fr=q.dataTypes.slice();if(Fr[1])for(ot in q.converters)cr[ot.toLowerCase()]=q.converters[ot];for(We=Fr.shift();We;)if(q.responseFields[We]&&(pe[q.responseFields[We]]=oe),!Ut&&be&&q.dataFilter&&(oe=q.dataFilter(oe,q.dataType)),Ut=We,We=Fr.shift(),We){if(We==="*")We=Ut;else if(Ut!=="*"&&Ut!==We){if(ot=cr[Ut+" "+We]||cr["* "+We],!ot){for(He in cr)if(rr=He.split(" "),rr[1]===We&&(ot=cr[Ut+" "+rr[0]]||cr["* "+rr[0]],ot)){ot===!0?ot=cr[He]:cr[He]!==!0&&(We=rr[0],Fr.unshift(rr[1]));break}}if(ot!==!0)if(ot&&q.throws)oe=ot(oe);else try{oe=ot(oe)}catch(li){return{state:"parsererror",error:ot?li:"No conversion from "+Ut+" to "+We}}}}return{state:"success",data:oe}}ne.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Hh.href,type:"GET",isLocal:Pu.test(Hh.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Gh,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":ne.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(q,oe){return oe?Hd(Hd(q,ne.ajaxSettings),oe):Hd(ne.ajaxSettings,q)},ajaxPrefilter:Gf(xl),ajaxTransport:Gf(Ws),ajax:function(q,oe){typeof q=="object"&&(oe=q,q=void 0),oe=oe||{};var pe,be,He,We,ot,rr,Ut,cr,Fr,li,vr=ne.ajaxSetup({},oe),Bi=vr.context||vr,gn=vr.context&&(Bi.nodeType||Bi.jquery)?ne(Bi):ne.event,gs=ne.Deferred(),Mo=ne.Callbacks("once memory"),bl=vr.statusCode||{},al={},Da={},Ka="canceled",Yn={readyState:0,getResponseHeader:function(Gr){var wi;if(Ut){if(!We)for(We={};wi=vl.exec(He);)We[wi[1].toLowerCase()+" "]=(We[wi[1].toLowerCase()+" "]||[]).concat(wi[2]);wi=We[Gr.toLowerCase()+" "]}return wi==null?null:wi.join(", ")},getAllResponseHeaders:function(){return Ut?He:null},setRequestHeader:function(Gr,wi){return Ut==null&&(Gr=Da[Gr.toLowerCase()]=Da[Gr.toLowerCase()]||Gr,al[Gr]=wi),this},overrideMimeType:function(Gr){return Ut==null&&(vr.mimeType=Gr),this},statusCode:function(Gr){var wi;if(Gr)if(Ut)Yn.always(Gr[Yn.status]);else for(wi in Gr)bl[wi]=[bl[wi],Gr[wi]];return this},abort:function(Gr){var wi=Gr||Ka;return pe&&pe.abort(wi),Er(0,wi),this}};if(gs.promise(Yn),vr.url=((q||vr.url||Hh.href)+"").replace(La,Hh.protocol+"//"),vr.type=oe.method||oe.type||vr.method||vr.type,vr.dataTypes=(vr.dataType||"*").toLowerCase().match(mr)||[""],vr.crossDomain==null){rr=ee.createElement("a");try{rr.href=vr.url,rr.href=rr.href,vr.crossDomain=Ec.protocol+"//"+Ec.host!=rr.protocol+"//"+rr.host}catch{vr.crossDomain=!0}}if(vr.data&&vr.processData&&typeof vr.data!="string"&&(vr.data=ne.param(vr.data,vr.traditional)),Wh(xl,vr,oe,Yn),Ut)return Yn;cr=ne.event&&vr.global,cr&&ne.active++===0&&ne.event.trigger("ajaxStart"),vr.type=vr.type.toUpperCase(),vr.hasContent=!tu.test(vr.type),be=vr.url.replace(sl,""),vr.hasContent?vr.data&&vr.processData&&(vr.contentType||"").indexOf("application/x-www-form-urlencoded")===0&&(vr.data=vr.data.replace(ec,"+")):(li=vr.url.slice(be.length),vr.data&&(vr.processData||typeof vr.data=="string")&&(be+=(Sp.test(be)?"&":"?")+vr.data,delete vr.data),vr.cache===!1&&(be=be.replace(Ol,"$1"),li=(Sp.test(be)?"&":"?")+"_="+Io.guid+++li),vr.url=be+li),vr.ifModified&&(ne.lastModified[be]&&Yn.setRequestHeader("If-Modified-Since",ne.lastModified[be]),ne.etag[be]&&Yn.setRequestHeader("If-None-Match",ne.etag[be])),(vr.data&&vr.hasContent&&vr.contentType!==!1||oe.contentType)&&Yn.setRequestHeader("Content-Type",vr.contentType),Yn.setRequestHeader("Accept",vr.dataTypes[0]&&vr.accepts[vr.dataTypes[0]]?vr.accepts[vr.dataTypes[0]]+(vr.dataTypes[0]!=="*"?", "+Gh+"; q=0.01":""):vr.accepts["*"]);for(Fr in vr.headers)Yn.setRequestHeader(Fr,vr.headers[Fr]);if(vr.beforeSend&&(vr.beforeSend.call(Bi,Yn,vr)===!1||Ut))return Yn.abort();if(Ka="abort",Mo.add(vr.complete),Yn.done(vr.success),Yn.fail(vr.error),pe=Wh(Ws,vr,oe,Yn),!pe)Er(-1,"No Transport");else{if(Yn.readyState=1,cr&&gn.trigger("ajaxSend",[Yn,vr]),Ut)return Yn;vr.async&&vr.timeout>0&&(ot=t.setTimeout(function(){Yn.abort("timeout")},vr.timeout));try{Ut=!1,pe.send(al,Er)}catch(Gr){if(Ut)throw Gr;Er(-1,Gr)}}function Er(Gr,wi,ni,b){var Po,_o,Ye,Ms,ao,Ps=wi;Ut||(Ut=!0,ot&&t.clearTimeout(ot),pe=void 0,He=b||"",Yn.readyState=Gr>0?4:0,Po=Gr>=200&&Gr<300||Gr===304,ni&&(Ms=Cp(vr,Yn,ni)),!Po&&ne.inArray("script",vr.dataTypes)>-1&&ne.inArray("json",vr.dataTypes)<0&&(vr.converters["text script"]=function(){}),Ms=Af(vr,Ms,Yn,Po),Po?(vr.ifModified&&(ao=Yn.getResponseHeader("Last-Modified"),ao&&(ne.lastModified[be]=ao),ao=Yn.getResponseHeader("etag"),ao&&(ne.etag[be]=ao)),Gr===204||vr.type==="HEAD"?Ps="nocontent":Gr===304?Ps="notmodified":(Ps=Ms.state,_o=Ms.data,Ye=Ms.error,Po=!Ye)):(Ye=Ps,(Gr||!Ps)&&(Ps="error",Gr<0&&(Gr=0))),Yn.status=Gr,Yn.statusText=(wi||Ps)+"",Po?gs.resolveWith(Bi,[_o,Ps,Yn]):gs.rejectWith(Bi,[Yn,Ps,Ye]),Yn.statusCode(bl),bl=void 0,cr&&gn.trigger(Po?"ajaxSuccess":"ajaxError",[Yn,vr,Po?_o:Ye]),Mo.fireWith(Bi,[Yn,Ps]),cr&&(gn.trigger("ajaxComplete",[Yn,vr]),--ne.active||ne.event.trigger("ajaxStop")))}return Yn},getJSON:function(q,oe,pe){return ne.get(q,oe,pe,"json")},getScript:function(q,oe){return ne.get(q,void 0,oe,"script")}}),ne.each(["get","post"],function(q,oe){ne[oe]=function(pe,be,He,We){return U(be)&&(We=We||He,He=be,be=void 0),ne.ajax(ne.extend({url:pe,type:oe,dataType:We,data:be,success:He},ne.isPlainObject(pe)&&pe))}}),ne.ajaxPrefilter(function(q){var oe;for(oe in q.headers)oe.toLowerCase()==="content-type"&&(q.contentType=q.headers[oe]||"")}),ne._evalUrl=function(q,oe,pe){return ne.ajax({url:q,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(be){ne.globalEval(be,oe,pe)}})},ne.fn.extend({wrapAll:function(q){var oe;return this[0]&&(U(q)&&(q=q.call(this[0])),oe=ne(q,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&oe.insertBefore(this[0]),oe.map(function(){for(var pe=this;pe.firstElementChild;)pe=pe.firstElementChild;return pe}).append(this)),this},wrapInner:function(q){return U(q)?this.each(function(oe){ne(this).wrapInner(q.call(this,oe))}):this.each(function(){var oe=ne(this),pe=oe.contents();pe.length?pe.wrapAll(q):oe.append(q)})},wrap:function(q){var oe=U(q);return this.each(function(pe){ne(this).wrapAll(oe?q.call(this,pe):q)})},unwrap:function(q){return this.parent(q).not("body").each(function(){ne(this).replaceWith(this.childNodes)}),this}}),ne.expr.pseudos.hidden=function(q){return!ne.expr.pseudos.visible(q)},ne.expr.pseudos.visible=function(q){return!!(q.offsetWidth||q.offsetHeight||q.getClientRects().length)},ne.ajaxSettings.xhr=function(){try{return new t.XMLHttpRequest}catch{}};var ia={0:200,1223:204},mh=ne.ajaxSettings.xhr();k.cors=!!mh&&"withCredentials"in mh,k.ajax=mh=!!mh,ne.ajaxTransport(function(q){var oe,pe;if(k.cors||mh&&!q.crossDomain)return{send:function(be,He){var We,ot=q.xhr();if(ot.open(q.type,q.url,q.async,q.username,q.password),q.xhrFields)for(We in q.xhrFields)ot[We]=q.xhrFields[We];q.mimeType&&ot.overrideMimeType&&ot.overrideMimeType(q.mimeType),!q.crossDomain&&!be["X-Requested-With"]&&(be["X-Requested-With"]="XMLHttpRequest");for(We in be)ot.setRequestHeader(We,be[We]);oe=function(rr){return function(){oe&&(oe=pe=ot.onload=ot.onerror=ot.onabort=ot.ontimeout=ot.onreadystatechange=null,rr==="abort"?ot.abort():rr==="error"?typeof ot.status!="number"?He(0,"error"):He(ot.status,ot.statusText):He(ia[ot.status]||ot.status,ot.statusText,(ot.responseType||"text")!=="text"||typeof ot.responseText!="string"?{binary:ot.response}:{text:ot.responseText},ot.getAllResponseHeaders()))}},ot.onload=oe(),pe=ot.onerror=ot.ontimeout=oe("error"),ot.onabort!==void 0?ot.onabort=pe:ot.onreadystatechange=function(){ot.readyState===4&&t.setTimeout(function(){oe&&pe()})},oe=oe("abort");try{ot.send(q.hasContent&&q.data||null)}catch(rr){if(oe)throw rr}},abort:function(){oe&&oe()}}}),ne.ajaxPrefilter(function(q){q.crossDomain&&(q.contents.script=!1)}),ne.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(q){return ne.globalEval(q),q}}}),ne.ajaxPrefilter("script",function(q){q.cache===void 0&&(q.cache=!1),q.crossDomain&&(q.type="GET")}),ne.ajaxTransport("script",function(q){if(q.crossDomain||q.scriptAttrs){var oe,pe;return{send:function(be,He){oe=ne("